Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a portable way to put a timeout on flock()?

Tags:

php

timeout

flock

flock() is PHP's portable advisory file locking function. They explicitly promote that it even works under windows:

flock() allows you to perform a simple reader/writer model which can be used on virtually every platform (including most Unix derivatives and even Windows).

I'd like to put an also portable timeout on a blocking flock() (and no busy waiting work around with the LOCK_NB option). In UNIX this can simply be achieved with setting an alarm which would send a SIGALRM:

pcntl_signal(SIGALRM, function() {});
pcntl_alarm(3);
try {
    if (!flock($handle, LOCK_EX)) {
        throw new \Exception("Timeout");
    }
} finally {
    pcntl_alarm(0);
    pcntl_signal_dispatch();
    pcntl_signal(SIGALRM, SIG_DFL);
}

Is there a portable way to put a timeout on a blocking flock()? If so, how?

like image 522
Markus Malkusch Avatar asked Nov 20 '16 23:11

Markus Malkusch


1 Answers

I don't think that there is any way to do this on Windows without a busy wait / polling loop.

PHP implements flock on windows using LockFileEx (see flock_compat.c:132). As you can see from these similar questions, there is no way to set a timeout on LockFileEx or to cancel a process waiting for a LockFileEx request (i.e. there is no equivalent to the SIGALRM signal for this use-case):

  1. LockFile with timeout? (asked 2011)

Q) If I want to wait for file-lock with timeout, how would I go about it?

...

A) write a small loop to check the return code

  1. "LockFileEx can't time out it just hangs" from microsoft.public.win32.programmer.kernel mailing list, 1997

Q) Does anyone know of a way to get LockFileEx to time out ?

...

A) you can only have it fail imemdiately, sleep, and loop back until you reach some retry limit.

like image 98
Rich Avatar answered Oct 06 '22 00:10

Rich