yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.23k stars 6.91k forks source link

Mutex and PCNTL aren't good friends at all #15913

Open twisted1919 opened 6 years ago

twisted1919 commented 6 years ago

What steps will reproduce the problem?

Using the command line, create a php file where you acquire a mutex then go ahead and using a for loop and pcntl_fork, fork 10 processes, 9 of the processes will have a sleep call for say 30 seconds but the last process in the for loop have a sleep time of 1 second to finish before the other ones. Run the file with php file.php, then from another terminal, after 5 seconds, run the same file and see if it can pass the mutex which you just acquired.

What is the expected result?

I expect the call from the other terminal to not be able to continue since the previous process has acquired the mutex and it is still running.

What do you get instead?

I simply can start the process in the second terminal like i did in the first one even if the first one is still running. This happens because even if all the processes last for 30 seconds, one of them last for just one second, and because of the Mutex::autoRelease feature and the way pcntl works (because it clones the entire process), the short process finishes first and releases the mutex, leaving all the other processes unprotected and allowing creating new processes by accessing same file when it should not be possible.

I am note sure if this should be marked as a bug since there is not much that the framework can do in this case, but at least one big warning explaining this behaviour should be made in the documentation of the mutex component. And really, make it in red or something because this one is not obvious and it will byte you really bad.

Additional info

Q A
Yii version 2.0.14
PHP version 7.1
Operating system Linux
sergeymakinen commented 6 years ago

AFAIK, spl_object_hash($this) could be used to detect a possibly forked process.