PHP why can i get 2 concurrent LOCK_EX on the same handle?

67 Views Asked by At

why does this code print 3x true?

<?php

$h = tmpfile();
var_dump(flock($h, LOCK_EX|LOCK_NB));
var_dump(flock($h, LOCK_SH|LOCK_NB));
var_dump(flock($h, LOCK_EX|LOCK_NB));

why doesn't the initial LOCK_EX block the 2 other requests? 3v4l: https://3v4l.org/3gTv1

fwiw trying to lock a second handle to the same file does not work:

<?php

$h = tmpfile();
$h2 = fopen(stream_get_meta_data($h)['uri'], 'rb');
var_dump(flock($h, LOCK_EX|LOCK_NB));
var_dump(flock($h2, LOCK_SH|LOCK_NB));

prints bool(true) bool(false)

1

There are 1 best solutions below

1
Ilia Yatsenko On

According to this note https://www.php.net/manual/en/function.flock.php#78318:

If however, you call flock on a file on which you possess the lock, it will try to change it. So: flock(LOCK_EX) followed by flock(LOCK_SH) will get you a SHARED lock, not "read-write" lock.

I suppose that the PID of process, currently owning a lock, is considered somehow in flock(). So when you call it again on the handle, on which your currently running process already has a lock, it doesn't try to re-possess lock, just changes it's mode if needed.

Seems like logical behavior, not well-documented, though.