1 " |
1 " |
2 COPYRIGHT (c) 1993 by Claus Gittinger |
2 COPYRIGHT (c) 1993 by Claus Gittinger |
3 All Rights Reserved |
3 All Rights Reserved |
4 |
4 |
5 This software is furnished under a license and may be used |
5 This software is furnished under a license and may be used |
6 only in accordance with the terms of that license and with the |
6 only in accordance with the terms of that license and with the |
7 inclusion of the above copyright notice. This software may not |
7 inclusion of the above copyright notice. This software may not |
8 be provided or otherwise made available to, or used by, any |
8 be provided or otherwise made available to, or used by, any |
9 other person. No title to or ownership of the software is |
9 other person. No title to or ownership of the software is |
10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 |
12 |
13 Object subclass:#Signal |
13 Object subclass:#Signal |
14 instanceVariableNames:'mayProceed notifierString nameClass message |
14 instanceVariableNames:'mayProceed notifierString nameClass message |
15 handlerBlock' |
15 handlerBlock parent' |
16 classVariableNames:'NoHandlerSignal' |
16 classVariableNames:'NoHandlerSignal RecursiveRaiseSignal' |
17 poolDictionaries:'' |
17 poolDictionaries:'' |
18 category:'Kernel-Exceptions' |
18 category:'Kernel-Exceptions' |
19 ! |
19 ! |
20 |
20 |
21 Signal comment:' |
21 Signal comment:' |
22 COPYRIGHT (c) 1993 by Claus Gittinger |
22 COPYRIGHT (c) 1993 by Claus Gittinger |
23 All Rights Reserved |
23 All Rights Reserved |
24 |
24 |
25 $Header: /cvs/stx/stx/libbasic/Signal.st,v 1.13 1994-08-23 23:11:14 claus Exp $ |
25 $Header: /cvs/stx/stx/libbasic/Signal.st,v 1.14 1994-10-10 00:28:19 claus Exp $ |
26 '! |
26 '! |
27 |
27 |
28 !Signal class methodsFor:'documentation'! |
28 !Signal class methodsFor:'documentation'! |
29 |
29 |
30 copyright |
30 copyright |
31 " |
31 " |
32 COPYRIGHT (c) 1993 by Claus Gittinger |
32 COPYRIGHT (c) 1993 by Claus Gittinger |
33 All Rights Reserved |
33 All Rights Reserved |
34 |
34 |
35 This software is furnished under a license and may be used |
35 This software is furnished under a license and may be used |
36 only in accordance with the terms of that license and with the |
36 only in accordance with the terms of that license and with the |
37 inclusion of the above copyright notice. This software may not |
37 inclusion of the above copyright notice. This software may not |
38 be provided or otherwise made available to, or used by, any |
38 be provided or otherwise made available to, or used by, any |
96 |
96 |
97 See samples in doc/coding. |
97 See samples in doc/coding. |
98 |
98 |
99 Instance variables: |
99 Instance variables: |
100 |
100 |
101 mayProceed <Boolean> hint for the debugger - program may |
101 mayProceed <Boolean> hint for the debugger - program may |
102 proceed (currently not honored by the |
102 proceed (currently not honored by the |
103 debugger) |
103 debugger) |
104 |
104 |
105 notifierString <String> eror message to be output |
105 notifierString <String> eror message to be output |
106 |
106 |
107 nameClass <???> I dont know what this is for |
107 nameClass <???> I dont know what this is for |
108 (included for ST-80 compatibility) |
108 (included for ST-80 compatibility) |
109 |
109 |
110 message <???> I dont know what this is for |
110 message <???> I dont know what this is for |
111 (included for ST-80 compatibility) |
111 (included for ST-80 compatibility) |
112 |
112 |
113 handlerBlock <Block> if nonNil, a 1-arg block to be |
113 handlerBlock <Block> if nonNil, a 1-arg block to be |
114 evaluated when no handler context is |
114 evaluated when no handler context is |
115 found. The block gets the exception |
115 found. The block gets the exception |
116 object as argument. |
116 object as argument. |
117 |
117 |
118 Notice: |
118 Notice: |
119 Part of the implementation is a left-over from old times when the |
119 Part of the implementation is a left-over from old times when the |
120 resume/restart things in context did not work properly. Now, with the |
120 resume/restart things in context did not work properly. Now, with the |
121 handler- and suspendedContext at hand, the exception can do it using |
121 handler- and suspendedContext at hand, the exception can do it using |
146 |
153 |
147 noHandlerSignal |
154 noHandlerSignal |
148 "return the signal used to handle unhandled signals" |
155 "return the signal used to handle unhandled signals" |
149 |
156 |
150 ^ NoHandlerSignal |
157 ^ NoHandlerSignal |
|
158 ! |
|
159 |
|
160 recursiveRaiseSignal |
|
161 "return the signal used to handle recursive signal raises" |
|
162 |
|
163 ^ RecursiveRaiseSignal |
151 ! ! |
164 ! ! |
152 |
165 |
153 !Signal methodsFor:'instance creation'! |
166 !Signal methodsFor:'instance creation'! |
154 |
167 |
155 newSignalMayProceed:aBoolean |
168 newSignalMayProceed:aBoolean |
156 "create a new signal, using the receiver as a prototype" |
169 "create a new signal, using the receiver as a prototype and |
157 |
170 setting the parent of the new signal to the receiver." |
158 ^ (self copy) mayProceed:aBoolean |
171 |
|
172 |newSignal| |
|
173 |
|
174 newSignal := (self copy) mayProceed:aBoolean. |
|
175 newSignal parent:self. |
|
176 ^ newSignal |
159 ! |
177 ! |
160 |
178 |
161 newSignal |
179 newSignal |
162 "create a new signal, using the receiver as a prototype" |
180 "create a new signal, using the receiver as a prototype and |
163 |
181 setting the parent of the new signal to the receiver." |
164 ^ (self copy) |
182 |
|
183 ^ (self copy) parent:self |
|
184 ! ! |
|
185 |
|
186 !Signal methodsFor:'copying'! |
|
187 |
|
188 deepCopy |
|
189 "raise an error - deepCopy is not allowed for signals" |
|
190 |
|
191 ^ self deepCopyError |
165 ! ! |
192 ! ! |
166 |
193 |
167 !Signal methodsFor:'accessing'! |
194 !Signal methodsFor:'accessing'! |
168 |
195 |
169 nameClass:aClass message:aSelector |
196 nameClass:aClass message:aSelector |
170 "I dont know what that is used for (yet)" |
197 "this sets the class & selector of a method which returns |
|
198 that signal - this is simply for documentation purposes - |
|
199 see Signal>>printOn: implementation. |
|
200 (took me a while to find that one out ;-)" |
171 |
201 |
172 nameClass := aClass. |
202 nameClass := aClass. |
173 message := aSelector |
203 message := aSelector |
174 ! |
204 ! |
175 |
205 |
196 handlerBlock:aOneArgBlock |
238 handlerBlock:aOneArgBlock |
197 "set the handlerblock - this will be evaluated with the exception |
239 "set the handlerblock - this will be evaluated with the exception |
198 object as argument, if no #handle:do: context was found on the stack." |
240 object as argument, if no #handle:do: context was found on the stack." |
199 |
241 |
200 handlerBlock := aOneArgBlock |
242 handlerBlock := aOneArgBlock |
|
243 ! ! |
|
244 |
|
245 !Signal methodsFor:'printing'! |
|
246 |
|
247 printOn:aStream |
|
248 "append a printed representation of the receiver on aStream" |
|
249 |
|
250 nameClass notNil ifTrue:[ |
|
251 aStream nextPutAll:nameClass name. |
|
252 aStream space. |
|
253 aStream nextPutAll:message. |
|
254 ^ self |
|
255 ]. |
|
256 ^ super printOn:aStream |
201 ! ! |
257 ! ! |
202 |
258 |
203 !Signal methodsFor:'save evaluation'! |
259 !Signal methodsFor:'save evaluation'! |
204 |
260 |
205 handle:handleBlock do:aBlock |
261 handle:handleBlock do:aBlock |
213 |
269 |
214 ^ aBlock value "the real logic is in raise/Exception" |
270 ^ aBlock value "the real logic is in raise/Exception" |
215 |
271 |
216 " |
272 " |
217 Object messageNotUnderstoodSignal handle:[:ex | |
273 Object messageNotUnderstoodSignal handle:[:ex | |
218 'oops' printNL. |
274 'oops' printNL. |
219 ex return |
275 ex return |
220 ] do:[ |
276 ] do:[ |
221 123 size open |
277 123 size open |
222 ] |
278 ] |
223 " |
279 " |
224 |
280 |
225 " |
281 " |
226 |num| |
282 |num| |
227 |
283 |
228 num := 0. |
284 num := 0. |
229 Number divisionByZeroSignal handle:[:ex | |
285 Number divisionByZeroSignal handle:[:ex | |
230 'oops' printNL. |
286 'oops' printNL. |
231 ex return |
287 ex return |
232 ] do:[ |
288 ] do:[ |
233 123 / num |
289 123 / num |
234 ] |
290 ] |
235 " |
291 " |
236 ! |
292 ! |
237 |
293 |
238 catch:aBlock |
294 catch:aBlock |
239 "evaluate the argument, aBlock; return false. |
295 "evaluate the argument, aBlock. |
240 If the receiver-signal is raised during evaluation, abort |
296 If the receiver-signal is raised during evaluation, abort |
241 the evaluation and return true. |
297 the evaluation and return true; otherwise return false. |
242 This is the catch & throw mechanism found in other languages, |
298 This is the catch & throw mechanism found in other languages, |
243 where the returned value indicates if an exception occured." |
299 where the returned value indicates if an exception occured." |
244 |
300 |
245 |raiseOccurred| |
301 |raiseOccurred| |
246 |
302 |
248 self handle:[:ex | raiseOccurred := true. ex return] do:aBlock. |
304 self handle:[:ex | raiseOccurred := true. ex return] do:aBlock. |
249 ^ raiseOccurred |
305 ^ raiseOccurred |
250 |
306 |
251 " |
307 " |
252 Object messageNotUnderstoodSignal catch:[ |
308 Object messageNotUnderstoodSignal catch:[ |
253 123 size open |
309 123 size open |
254 ] |
310 ] |
255 " |
311 " |
|
312 ! |
|
313 |
|
314 ignore:aBlock |
|
315 "evaluate the argument, aBlock. |
|
316 Ignore the receiver-signal during evaluation - i.e. simply |
|
317 continue. This makes only sense for some signals, such as UserInterrupt |
|
318 or AbortSignals, because continuing after an exception without any cleanup |
|
319 will often lead to followup-errors." |
|
320 |
|
321 ^ self handle:[:ex | ex proceed] do:aBlock. |
|
322 |
|
323 " |
|
324 Object messageNotUnderstoodSignal ignore:[ |
|
325 123 size open |
|
326 ] |
|
327 " |
256 ! ! |
328 ! ! |
257 |
329 |
258 !Signal methodsFor:'queries'! |
330 !Signal methodsFor:'queries'! |
|
331 |
|
332 accepts:aSignal |
|
333 "return true, if the receiver accepts the argument, aSignal. |
|
334 (i.e. the recevier is aSignal or a parent of it). False otherwise." |
|
335 |
|
336 |s| |
|
337 |
|
338 s := aSignal. |
|
339 [s notNil] whileTrue:[ |
|
340 self == s ifTrue:[^ true]. |
|
341 s := s parent |
|
342 ]. |
|
343 ^ false |
|
344 ! |
259 |
345 |
260 isHandled |
346 isHandled |
261 "return true, if there is a handler for the receiver signal. |
347 "return true, if there is a handler for the receiver signal. |
262 Raising an unhandled signal will usually lead into the debugger, |
348 Raising an unhandled signal will usually lead into the debugger, |
263 but can be cought globally by setting Exceptions EmergencyHandler." |
349 but can be cought globally by setting Exceptions EmergencyHandler." |
296 (thus making things cleaner in the debugger-walkback eventually)" |
381 (thus making things cleaner in the debugger-walkback eventually)" |
297 |
382 |
298 |ex block| |
383 |ex block| |
299 |
384 |
300 ex := Exception new |
385 ex := Exception new |
301 signal:self |
386 signal:self |
302 parameter:nil |
387 parameter:nil |
303 errorString:notifierString |
388 errorString:notifierString |
304 suspendedContext:thisContext sender. |
389 suspendedContext:thisContext sender. |
305 |
390 |
306 ex resumeBlock:[:value | ^ value]. |
391 ex resumeBlock:[:value | ^ value]. |
307 self evaluateHandlerWith:ex. |
392 self evaluateHandlerWith:ex. |
308 |
393 |
309 (block := handlerBlock) isNil ifTrue:[ |
394 (block := handlerBlock) isNil ifTrue:[ |
310 " |
395 " |
311 if I am not the NoHandlerSignal, raise it ... |
396 if I am not the NoHandlerSignal, raise it ... |
312 passing the exception as parameter. |
397 passing the exception as parameter. |
313 " |
398 " |
314 self == NoHandlerSignal ifFalse:[ |
399 self == NoHandlerSignal ifFalse:[ |
315 ^ NoHandlerSignal |
400 ^ NoHandlerSignal |
316 raiseRequestWith:ex |
401 raiseRequestWith:ex |
317 errorString:('unhandled exception: ' , ex errorString) |
402 errorString:('unhandled exception: ' , ex errorString) |
318 ]. |
403 ]. |
319 |
404 |
320 " |
405 " |
321 otherwise, |
406 otherwise, |
322 take either a per-process emergencyHandlerBlock |
407 take either a per-process emergencyHandlerBlock |
323 or the global emergencyHandler (from Exception) ... |
408 or the global emergencyHandler (from Exception) ... |
324 " |
409 " |
325 block := Processor activeProcess emergencySignalHandler. |
410 Processor notNil ifTrue:[ |
326 block isNil ifTrue:[ |
411 "care for signal during startup (Processor not yet created)" |
327 block := Exception emergencyHandler |
412 block := Processor activeProcess emergencySignalHandler. |
328 ] |
413 ]. |
|
414 block isNil ifTrue:[ |
|
415 block := Exception emergencyHandler |
|
416 ]. |
|
417 block isNil ifTrue:[ |
|
418 "care for error during startup (Exception not yet initialized)" |
|
419 ^ MiniDebugger enterWithMessage:ex errorString |
|
420 ] |
329 ]. |
421 ]. |
330 |
422 |
331 "... and call it" |
423 "... and call it" |
332 ^ block value:ex. |
424 ^ block value:ex. |
333 ! |
425 ! |
342 (thus making things cleaner in the debugger-walkback eventually)" |
434 (thus making things cleaner in the debugger-walkback eventually)" |
343 |
435 |
344 |ex block| |
436 |ex block| |
345 |
437 |
346 ex := Exception new |
438 ex := Exception new |
347 signal:self |
439 signal:self |
348 parameter:aParameter |
440 parameter:aParameter |
349 errorString:notifierString |
441 errorString:notifierString |
350 suspendedContext:thisContext sender. |
442 suspendedContext:thisContext sender. |
351 |
443 |
352 ex resumeBlock:[:value | ^ value]. |
444 ex resumeBlock:[:value | ^ value]. |
353 self evaluateHandlerWith:ex. |
445 self evaluateHandlerWith:ex. |
354 |
446 |
355 (block := handlerBlock) isNil ifTrue:[ |
447 (block := handlerBlock) isNil ifTrue:[ |
356 " |
448 " |
357 if I am not the NoHandlerSignal, raise it ... |
449 if I am not the NoHandlerSignal, raise it ... |
358 passing the exception as parameter. |
450 passing the exception as parameter. |
359 " |
451 " |
360 self == NoHandlerSignal ifFalse:[ |
452 self == NoHandlerSignal ifFalse:[ |
361 ^ NoHandlerSignal |
453 ^ NoHandlerSignal |
362 raiseRequestWith:ex |
454 raiseRequestWith:ex |
363 errorString:('unhandled exception: ' , ex errorString) |
455 errorString:('unhandled exception: ' , ex errorString) |
364 ]. |
456 ]. |
365 |
457 |
366 " |
458 " |
367 otherwise, |
459 otherwise, |
368 take either a per-process emergencyHandlerBlock |
460 take either a per-process emergencyHandlerBlock |
369 or the global emergencyHandler (from Exception) ... |
461 or the global emergencyHandler (from Exception) ... |
370 " |
462 " |
371 block := Processor activeProcess emergencySignalHandler. |
463 Processor notNil ifTrue:[ |
372 block isNil ifTrue:[ |
464 "care for signal during startup (Processor not yet created)" |
373 block := Exception emergencyHandler |
465 block := Processor activeProcess emergencySignalHandler. |
374 ] |
466 ]. |
|
467 block isNil ifTrue:[ |
|
468 block := Exception emergencyHandler |
|
469 ]. |
|
470 block isNil ifTrue:[ |
|
471 "care for error during startup (Exception not yet initialized)" |
|
472 ^ MiniDebugger enterWithMessage:ex errorString |
|
473 ] |
375 ]. |
474 ]. |
376 |
475 |
377 "... and call it" |
476 "... and call it" |
378 ^ block value:ex. |
477 ^ block value:ex. |
379 ! |
478 ! |
385 XXX: I am not certain, if this is the correct behavior (seen in remoteInvocation-goodie)" |
484 XXX: I am not certain, if this is the correct behavior (seen in remoteInvocation-goodie)" |
386 |
485 |
387 |ex block| |
486 |ex block| |
388 |
487 |
389 ex := Exception new |
488 ex := Exception new |
390 signal:self |
489 signal:self |
391 parameter:nil |
490 parameter:nil |
392 errorString:something printString |
491 errorString:something printString |
393 suspendedContext:thisContext sender. |
492 suspendedContext:thisContext sender. |
394 |
493 |
395 ex resumeBlock:[:value | ^ value]. |
494 ex resumeBlock:[:value | ^ value]. |
396 self evaluateHandlerWith:ex. |
495 self evaluateHandlerWith:ex. |
397 |
496 |
398 (block := handlerBlock) isNil ifTrue:[ |
497 (block := handlerBlock) isNil ifTrue:[ |
399 " |
498 " |
400 if I am not the NoHandlerSignal, raise it ... |
499 if I am not the NoHandlerSignal, raise it ... |
401 passing the exception as parameter. |
500 passing the exception as parameter. |
402 " |
501 " |
403 self == NoHandlerSignal ifFalse:[ |
502 self == NoHandlerSignal ifFalse:[ |
404 ^ NoHandlerSignal |
503 ^ NoHandlerSignal |
405 raiseRequestWith:ex |
504 raiseRequestWith:ex |
406 errorString:('unhandled exception: ' , ex errorString) |
505 errorString:('unhandled exception: ' , ex errorString) |
407 ]. |
506 ]. |
408 |
507 |
409 " |
508 " |
410 otherwise, |
509 otherwise, |
411 take either a per-process emergencyHandlerBlock |
510 take either a per-process emergencyHandlerBlock |
412 or the global emergencyHandler (from Exception) ... |
511 or the global emergencyHandler (from Exception) ... |
413 " |
512 " |
414 block := Processor activeProcess emergencySignalHandler. |
513 Processor notNil ifTrue:[ |
415 block isNil ifTrue:[ |
514 "care for signal during startup (Processor not yet created)" |
416 block := Exception emergencyHandler |
515 block := Processor activeProcess emergencySignalHandler. |
417 ] |
516 ]. |
|
517 block isNil ifTrue:[ |
|
518 block := Exception emergencyHandler |
|
519 ]. |
|
520 block isNil ifTrue:[ |
|
521 "care for error during startup (Exception not yet initialized)" |
|
522 ^ MiniDebugger enterWithMessage:ex errorString |
|
523 ] |
418 ]. |
524 ]. |
419 |
525 |
420 "... and call it" |
526 "... and call it" |
421 ^ block value:ex. |
527 ^ block value:ex. |
422 ! |
528 ! |
427 The argument, aString is used as errorString." |
533 The argument, aString is used as errorString." |
428 |
534 |
429 |ex block| |
535 |ex block| |
430 |
536 |
431 ex := Exception new |
537 ex := Exception new |
432 signal:self |
538 signal:self |
433 parameter:aParameter |
539 parameter:aParameter |
434 errorString:aString |
540 errorString:aString |
435 suspendedContext:thisContext sender. |
541 suspendedContext:thisContext sender. |
436 |
542 |
437 ex resumeBlock:[:value | ^ value]. |
543 ex resumeBlock:[:value | ^ value]. |
438 self evaluateHandlerWith:ex. |
544 self evaluateHandlerWith:ex. |
439 |
545 |
440 (block := handlerBlock) isNil ifTrue:[ |
546 (block := handlerBlock) isNil ifTrue:[ |
441 " |
547 " |
442 if I am not the NoHandlerSignal, raise it ... |
548 if I am not the NoHandlerSignal, raise it ... |
443 passing the exception as parameter. |
549 passing the exception as parameter. |
444 " |
550 " |
445 self == NoHandlerSignal ifFalse:[ |
551 self == NoHandlerSignal ifFalse:[ |
446 ^ NoHandlerSignal |
552 ^ NoHandlerSignal |
447 raiseRequestWith:ex |
553 raiseRequestWith:ex |
448 errorString:('unhandled exception: ' , ex errorString) |
554 errorString:('unhandled exception: ' , ex errorString) |
449 ]. |
555 ]. |
450 |
556 |
451 " |
557 " |
452 otherwise, |
558 otherwise, |
453 take either a per-process emergencyHandlerBlock |
559 take either a per-process emergencyHandlerBlock |
454 or the global emergencyHandler (from Exception) ... |
560 or the global emergencyHandler (from Exception) ... |
455 " |
561 " |
456 block := Processor activeProcess emergencySignalHandler. |
562 Processor notNil ifTrue:[ |
457 block isNil ifTrue:[ |
563 "care for signal during startup (Processor not yet created)" |
458 block := Exception emergencyHandler |
564 block := Processor activeProcess emergencySignalHandler. |
459 ] |
565 ]. |
|
566 block isNil ifTrue:[ |
|
567 block := Exception emergencyHandler |
|
568 ]. |
|
569 block isNil ifTrue:[ |
|
570 "care for error during startup (Exception not yet initialized)" |
|
571 ^ MiniDebugger enterWithMessage:ex errorString |
|
572 ] |
460 ]. |
573 ]. |
461 |
574 |
462 "... and call it" |
575 "... and call it" |
463 ^ block value:ex. |
576 ^ block value:ex. |
464 ! ! |
577 ! ! |
465 |
578 |
466 !Signal methodsFor:'private'! |
579 !Signal methodsFor:'private'! |
467 |
580 |
468 evaluateHandlerWith:anException |
581 evaluateHandlerWith:ex |
469 "search through the context-calling chain for a 'handle:do:'-context |
582 "search through the context-calling chain for a 'handle:do:'-context |
470 to the receiver or a SignalSet which includes the receiver. |
583 to the receiver or a parent of the receiver or a SignalSet which includes |
|
584 the receiver. |
471 If found, take its 2nd argument (the handler) and evaluate |
585 If found, take its 2nd argument (the handler) and evaluate |
472 it with the exception as argument. |
586 it with the exception as argument. |
473 If none found, just return." |
587 If none found, just return." |
474 |
588 |
475 |con| |
589 |con| |
476 |
590 |
477 con := thisContext. |
591 con := thisContext. |
478 con := con sender. |
592 con := con sender. |
479 con isRecursive ifTrue:[ |
593 con isRecursive ifTrue:[ |
480 " |
594 " |
481 mhmh - an error while in a handler |
595 mhmh - an error while in a handler |
482 go immediately into the debugger. |
596 " |
483 " |
597 ((self == RecursiveRaiseSignal) |
484 ^ self enterDebuggerWith:anException |
598 or:[RecursiveRaiseSignal isNil]) ifTrue:[ |
485 message:'recursive signal raise' |
599 " |
|
600 ... either while handling RecursiveSignal |
|
601 or at startup when RecursiveSignal is not yet |
|
602 created - |
|
603 - go immediately into the debugger. |
|
604 " |
|
605 ^ self enterDebuggerWith:ex |
|
606 message:'recursive signal raise' |
|
607 ]. |
|
608 ^ RecursiveRaiseSignal |
|
609 raiseRequestWith:ex |
|
610 errorString:('recursive signal raise: ' , ex errorString) |
486 ]. |
611 ]. |
487 |
612 |
488 [con notNil] whileTrue:[ |
613 [con notNil] whileTrue:[ |
489 (con selector == #'handle:do:') ifTrue:[ |
614 (con selector == #'handle:do:') ifTrue:[ |
490 " |
615 " |
491 if this is the Signal>>handle:do: context |
616 if this is the Signal>>handle:do: context |
492 or a SignalSet>>handle:do: context with self in it, |
617 or a SignalSet>>handle:do: context with self in it, |
493 call the handler |
618 call the handler |
494 " |
619 " |
495 ((con receiver == self) |
620 (con receiver accepts:self) ifTrue:[ |
496 or:[(con receiver isMemberOf:SignalSet) |
621 "call the handler" |
497 and:[con receiver includes:self]]) ifTrue:[ |
622 |
498 "call the handler" |
623 ex handlerContext:con. |
499 |
624 self doCallHandler:(con args at:1) with:ex. |
500 anException handlerContext:con. |
625 |
501 self doCallHandler:(con args at:1) with:anException. |
626 "if the handler rejects or falls through we arrive here" |
502 |
627 "continue search for another handler" |
503 "if the handler rejects or falls through we arrive here" |
628 ]. |
504 "continue search for another handler" |
629 ]. |
505 ]. |
630 con := con sender |
506 ]. |
|
507 con := con sender |
|
508 ]. |
631 ]. |
509 |
632 |
510 " |
633 " |
511 we arrive here, if either no handler was found, or none of the |
634 we arrive here, if either no handler was found, or none of the |
512 handlers did a return (i.e. every handler rejected or fell through). |
635 handlers did a return (i.e. every handler rejected or fell through). |