[ENH][GOODIE]RE: Interesting Locking Problem (and Transcript [FIX])

Andreas Raab Andreas.Raab at gmx.de
Fri Mar 29 00:37:04 UTC 2002


Ross,

The attached changes contain a Monitor class which handles exactly the
problem you're describing. I used this to fix the problem of using
Transcript from #drawOn: methods.

Cheers,
  - Andreas

> -----Original Message-----
> From: squeak-dev-admin at lists.squeakfoundation.org 
> [mailto:squeak-dev-admin at lists.squeakfoundation.org] On 
> Behalf Of Ross Boylan
> Sent: Friday, March 29, 2002 1:02 AM
> To: squeak-dev at lists.squeakfoundation.org
> Cc: Ross Boylan
> Subject: Interesting Locking Problem
> 
> 
> I have two smalltalk processes that sometimes write the same
> data. Further, each process may write recursively; in the course of
> handling one write, it will attempt other writes.  I need to permit
> the recursive writes within a process while blocking activity between
> the processes.
> 
> I would appreciate advice about how best to do this.  My current
> approach has a small vulnerability, and it's not clear to me how to
> correct it.  Further, it already seems a bit elaborate.
> 
> I implement locking on the class side of one of my classes:
> lock
> 	"Acquire a Lock for the invoking Process, waiting as necessary"
> 	[ProcessLock notNil and: [ProcessLock ~~ Processor 
> activeProcess]] whileTrue: [
> 		(Delay forMilliseconds: 300) wait.
> 		].
> 	ProcessLock _ Processor activeProcess.
> 	UpdateLocks _ UpdateLocks ifNil: [1] ifNotNil:[UpdateLocks+1].
> 
> The ProcessLock class variable permits the original process to get
> recursive locks, and the UpdateLocks variable keeps track of when
> we're really done.
> 
> unlock
> 	"Permit activity in the update process"
> 	self assert: [UpdateLocks > 0].  "and it should not be nil"
> 	self assert: [ProcessLock == Processor activeProcess].
> 	UpdateLocks _ UpdateLocks-1.
> 	UpdateLocks = 0 ifTrue: [
> 		ProcessLock _ nil.
> 		]
> 
> The problem is that these operations need to be atomic and they
> aren't.  For example, in lock ProcessLock might test as nil, but then
> the other process might reset it before the first process does.  For
> the truly paranoid, even UpdateLocks _ UpdateLocks-1 is not safe
> (maybe it is, given the VM, but I don't know that).
> 
> I thought of adding a Semaphore and using critical: to protect the
> entire method, but this could lead to deadlock:
> Process A sets the ProcessLock (waiting and then signalling 
> the semaphore).
> Process B enters the critical section, but does not exit it since
> 	it is in the loop waiting for ProcessLock to be nil)
> Process A attempts a recursive write operation.  It begins by 
> 	invoking the lock method, which waits on the semaphore.
> 	Since B has not finished its critical section, there
> 	are no spare signals, so A is blocked.
> 
> For one of the processes there is a natural place to use a top-level
> lock, but for the other there is not; hence the need to deal with
> recursion.  I suppose if I could restructure it to get a top level for
> the other process I could use a conventional mutex and be done.  Any
> other ideas?
> 
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: FixTranscript.cs
Type: application/octet-stream
Size: 2896 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20020329/016363e7/FixTranscript.obj


More information about the Squeak-dev mailing list