[M3devel] Recursive locks

Jay jay.krell at cornell.edu
Fri Aug 15 08:27:17 CEST 2008


Btw, notice that the comment I quoted is NOT true, prior to my change.
It claims we don't hold locks when we call out to Win32, but we do.
 
I vaguely know that releasing and reacquiring locks is or can be dangerous..
But, it depends, right?
It depends on if the locked data has been used yet, and if it is assumed to be
unchanged from the use before the release to uses after the reacquire, right?
 
I believe:
  Handling messages in Win32 possibly causes reentrance  -- called while already "in the middle" of doing something.
  Trestle, at least in parts, is perhaps not "designed" to handle that.
     That is, it does a lot of long term locking.
 
I tried to consider if the work here can be deferred, but it seems like it is exactly meant to occur in this order. I'll have dig more..sometimes...
 
 - Jay> Date: Thu, 14 Aug 2008 20:20:07 -0500> From: rodney.bates at wichita.edu> To: m3devel at elegosoft.com> Subject: [M3devel] Recursive locks> > Randy Coleburn wrote:> > Jay:> > > > There is the abstraction of multiple concurrent "readers" but only one > > "writer". I actually have such a module that I use sometimes in my > > programs. The idea is one of acquiring/releasing read locks and write > > locks. The difficulty here is in preventing starvation and usually > > requires adherence to some rules (again rigor). By starvation I mean > > that writers must wait for all readers to finish before they get access, > > so if there is always at least one reader, the writer will "starve" and > > never gain access.> > > > As for recursive locks, again that is usually indicative of a design > > flaw. I did once implement a system that permitted the same thread to > > acquire a lock multiple times, provided that it eventually released the > > lock the same number of times that it acquired it. In other words, > > after the first lock, subsequent locks by the same thread just increment > > a counter. Then, unlocks decrement the counter until it is zero with > > the final unlock actually releasing the mutex.> > > > In the code you modified, you could implement such a scheme to handle > > the recursive locks, provided that at some point the thread releases for > > each lock. The Thread interface has the ability to note the current > > thread (i.e., Thread.Self()). So you could make a stack of locks by > > same thread. Other threads would have to block until the first thread's > > lock stack was empty.> > > > For example:> > > > ACQUIRE: If resource available, lock resource mutex and put current > > thread on granted stack. Otherwise, if current thread already on > > granted stack, push it on stack again and let it proceed. Otherwise > > (this is a new thread wanting access), so push this thread onto a > > waiting stack and wait.> > > > RELEASE: Pop granted stack and check to ensure the popped stack entry > > represents the current thread. If not, must crash due to a programming > > error. If granted stack is now empty, check to see if the waiting stack > > is empty. If the waiting stack is empty, release the resource mutex. > > Otherwise (there is at least one thread waiting), pop waiting stack and > > push onto granted stack. Repeat pop/push for each occurrence of current > > thread at top of waiting stack. Allow waiting thread to proceed.> > > > I can check into providing my read-write locks modules if needed.> > > > Regards,> > Randy> > > > > I have forgotten just where, but there are places in Trestle where it is> documented that, when your <whatever>-procedure is called, it is possible> that a certain MUTEX will sometimes already be held by the executing thread,> sometimes not. If you need to access the data protected by that MUTEX,> you are just out of luck. No matter what you do, it will be sometimes> wrong, sometimes not. I don't remember the details, but I gave up trying> to find a way to do what I wanted to do. I think it was very difficult,> even allowing modifications to Trestle. This kind of lock scheme would> probably have solved this problem.> > > > >>> Jay <jay.krell at cornell.edu> 8/14/2008 6:08 PM >>>> > > > Maybe we should have another lock type that allows recursive acquires?> > To be used sparingly, but used here?> > I know that is often frowned upon -- the need for it implies a design > > flaw -- but> > maybe it is ok sometimes?> > I don't understand when/why recursive locks are ok or not.> > > > - Jay> > > > > > ________________________________> > > > From: jay.krell at cornell.edu> > To: rcoleburn at scires.com; jkrell at elego.de; m3commit at elegosoft.com> > Date: Thu, 14 Aug 2008 22:05:13 +0000> > Subject: Re: [M3commit] CVS Update: cm3> > > > > > > > > > How about this comment in the code:> > > > (*-------------------------------------------------- raw seething > > windows ---*)> > (* NOTE: The helper procedures called by WindowProc lock VBT.mu when calling> > various Trestle procedures. They do not hold locks while calling Win32> > because it knows nothing about Modula-3 locks and it can, on a whim, call> > WindowProc to do something. The only reason this scheme might work is> > because we have a single Modula-3 thread that's pulling on the Win32> > message queue and calling WindowProc.> > > > Similarly, we don't bother locking around updates to Child records.> > They are updated by the single Modula-3/WindowProc thread.> > *)> > > > ?> > I also need to check if any state has been modified, or cached in > > locals, with> > the locks held that are being released.> > > > -Jay> > > > > > > > ________________________________> > > > > > Date: Thu, 14 Aug 2008 11:13:25 -0400> > From: rcoleburn at scires.com> > To: jkrell at elego.de; m3commit at elegosoft.com> > Subject: Re: [M3commit] CVS Update: cm3> > > > > > > > Jay:> > > > > > > > I haven't studied this code in depth, but on the surface I doubt your > > change is "correct".> > > > > > > > I think the more telling problem is that if you look at the body of > > WinTrestle.Release, it is empty, save for a comment that it is not yet > > implemented. So, it would seem that if WinTrestle.Acquire is called > > more than once, you will crash because the locks have not been released.> > > > > > > > Further, I don't think it would make sense to release the locks before > > calling out to Windows, and then reacquire them upon return. The locks > > are known to Modula-3 and not Windows. Releasing them will allow other > > competing threads to acquire them while you are in the Windows subsystem > > and would seem to violate whatever protections were in place per holding > > the locks. Upon return from Windows, the thread will be back in > > competition with others to reacquire the locks it gave up and upon > > success, there is no guarantee that the other threads didn't disturb the > > state the original thread depended upon.> > > > > > > > I would suggest reverting these changes and looking to implement the > > Release procedure.> > > > > > > > Regards,> > > > Randy> > > > > > >>> Jay Krell 8/14/2008 4:26 PM>>>> > CVSROOT:/usr/cvs> > Changes by:jkrell at birch.08/08/14 16:26:59> > > > Modified files:> > cm3/m3-ui/ui/src/winvbt/: WinTrestle.m3> > > > Log message:> > release locks when calling out to Win32 to prevent recursive lock > > acquisition. correct?> > > > > > > > -- > -------------------------------------------------------------> Rodney M. Bates, retired assistant professor> Dept. of Computer Science, Wichita State University> Wichita, KS 67260-0083> 316-978-3922> rodney.bates at wichita.edu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20080815/2369c19c/attachment-0002.html>


More information about the M3devel mailing list