577 errorInterrupt:errID with:aParameter |
576 errorInterrupt:errID with:aParameter |
578 "{ Pragma: +optSpace }" |
577 "{ Pragma: +optSpace }" |
579 |
578 |
580 "an error in the devices low level code (typically Xlib or XtLib) |
579 "an error in the devices low level code (typically Xlib or XtLib) |
581 This is invoked via |
580 This is invoked via |
582 XError->errorInterrupt:#DisplayError->registeredErrorInterruptHandlers |
581 XError->errorInterrupt:#DisplayError->registeredErrorInterruptHandlers |
583 or |
582 or |
584 XError->errorInterrupt:#DisplayIOError->registeredErrorInterruptHandlers |
583 XError->errorInterrupt:#DisplayIOError->registeredErrorInterruptHandlers |
585 |
584 |
586 looks if a signal handler for DeviceErrorSignal is present, |
585 looks if a signal handler for DeviceErrorSignal is present, |
587 and - if so raises the signal. |
586 and - if so raises the signal. |
588 If the signal not handled, simply output a message and continue. |
587 If the signal not handled, simply output a message and continue. |
589 This allows for non disrupted error reporting OR to catch and |
588 This allows for non disrupted error reporting OR to catch and |
591 However, io-errors are always delivered as a signal raise." |
590 However, io-errors are always delivered as a signal raise." |
592 |
591 |
593 |badResource msg theDevice theSignal p signalHolder| |
592 |badResource msg theDevice theSignal p signalHolder| |
594 |
593 |
595 errID notNil ifTrue:[ |
594 errID notNil ifTrue:[ |
596 "/ |
595 "/ |
597 "/ timeoutError passes the device; |
596 "/ timeoutError passes the device; |
598 "/ the others pass the devicesID |
597 "/ the others pass the devicesID |
599 "/ |
598 "/ |
600 errID == #DisplayIOTimeoutError ifTrue:[ |
599 errID == #DisplayIOTimeoutError ifTrue:[ |
601 theDevice := aParameter. |
600 theDevice := aParameter. |
602 "/ 'device timeout error' printCR. |
601 "/ 'device timeout error' printCR. |
603 ] ifFalse:[ |
602 ] ifFalse:[ |
604 AllScreens do:[:aDisplayDevice | |
603 AllScreens do:[:aDisplayDevice | |
605 aDisplayDevice id = aParameter ifTrue:[ |
604 aDisplayDevice id = aParameter ifTrue:[ |
606 theDevice := aDisplayDevice. |
605 theDevice := aDisplayDevice. |
607 ] |
606 ] |
608 ] |
607 ] |
609 ] |
608 ] |
610 ]. |
609 ]. |
611 |
610 |
612 "/ now, we have the bad guy at hand ... |
611 "/ now, we have the bad guy at hand ... |
613 "/ get a per-instance signal. |
612 "/ get a per-instance signal. |
614 |
613 |
615 signalHolder := theDevice ? self. |
614 signalHolder := theDevice ? self. |
616 errID == #DisplayIOError ifTrue:[ |
615 errID == #DisplayIOError ifTrue:[ |
617 "always raises an exception" |
616 "always raises an exception" |
618 theSignal := signalHolder deviceIOErrorSignal. |
617 theSignal := signalHolder deviceIOErrorSignal. |
619 msg := 'Display I/O Error'. |
618 msg := 'Display I/O Error'. |
620 badResource := theDevice. |
619 badResource := theDevice. |
621 ] ifFalse:[errID == #DisplayIOTimeoutError ifTrue:[ |
620 ] ifFalse:[errID == #DisplayIOTimeoutError ifTrue:[ |
622 "always raises an exception for the current process" |
621 "always raises an exception for the current process" |
623 theSignal := signalHolder deviceIOTimeoutErrorSignal. |
622 theSignal := signalHolder deviceIOTimeoutErrorSignal. |
624 msg := 'Display I/O timeout Error'. |
623 msg := 'Display I/O timeout Error'. |
625 badResource := theDevice. |
624 badResource := theDevice. |
626 ] ifFalse:[ "errID == #DisplayError" |
625 ] ifFalse:[ "errID == #DisplayError" |
627 "only raises an exception if handled" |
626 "only raises an exception if handled" |
628 theSignal := signalHolder deviceErrorSignal. |
627 theSignal := signalHolder deviceErrorSignal. |
629 theDevice notNil ifTrue:[ |
628 theDevice notNil ifTrue:[ |
630 "/ #resourceIdOfLastError will become instance-specific information in |
629 "/ #resourceIdOfLastError will become instance-specific information in |
631 "/ the near future ... |
630 "/ the near future ... |
632 badResource := theDevice resourceOfId:self resourceIdOfLastError. |
631 badResource := theDevice resourceOfId:self resourceIdOfLastError. |
633 ]. |
632 ]. |
634 msg := 'Display error: ' , self lastErrorString. |
633 msg := 'Display error: ' , self lastErrorString. |
635 ]]. |
634 ]]. |
636 'DeviceWorkstation [info]: ' infoPrint. msg infoPrint. ' - ' infoPrint. badResource infoPrintCR. |
635 'DeviceWorkstation [info]: ' infoPrint. msg infoPrint. ' - ' infoPrint. badResource infoPrintCR. |
637 |
636 |
638 |
637 |
639 "interrupt that displays dispatch process |
638 "interrupt that displays dispatch process |
641 |
640 |
642 "DiplayIOTimeoutError is a synchronous event, that should hit the process |
641 "DiplayIOTimeoutError is a synchronous event, that should hit the process |
643 that caused the timeout." |
642 that caused the timeout." |
644 |
643 |
645 (errID ~~ #DisplayIOTimeoutError and:[theDevice notNil]) ifTrue:[ |
644 (errID ~~ #DisplayIOTimeoutError and:[theDevice notNil]) ifTrue:[ |
646 p := theDevice dispatchProcess. |
645 p := theDevice dispatchProcess. |
647 (p notNil and:[p ~~ Processor activeProcess]) ifTrue:[ |
646 (p notNil and:[p ~~ Processor activeProcess]) ifTrue:[ |
648 'DeviceWorkstation [info]: interrupting: ' infoPrint. p infoPrintCR. |
647 'DeviceWorkstation [info]: interrupting: ' infoPrint. p infoPrintCR. |
649 p interruptWith:[ |
648 p interruptWith:[ |
650 (errID == #DisplayError and:[theSignal isHandled not]) ifTrue:[ |
649 (errID == #DisplayError and:[theSignal isHandled not]) ifTrue:[ |
651 "unhandled display errors are ignored" |
650 "unhandled display errors are ignored" |
652 ErrorPrinting ifTrue:[ |
651 ErrorPrinting ifTrue:[ |
653 ('DeviceWorkstation [error]: ' , msg) errorPrintCR |
652 ('DeviceWorkstation [error]: ' , msg) errorPrintCR |
654 ]. |
653 ]. |
655 ] ifFalse:[ |
654 ] ifFalse:[ |
656 'DeviceWorkstation [info]: raising exception ...' infoPrintCR. |
655 'DeviceWorkstation [info]: raising exception ...' infoPrintCR. |
657 theSignal raiseSignalWith:badResource errorString:msg. |
656 theSignal raiseSignalWith:badResource errorString:msg. |
658 'DeviceWorkstation [warning]: exception returned - send brokenConnection' errorPrintCR. |
657 'DeviceWorkstation [warning]: exception returned - send brokenConnection' errorPrintCR. |
659 theDevice brokenConnection. |
658 theDevice brokenConnection. |
660 'DeviceWorkstation [warning]: stopping dispatch' errorPrintCR. |
659 'DeviceWorkstation [warning]: stopping dispatch' errorPrintCR. |
661 theDevice stopDispatch. |
660 theDevice stopDispatch. |
662 ]. |
661 ]. |
663 ]. |
662 ]. |
664 ^ self. |
663 ^ self. |
665 "/ Processor reschedule. |
664 "/ Processor reschedule. |
666 "/ AbortOperationRequest raise. |
665 "/ AbortOperationRequest raise. |
667 ]. |
666 ]. |
668 ]. |
667 ]. |
669 |
668 |
670 "If we come here, this is a DiplayIOTimeoutError, we don't know |
669 "If we come here, this is a DiplayIOTimeoutError, we don't know |
671 the display device or we are running on top of the dispatchProcess" |
670 the display device or we are running on top of the dispatchProcess" |
672 |
671 |
673 (theSignal isHandled or:[theSignal handlerBlock notNil]) ifTrue:[ |
672 (theSignal isHandled or:[theSignal handlerBlock notNil]) ifTrue:[ |
674 'DeviceWorkstation [info]: raising signal in current process' infoPrintCR. |
673 'DeviceWorkstation [info]: raising signal in current process' infoPrintCR. |
675 "/ Processor activeProcess displayString infoPrintCR. |
674 "/ Processor activeProcess displayString infoPrintCR. |
676 theSignal raiseSignalWith:badResource errorString:msg. |
675 theSignal raiseSignalWith:badResource errorString:msg. |
677 ]. |
676 ]. |
678 |
677 |
679 errID == #DisplayError ifTrue:[ |
678 errID == #DisplayError ifTrue:[ |
680 "unhandled display errors are ignored" |
679 "unhandled display errors are ignored" |
681 ^ self. |
680 ^ self. |
682 ]. |
681 ]. |
683 |
682 |
684 theDevice notNil ifTrue:[ |
683 theDevice notNil ifTrue:[ |
685 'DeviceWorkstation [info]: sending #brokenConnection' infoPrintCR. |
684 'DeviceWorkstation [info]: sending #brokenConnection' infoPrintCR. |
686 theDevice brokenConnection. |
685 theDevice brokenConnection. |
687 theDevice dispatchProcess == Processor activeProcess ifTrue:[ |
686 theDevice dispatchProcess == Processor activeProcess ifTrue:[ |
688 "I am running in the dispatch process |
687 "I am running in the dispatch process |
689 and nobody handles theSignal, so abort the dispatcher" |
688 and nobody handles theSignal, so abort the dispatcher" |
690 |
689 |
691 'DeviceWorkstation [info]: raising AbortOperationRequest' infoPrintCR. |
690 'DeviceWorkstation [info]: raising AbortOperationRequest' infoPrintCR. |
692 AbortOperationRequest raise. |
691 AbortOperationRequest raise. |
693 ] ifFalse:[ |
692 ] ifFalse:[ |
694 "Some other process (probably not even guilty - like someone doing a draw after a change) ... |
693 "Some other process (probably not even guilty - like someone doing a draw after a change) ... |
695 ... see if we can unwind out of the drawing operation" |
694 ... see if we can unwind out of the drawing operation" |
696 |
695 |
697 'DeviceWorkstation [info]: should unwind the draw operation' infoPrintCR. |
696 |context| |
698 thisContext fullPrintAll. |
697 |
699 ] |
698 "/ thisContext fullPrintAll. |
|
699 context := thisContext. |
|
700 [ |
|
701 "find the first returnable context where theDevice is the receiver" |
|
702 context := context sender. |
|
703 ] doUntil:[ |
|
704 context isNil or:[context receiver == theDevice and:[context canReturn]]. |
|
705 ]. |
|
706 context notNil ifTrue:[ |
|
707 'DeviceWorkstation [info]: unwind the draw operation' infoPrintCR. |
|
708 "/ context fullPrintAll. |
|
709 context unwind. |
|
710 "not reached" |
|
711 ]. |
|
712 ] |
700 ]. |
713 ]. |
701 'DeviceWorkstation [info]: proceeding after error' infoPrintCR. |
714 'DeviceWorkstation [info]: proceeding after error' infoPrintCR. |
702 |
715 |
703 "Modified: 11.4.1997 / 11:28:27 / cg" |
716 "Modified: 11.4.1997 / 11:28:27 / cg" |
704 ! |
717 ! |