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