I think there is another bug as well.

The _unlock function only unlocks the session file if it exists but leaves 
response.session_file defined. 

Later when the request cycle finishes the _try_store_on_disk function will 
still see response.session_file as active and write it but this is now 
dangerous because it was unlocked before the write and a second request from 
the same client machine could clash. This has also had the fortunate side 
effect of closing the session file so the server does not leak file 
descriptors.

I think the tail end of _try_store_on_disk and _unlock should look like 
this:

        if response.session_file:
            cPickle.dump(dict(self), response.session_file)
            response.session_file.truncate()
            self._unlock(response)

    def _unlock(self, response):
        if response and response.session_file:
            try:
                portalocker.unlock(response.session_file)
                response.session_file.close()
                del response.session_file
            except: ### this should never happen but happens in Windows
                pass

But the del response.session_file will cause an AttributeError exception so 
maybe it would be better to set it to None or change all the tests for 
response.session_file to be hasattr(response, 'session_file')

Ron

Reply via email to