1

Although the title mentions file, it doesn't have to be a file. Any locking mechanism would do.

Here is the situation: I have a daemon process written in C, and a web page in php. I'd like to have a way of mutual locking so that under certain situation, the C daemon would lock a file and php detects the situation and tells the client side that the system is busy.

Is there an easy way of doing this?

Thanks,

Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
lang2
  • 11,433
  • 18
  • 83
  • 133

4 Answers4

3

flock does it properly.

In your PHP script, use a non-blocking lock:

$fd = fopen('/var/run/lock.file', 'r+');
if (!flock($fd, LOCK_SH | LOCK_NB, $wouldblock) && $wouldblock) {
    // buzy
}

The LOCK_NB flag make this call non blocking. If the file is locked exclusively, it will return immediately. Multiple pages will be allowed to lock the file at the same time.

You can release the lock with

flock($fd, LOCK_UN);

In your C daemon, use a blocking and exclusive lock:

flock(fd, LOCK_EX); // This will wait until no page has locked the file

See PHP's flock() documentation and C's one

Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
2

You could have your daemon create a file when busy, and remove it when not, then in PHP do something like:

if (file_exists('/path/to/file')) {
    echo 'System busy';
}
mfonda
  • 7,873
  • 1
  • 26
  • 30
  • Much easier to do this than having to hit the database each time. As long as the daemon's careful to remove the file after the lockout period is over, this is most likely the simplest and most failproof option. +1 – Marc B Jan 25 '11 at 16:47
  • 1
    mfonda: this looks like it might be a victim of race condition. No? – lang2 Jan 25 '11 at 16:51
  • The problem with this is that the daemon can start just during the file_exits() call and create the file just after the call or at any time during execution of the page. – Arnaud Le Blanc Jan 25 '11 at 16:53
  • 1
    @lang2 @user576875 Yeah looks like you're right--user576875's solution is the way to go. – mfonda Jan 25 '11 at 16:57
1

If your PHP application is database driven, it should be easy to update a certain column of that database to indicate "the system is busy".

Your cronjob would set and reset this flag and your PHP application can read its value.

Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
1

Do you only want PHP to detect that the daemon is busy? Or do you actually want them to wait on each other? Using an exclusive lock would have the downside that the C daemon will have to wait for any and all PHP instances to finish their work before it can grab its lock and continue on.

If you're only looking to detect that the C daemon is busy (ie, only in one direction), just testing for the existance of a busy token file (or semaphore, or shared memory object - platform dependant) might be a better option. Creating files tends to be more expensive than just setting a simple flag in shared memory however.

CoreyStup
  • 1,488
  • 13
  • 14
  • Only to detect if the daemon is busy. But the good thing about a file is that it's persistent. I'm not sure if you can have persistent semaphore or shared memory? – lang2 Jan 26 '11 at 08:57
  • By persistent do you mean across reboots? Or across process lifecycle? Why not just have the daemon create a shared memory region that the clients all attach to on startup. They can check for the "busy" flag there. – CoreyStup Jan 26 '11 at 16:15