Graham Dumpleton
grahamd at dscpl.com.au
Sun Aug 13 18:49:59 EDT 2006
Jim Gallacher wrote .. > Michael Spang wrote: > > I recently ran into deadlocks using sessions in both my mod_python > > handler and in psp. I've read through the thread at > > http://www.modpython.org/pipermail/mod_python/2005-May/018035.html and > > understand that this occurs because both my handler and PSP create their > > own session instance and attempt to lock the session. > > > > My question is: why doesn't the mod_python sessions module keep a > > reference to each constructed session object and the thread that has > it > > locked? > > Easier said than done in mpm-prefork or mpm-worker. It's possible to > keep track of the session object within a single request, but difficult > (as in nearly impossible) to do it across requests in these 2 mpms. Hmmm, what do you mean by across requests here? The only thing I can think of that even makes sense doesn't even relate to which MPM is used. This is the problem in 3.2 whereby if an internal redirect occurs and the parent handler had acquired the session and not unlocked it, that an attempt by the handler for the sub request to also acquire the session object will result in a deadlock. I have demonstrated code before which can be used to make this work provided that both parent and sub request are in the same interpreter. In short it would stash the session object in a global area where the thread was the key. It would be up to any handler to first check in the cache for the session object before deciding to create its own and in turn store that in the cache. The request handler would also need to register a cleanup handler to ensure that any reference was removed at the end of the request. This could be done as part of the implementation of the cache though. Now, having said that, in mod_python 3.3 there is a change that may make all this simpler to do and which may also allow sharing of the session object between handlers executed within the context of different interpreters. The change is that req.main now provides access to the actual request object of a parent request whereas previously the Python part of the object was a new wrapper around the request_rec structure for the parent request. What this means is that the following may actually work in a handler of a sub request. def handler(req): if req.main and hasattr(req.main, 'session'): req.session = req.main.session else: req.session = Session(req) if req.main: req.main.session = req.session I can't remember how thoroughly I tested this and whether it does work across interpreters. It should for simple data and whether a session object is too complicated I don't know. Graham
|