Feature #714
Interrupt mechanism
Description
Add an interrupt mechanism to CoCoALib.
Related issues
History
#1 Updated by John Abbott almost 9 years ago
As far as CoCoA-5 is concerned CoCoALib is "external software", and the problem noted in #713 applies as much to CoCoALib as to other external libraries.
I suggest the following design:- there is a global flag
CoCoA::InterruptFlag
which is normallyfalse
- there is a function
CoCoA::SignalInterrupt
which sets the flag - there is a function
CoCoA::CheckForInterrupt
which tests the flag; iffalse
, the function simply returns; otherwise it resets the flag, and throws aCoCoA::interrupted
exception
CoCoALib authors would then be obliged to call CheckForInterrupt
every so often, so that an interrupt will actually take effect within a reasonable time.
#2 Updated by John Abbott almost 9 years ago
There is a slight risk in my proposal above. If SignalInterrupt
is called asynchronously while CheckForInterrupt
is running, and has just reset the flag but not yet thrown the exception, then the flag will be set while the exception is thrown. This could be rather unexpected.
I suggest that a new class CoCoA::InterruptException
be the type thrown. Its destructor could reset the interrupt flag. This should ensure that the flag is reset once the (interrupt) exception handler exits scope. This should have the effect of ignoring any further signals while the exception is propagating and being handled.
Maybe even: the ctor for CoCoA::InterruptException
could block all signals (and then reset the flag), and the dtor unblocks them. This fits in well with ctor-dtor corresponding to resource acquisition-release.
#3 Updated by John Abbott almost 9 years ago
Here is a further complication: how to handle several libraries together?
Let us suppose that CoCoALib has a mechanism similar to that outlined above, and that libnormaliz has an analogous system.
Suppose we have CoCoALib+libnormaliz working on a problem, and we want to interrupt the computation. From outside we do not know whether the currently running code is part of CoCoALib or part of libnormaliz; so we want to set both flags to be certain that the running code will see the interrupt.
We must also make sure that all flags are reset when the interrupt is handled. Perhaps the simplest solution is to have a single shared flag; this implies that CoCoALib and libnormaliz must work with references to some common global flag. How to tell them where this flag is? In CoCoALib, this could probably be done via GlobalManager
.
#4 Updated by John Abbott almost 9 years ago
- Status changed from New to In Progress
- % Done changed from 0 to 20
I have implemented a first version following the outlines given above.
It seems to pass a quick test -- I have made RingBase::mySequentialPower
interruptible, and have verified that it works.
- (A) check that the new
catch
statement in the interpreter (Interpreter.C:2678
) is all that is needed - (B) print out some message about being interrupted
- (C) is there some way to put in context information? (e.g. convert
CoCoA::InterruptReceived
intoInterruptException
with context info) - (D) insert numerous calls to
CheckForInterrupt()
throughout CoCoALib
(D) will be long and tedious, but probably not too hard -- make a new issue?
(C) requires studying the interpreter; maybe Giovanni can help?
(B) probably becomes irrelevant if (C) can be done well
(A) again Giovanni's help would be a boon!
#5 Updated by John Abbott almost 9 years ago
Also seems to work with the C5 GUI now :-)
#6 Updated by John Abbott almost 9 years ago
- (A) specify the flag in
GlobalSettings
which is passed as ctor param toGlobalManager
- (B) specify the flag by calling a mem fn of
GlobalManager
Approach (B) is more powerful than approach (A) in that approach (A) can always be replaced by approach (B) but not vice versa (as I discovered when modifying src/CoCoA-5/Main.C
)
Is there any sense in offering approach (A)? Perhaps it is best to offer just (B), and add approach (A) later if there is good justification?
#7 Updated by Anna Maria Bigatti almost 9 years ago
John Abbott wrote:
Is there any sense in offering approach (A)? Perhaps it is best to offer just (B), and add approach (A) later if there is good justification?
(I admit I'm not understanding all the implications) my preference was for (B) even before reading John's last comment ;-)
#8 Updated by John Abbott almost 9 years ago
- Status changed from In Progress to Resolved
- Assignee set to John Abbott
- % Done changed from 20 to 80
I have checked in the impl with both (A) and (B).
Then I deleted (A) and checked in again. This way I hope (A) might still be recoverable from CVS if we should ever want it.
I'll discuss the design with Christof; and if all goes well, we can proceed to feedback
status.
PS I'm hoping Christof will add a similar feature to libnormaliz.
#9 Updated by John Abbott almost 9 years ago
- Status changed from Resolved to Feedback
- % Done changed from 80 to 90
I've been using the current code for a little while (not really proper testing), and no problems have come up. So changing status to feedback.
I am just slightly uneasy about the "clever trick" of making InterruptReceived
dtor reset the interrupt flag... but I cannot see how it can be harmful.
#10 Updated by Anna Maria Bigatti almost 9 years ago
- Status changed from Feedback to Closed
- % Done changed from 90 to 100
- Estimated time set to 4.51 h
Tested on my computer: pending interrupt and caught interrupt, they both work! Closing
#11 Updated by John Abbott almost 9 years ago
- Target version changed from CoCoALib-0.99540 Feb 2016 to CoCoALib-0.99536 June 2015
#12 Updated by John Abbott over 7 years ago
- Related to Bug #971: CheckForInterrupt does not work in the expected way added
#13 Updated by John Abbott almost 4 years ago
- Related to Bug #1458: Redesign interrupt mechanism? added