On Thu, 2010-01-07 at 16:46 -0500, Scott Lawrence wrote:
> On Thu, 2010-01-07 at 15:50 -0500, Dale Worley wrote:
> > More exactly, the problem is that whether and where the lock is held is
> > not determined by the static structure of the code. That is what OsLock
> > was designed to allow, and OsLock::release() violates that. Within that
> > context, I can replace ::release with OsUnLock with only a slight loss
> > of efficiency, and have the lock structure be statically determined.
> > With that structure, gotchas are still possible, but much less so than
> > with manual locking.
>
> Sorry - I'm not clear on what change that implies... could you put in a
> code snippet like the one you started with to illustrate?
Here's an example (with some extraneous code deleted):
OsStatus SipSubscribeClient::handleRestartEvent(const UtlString& handle)
{
OsLock lock(mSemaphore);
// Get the SubscriptionGroupState.
// Due to race conditions, it may no longer exist.
SubscriptionGroupState* groupState = getGroupStateByOriginalHandle(handle);
if (groupState)
{
// Test whether restart is set.
// It may be false because the subscription group is being ended.
if (groupState->mRestart)
{
groupState->setRestartTimer();
OsUnLock unlock(lock);
groupState = NULL; // Remember that groupState is no longer reliable,
// because it points to a structure protected by
// mSemaphore.
reestablish(handle);
}
}
}
The problem to be solved is that reestablish() needs to be called with
mSemaphore unlocked. OsUnLock causes mSemaphore to be released within
its scope.
Dale
_______________________________________________
sipx-dev mailing list [email protected]
List Archive: http://list.sipfoundry.org/archive/sipx-dev
Unsubscribe: http://list.sipfoundry.org/mailman/listinfo/sipx-dev
sipXecs IP PBX -- http://www.sipfoundry.org/