--- a/SignalSet.st Fri Feb 15 13:49:04 2002 +0100
+++ b/SignalSet.st Fri Feb 15 13:59:22 2002 +0100
@@ -158,24 +158,62 @@
!SignalSet methodsFor:'save evaluation'!
catch:aBlock
- "evaluate the argument, aBlock.
- If any of the signals in the receiver is raised during evaluation,
- abort the evaluation and return true; otherwise return false.
- With the special anySignal, evaluation can be performed totally save
- from signals
- - but who (beside radical c++ fans) would do that ?"
+ "evaluate the argument, aBlock.
+ If any of the signals in the receiver is raised during evaluation,
+ abort the evaluation and return true; otherwise return false.
+ With the special anySignal, evaluation can be performed totally save
+ from signals
+ - but who (beside radical c++ fans) would do that ?"
+
+ |raiseOccurred|
+
+ raiseOccurred := false.
+ self handle:[:ex | raiseOccurred := true. ex return] do:aBlock.
+ ^ raiseOccurred
- |raiseOccurred|
+ "
+ SignalSet anySignal catch:[
+ (#(1 2 3 4) at:5) / 0.0
+ ]
+ "
+!
+
+deferAfter:aBlock
+ "evaluate the argument, aBlock.
+ Ignore the receiver-signal during evaluation - i.e. simply continue,
+ but remember if the signal was raised.
+ After the block evaluation, finally raise the signal - if it was raised in the block.
+ If the signal is raised multiple times, only the first raises parameter is remembered,
+ and only a single raise is performed after the blocks evaluation.
- raiseOccurred := false.
- self handle:[:ex | raiseOccurred := true. ex return] do:aBlock.
- ^ raiseOccurred
+ Deferring makes sense for some signals, such as UserInterrupt or AbortSignal,
+ which must occasionally be delayed temprarily until a save place is reached
+ (especially when packages are sent across a communication channel, and you dont want
+ partial packages to be generated by user interruptions)."
+
+ |raisedSignal parameter result|
- "
- SignalSet anySignal catch:[
- (#(1 2 3 4) at:5) / 0.0
- ]
- "
+ self handle:[:ex |
+ raisedSignal isNil ifTrue:[
+ raisedSignal := ex signal.
+ parameter := ex parameter.
+ ].
+ ex proceedWith:nil
+ ] do:[
+ result := aBlock value.
+ ].
+ raisedSignal notNil ifTrue:[
+ "/ the signal was raised during the execution
+ "/ above. Raise it now (delayed).
+ raisedSignal raiseWith:parameter.
+ ].
+ ^ result
+
+ "
+ UserInterrupt deferAfter:[
+ UserInterrupt raiseWith:'hello'
+ ]
+ "
!
handle:handleBlock do:aBlock
@@ -233,26 +271,26 @@
!
ignoreIn:aBlock
- "evaluate the argument, aBlock.
- Ignore the any signals from the receiver during evaluation - i.e. simply
- continue. This makes only sense for some signals, such as UserInterrupt
- or AbortSignals, because continuing after an exception without any cleanup
- will often lead to followup-errors."
+ "evaluate the argument, aBlock.
+ Ignore the any signals from the receiver during evaluation - i.e. simply
+ continue. This makes only sense for some signals, such as UserInterrupt
+ or AbortSignals, because continuing after an exception without any cleanup
+ will often lead to followup-errors."
- ^ self handle:[:ex | ex proceedWith:nil] do:aBlock.
+ ^ self handle:[:ex | ex proceedWith:nil] do:aBlock.
- "
- SignalSet anySignal ignoreIn:[
- 123 size open
- ]
- "
+ "
+ SignalSet anySignal ignoreIn:[
+ 123 size open
+ ]
+ "
- "Created: / 27.1.1997 / 20:32:50 / cg"
- "Modified: / 4.3.1998 / 16:36:30 / cg"
+ "Created: / 27.1.1997 / 20:32:50 / cg"
+ "Modified: / 4.3.1998 / 16:36:30 / cg"
! !
!SignalSet class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/SignalSet.st,v 1.34 2001-03-23 13:43:18 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/SignalSet.st,v 1.35 2002-02-15 12:59:15 cg Exp $'
! !