• Forum
  • Doc
  • Screenshots
  • Download
  • Donate
  • Contributors
  • Contact
  • Follow @phpfreechat
  • DEMO
  • Board index ‹ Version 1.x branch ‹ Contributions (v1.x)
  • Change font size
  • FAQ
  • Register
  • Login

Alternative file locking (flock) for NFS and free.fr

Post a bug fix, a new feature, a theme ...

Moderators: OldWolf, re*s.t.a.r.s.*2

Post a reply
1 post • Page 1 of 1

Postby King Moonraiser » Thu Nov 15, 2007 7:43 pm

File locking is performed at the OS level. If it's turned off or unsupported, PHPFREECHAT will not work properly. I've done some research to look for alternatives. One possibility is to rely on the fact that "mkdir" and "rmdir" are usually atomic transactions on most operating systems. Therefore, it should be possible to manage the file locking at the PHP level and store the lock states using directories.

Here is some sample code:

Code: Select all
<?php

$method = 2;
$msgid_filename = '/tmp/readwrite';

$uid = md5(uniqid(rand(), true));
$msgid = 0;
while(1)
{
  clearstatcache();
  if (file_exists($msgid_filename)) {
    $fh = fopen($msgid_filename, 'r+');
    while(1)
    {
      if ($method == 1)
      {
        flock($fh, LOCK_EX);
      }
      else
      {
         nfs_flock($msgid_filename, LOCK_EX);
      }
      $msgid = chop(fread($fh, filesize($msgid_filename)));
      $msgid++;
      rewind($fh);
      fwrite($fh, $msgid);
      fflush($fh);
      ftruncate($fh, ftell($fh));
      if ($method == 1)
      {
        flock($fh, LOCK_UN);
      }
      else
      {
         nfs_flock($msgid_filename, LOCK_UN);
      }
      break;
    }
  }
  else {
    $fh = fopen($msgid_filename, 'w+');
    fwrite($fh, "1");
    $msgid="1";
  }
  fclose($fh);

  echo "uid=".$uid." ".trim($msgid)."n";
  usleep(rand(0,1000)); // a very small pause
}

function nfs_flock ($filename, $lock)
{
  if ($lock == LOCK_EX)
  {
    Do {
      $locked = @mkdir($filename.".lock");
      usleep(round(rand(0,10000)));
    } while ($locked === false);
    return true;
  }
  else if ($lock == LOCK_UN)
  {
    rmdir($filename.".lock");
    return true;
  }
}

?>

If you cannot use flock, please try to run multiple instances on your server and verify that the counter never gets reset or out of sync.

Known Issues:

1) If the application is inadvertently shuts down, the lock may not be cleaned up. That will cause deadlocks when the application is restarted. Perhaps I can enhance include logic to delete the lock if it's more than X seconds old?

2) I'd like this to be a direct replacement for flock. However, I need the filename and path, not the file handle. Does anyone know how to extract the absolute path and name of a file from the file handle?
King Moonraiser
Member
 
Posts: 98
Joined: Fri Jun 22, 2007 9:42 pm
  • Website
Top

Post a reply
1 post • Page 1 of 1

Return to Contributions (v1.x)

Who is online

Users browsing this forum: No registered users and 5 guests

  • Board index
  • The team • Delete all board cookies • All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
Sign in
Wrong credentials
Sign up I forgot my password
.
jeu-gratuit.net | more partners
Fork me on GitHub