'From Squeak3.8gamma of ''24 November 2004'' [latest update: #6550] on 23 February 2005 at 4:48:41 pm'! "Change Set: ProcessSignalException Date: 23 February 2005 Author: Andreas Raab Change Process>>signal: anException to Process>>signalException: anException."! !BlockClosure methodsFor: 'evaluating' stamp: 'ar 2/23/2005 11:48'! valueWithin: aDuration onTimeout: timeoutBlock "Evaluate the receiver. If the evaluation does not complete in less than aDuration evaluate the timeoutBlock instead" | theProcess delay watchdog done result | aDuration <= Duration zero ifTrue: [^ timeoutBlock value ]. "the block will be executed in the current process" theProcess := Processor activeProcess. delay := aDuration asDelay. "make a watchdog process" watchdog := [ delay wait. "wait for timeout or completion" done ifFalse: [ theProcess signalException: TimedOut ] ] newProcess. "watchdog needs to run at high priority to do its job" watchdog priority: Processor timingPriority. "catch the timeout signal" ^ [ done := false. watchdog resume. "start up the watchdog" result := self value. "evaluate the receiver" done := true. "it has completed, so ..." delay delaySemaphore signal. "arrange for the watchdog to exit" result ] on: TimedOut do: [ :e | timeoutBlock value ]. ! ! !BlockContext methodsFor: 'evaluating' stamp: 'ar 2/23/2005 11:48'! valueWithin: aDuration onTimeout: timeoutBlock "Evaluate the receiver. If the evaluation does not complete in less than aDuration evaluate the timeoutBlock instead" | theProcess delay watchdog done result | aDuration <= Duration zero ifTrue: [^ timeoutBlock value ]. "the block will be executed in the current process" theProcess := Processor activeProcess. delay := aDuration asDelay. "make a watchdog process" watchdog := [ delay wait. "wait for timeout or completion" done ifFalse: [ theProcess signalException: TimedOut ] ] newProcess. "watchdog needs to run at high priority to do its job" watchdog priority: Processor timingPriority. "catch the timeout signal" ^ [ done := false. watchdog resume. "start up the watchdog" result := self value. "evaluate the receiver" done := true. "it has completed, so ..." delay delaySemaphore signal. "arrange for the watchdog to exit" result ] on: TimedOut do: [ :e | timeoutBlock value ]. ! ! !Process methodsFor: 'signaling' stamp: 'ar 2/23/2005 11:48'! signalException: 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].! ! Process removeSelector: #signal:!