Locking the String or Object that is placed in the hashtable will do it
since that is presistent across all threads - and it doesn't really matter
which kind of Object it is - we just need something/anything to sync on.
There really isn't much to say about what's happening - we have one thread
entering the sync block, calling the c'tor.  In the c'tor it calls a web
service on the same machine (but different service) so that 2nd thread
blocks on the sync block because we've locked the session (in this case the
appSession) object.  But like I said, with the current code you'll see the
same deadlock (or really bad performance) if you have a hanging c'tor or
really slow c'tor.
-Dug


Glen Daniels <[EMAIL PROTECTED]> on 10/14/2002 05:24:20 PM

Please respond to [EMAIL PROTECTED]

To:    "'[EMAIL PROTECTED]'" <[EMAIL PROTECTED]>
cc:
Subject:    RE: sync



Could you describe exactly what's happening when you have problems?  I'm
assuming it's a deadlock situation, but I'm not sure I understand it - and
in fact I think I see a bug in the current code.  The lock is on the
Session object (i.e. the AxisHttpSession for HTTP).  It looks to me like
there will be one of those per request (AxisServlet:693)... so the locks
aren't actually doing what I want them to, are they?  In other words:

1. Thread 1 accepts request, wraps HTTPSession[A] with AxisSession[X]
2. Thread 2 accepts request, wraps HTTPSession[A] with AxisSession[Y]

Locking on the objects at X and Y will produce two different locks, and
won't prevent the other thread from modifying the HTTPSession contents
beneath the wrapper.

In fact, does the servlet API even mandate that you'll get exactly the same
HTTPSession object for different requests across different threads?  Do we
have to lock on the session ID instead?

I can see this being a problem at present with the application scope,
because that really IS the same object each time.  So is that what you're
experiencing?

--Glen

P.S.  Your solution will almost work, although you shouldn't lock a String,
just make a new Object().  The problem with it is the same as above,
though.  We need something real to lock on, and I don't think the
AxisHttpSession will do it.  Perhaps we should add getLock() and
releaseLock() APIs to the Session APIs.

> Glen - got kicked off of irc but I think the problem would be
> solved by
> something like this:
> String lockObject = null ;
> Object service = null ;
> sync (session) {
>   Hashtable  locks = session.get("AxisLocks");
>   if ( locks == null )  session.set("AxisLocks", locks = new
> Hashtable() );
>   if ( (lockObject = locks.get(serviceName)) == null )
>     locks.put(serviceName, lockObject = new String(serviceName));  //
> String can be anything
> }
> sync(lockObject) {
>   service = session.get(serviceName);
>   if ( service == null ) session.set(serviceName,
> service=getNewService(...));
> }
>
> The first sync would only allow one thread to modify the
> locks hashtable at
> a time - which is ok since the updates to the table would not
> be recursive
> at all.  And the second sync would prevent multiple hits to
> the exact same
> c'tor within the desired scope - rather than _any_ c'tor in
> the scope like
> it is now.  So, this would lift the restriction that a c'tor
> can't call a
> web service on the same server, but it won't allow the c'tor
> for a service
> to invoke the same service - which I think would be ok - for now  :-).
> Whatcha think?
> -Dug
>
>



Reply via email to