'From Squeak3.7alpha of ''11 September 2003'' [latest update: #5420] on 21 September 2003 at 11:29:49 am'! "Change Set: InterProcessSignaling-svp Date: 21 September 2003 Author: Stephen Pair [re-posted by Ned Konz as an attached changeset] The attached file-out is an improved inter-process signaling mechanism. It adds a method #signal: to Process that accepts an exception as its argument. It will signal the exception in the context of the receiver. If the receiver is currently suspended (i.e. not on a list), the exception will not get signaled until the process is resumed. If the receiver is currently blocking on a Semaphore, this method will return the receiver to a non-blocked state and the process will resume with the exception being signaled. If that exception is handled and resumed, the process will return to a blocked state if the semaphore does not have any excess signals. So, as Ned pointed out, you could use this to timeout a process that is waiting on a Semaphore with an exception. It might look something like this. | sem proc | sem := Semaphore new. proc := [sem wait] newProcess. proc resume. (Delay forSeconds: 5) wait. proc signal: (Error new messageText: 'hey wake up!!'; yourself). I think this has the potential for a multitude of uses. I can imagine extending the process browser such that you can right click and send a variety of common signals to a process. - Stephen "! !Process methodsFor: 'signaling' stamp: 'svp 9/19/2003 18:41'! pvtSignal: anException list: aList "Private. This method is used to signal an exception from another process...the receiver must be the active process. If the receiver was previously waiting on a Semaphore, then return the process to the waiting state after signaling the exception and if the Semaphore has not been signaled in the interim" "Since this method is not called in a normal way, we need to take care that it doesn't directly return to the caller (because I believe that could have the potential to push an unwanted object on the caller's stack)." | blocker | self isActiveProcess ifFalse: [^self]. anException signal. blocker := Semaphore new. [self suspend. suspendedContext := suspendedContext swapSender: nil. aList class == Semaphore ifTrue: [aList isSignaled ifTrue: [aList wait. "Consume the signal that would have restarted the receiver" self resume] ifFalse: ["Add us back to the Semaphore's list (and remain blocked)" myList := aList. aList add: self]] ifFalse: [self resume]] fork. blocker wait. ! ! !Process methodsFor: 'signaling' stamp: 'svp 9/19/2003 18:42'! signal: anException "Signal an exception in the receiver process...if the receiver is currently suspended, the exception will get signaled when the receiver is resumed. If the receiver is blocked on a Semaphore, it will be immediately re-awakened and the exception will be signaled; if the exception is resumed, then the receiver will return to a blocked state unless the blocking Semaphore has excess signals" "If we are the active process, go ahead and signal the exception" self isActiveProcess ifTrue: [^anException signal]. "Add a new method context to the stack that will signal the exception" suspendedContext := MethodContext sender: suspendedContext receiver: self method: (self class methodDict at: #pvtSignal:list:) arguments: (Array with: anException with: myList). "If we are on a list to run, then suspend and restart the receiver (this lets the receiver run if it is currently blocked on a semaphore). If we are not on a list to be run (i.e. this process is suspended), then when the process is resumed, it will signal the exception" myList ifNotNil: [self suspend; resume].! !