I'm submitting a ...
What is the current behavior?
In the current implementation (using zc.lockfile) and removing the lockfile in lib/sessions.py it is possible that two processes/threads obtain a lock on the identical session lock file. This of course can lead to problems when one thread/process writes into a session file (but hasn't finished) and another thread/process reads incomplete data from it (leading to unpickle errors).
The scenario works because of this:
P1 opens file
P1 locks file
P2 opens file
P1 unlocks file
P1 removes file
P2 locks file (creating a lock on the removed file)
P3 opens file (creates a new lock file)
P3 locks file (now both P2 and P3 hold a lock on the same file)
If the current behavior is a bug, please provide the steps to reproduce and if possible a screenshots and logs of the problem. If you can, show us your code.
import fcntl, os
flags = fcntl.LOCK_EX | fcntl.LOCK_NB
fp1 = open('x.lock', 'a+') # first file handle and file descriptor for the lock file
os.remove('x.lock')
fp2 = open('x.lock', 'a+') # second file handle and descriptor for the lock file
lock1 = fcntl.flock(fp1.fileno(), flags) # obtain lock in deleted file
lock2 = fcntl.flock(fp2.fileno(), flags) # obtain 2nd lock on new file
The simple (but maybe not the desired solution) would be to not remove the lock file.
What is the expected behavior?
The 2nd lock should fail
I went back to a very old Cherrypy Version (3.2.2), there the so called 'naive' lock file approach
via fd = os.open(path, os.O_CREAT | os.O_WRONLY | os.O_EXCL) was used, this indeed is very reliable, I could not reproduce my session lock errors with that ;-)
Please tell us about your environment:
- Cheroot version: 6.5.5
- CherryPy version: 18.1.1
- Python version: 3.6.3
- OS: Centos7
- Browser: all
Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, e.g. stackoverflow, gitter, etc.)
I'm submitting a ...
What is the current behavior?
In the current implementation (using zc.lockfile) and removing the lockfile in lib/sessions.py it is possible that two processes/threads obtain a lock on the identical session lock file. This of course can lead to problems when one thread/process writes into a session file (but hasn't finished) and another thread/process reads incomplete data from it (leading to unpickle errors).
The scenario works because of this:
P1 opens file
P1 locks file
P2 opens file
P1 unlocks file
P1 removes file
P2 locks file (creating a lock on the removed file)
P3 opens file (creates a new lock file)
P3 locks file (now both P2 and P3 hold a lock on the same file)
If the current behavior is a bug, please provide the steps to reproduce and if possible a screenshots and logs of the problem. If you can, show us your code.
The simple (but maybe not the desired solution) would be to not remove the lock file.
What is the expected behavior?
The 2nd lock should fail
I went back to a very old Cherrypy Version (3.2.2), there the so called 'naive' lock file approach
via
fd = os.open(path, os.O_CREAT | os.O_WRONLY | os.O_EXCL)was used, this indeed is very reliable, I could not reproduce my session lock errors with that ;-)Please tell us about your environment:
Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, e.g. stackoverflow, gitter, etc.)