[jcifs] Deadlock while cleaning up old sessions in transport
Michael B Allen
miallen at ioplex.com
Mon Aug 13 19:07:36 GMT 2007
On Mon, 13 Aug 2007 17:17:52 +0200 (CEST)
"Felix Schumacher" <felix.schumacher at internetallee.de> wrote:
> > Like I said the other day, the only way to fix this problem is to create
> > a custom lock class and replace all of the synchronized calls so that one
> > lock can be used and the lock can be *unlocked* deep in hte call-stack.
> So given an implementation of concurrent.ReentrantLock (with which one
> could start to have a known working implementation), how would you decide
> when to unlock the transport and where?
If you have a lock class that can be unlocked then the solution is simple
because you can have one lock for the entire VM. If there's only one
lock then a deadlock is theoretically impossible.
Meaning, create a static instance of ReentrantLock associated with
jcifs.util.transport.Transport and add static lock/unlock methods that
lock/unlock that ReentrantLock. Now, eliminate all synchronized calls
and replace them with Transport.lock() / Transport.unlock().
That will solve the deadlock but there is a pitfall. You must never ever
ever EVER block while that lock is locked. For example if the transport
tries to read() from a socket with the lock locked the entire client
will lockup (but not deadlock) waiting for that I/O. The end result will
be that performance will go subterranean.
If you actually do this and you know what you're doing and it works,
please send a patch and I'll put it in the patches directory.
Michael B Allen
PHP Active Directory Kerberos SSO
More information about the jcifs