[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
|