[gccsdk] Threading + Alt-Break = Trashed Computer

John Tytgat John.Tytgat at aaug.net
Sat Jul 12 17:02:47 PDT 2008

In message <op.ud7brttdl0n5eg at balaptop.ba>
          "Ben Avison" <bavison at riscosopen.org> wrote:

> John Tytgat <John.Tytgat at aaug.net> wrote:
> > Actually Wimp's Watchdog.s in ROOL's codebase is pretty clear : in
> > watchdogcallback you have around line 209 the test whether the current
> > task needs to die or not.  In case of the former a more or less straight
> > OS_Exit is done and that's the case which works as expected.
> You're right, I didn't read it properly first time - just naïvely assumed
> that the obvious thing to happen was for the exit handler to always be
> called. The exit handler is actually only called if it's the current task
> that's being killed, as you say. This in itself is a problem for removing
> UnixLib's handlers - you'll need to rely on either Service_WimpCloseDown or
> Message_TaskCloseDown to detect the removal of the task.

...which is IMHO not a very attractive approach.  As you need another task
(handling Message_TaskCloseDown), or a module (handling
Service_WimpCloseDown) to clean up the mess of an Alt-Breaked task (even
without really knowing what exactly needs to be cleanup because that task
could have been terminated in a very gracefully matter).

> > In the other case, the chosen task is delinked from the Wimp's internals
> > and that's it.  This means the chosen task's exit handler does not get
> > called (and I don't think the environment is left in a sane state  
> > either).
> My initial impression of the code was "that must be doing something clever"
> but having studied it a bit more, I think it's just plain wrong.

I fully agree :-)

> If I had
> to guess, I'd say it was written by someone who didn't know you can pass a
> task handle parameter to Wimp_CloseDown. The task paging appears to be
> solely to ensure that the correct task is terminated by Wimp_CloseDown, but
> Wimp_CloseDown is written so as to postpone some of the cleanup until the
> following call to Wimp_Poll if it's the current task that's being killed. To
> compensate for this, they've cut-and-pasted the cleanup code from Wimp_Poll
> into the Watchdog, but it has the unfortunate side-effect of screwing up the
> environment for the task that was active when the key event went off.
> I've tried changing this to use a parameterised call to Wimp_CloseDown and
> this fixes the faulty test case I posted yesterday. As this is a worthwhile
> fix in its own right, I'll upload it to the ROOL CVS repository shortly.

This is an improvement but no solution for our case here and IMHO it is not
logical that handling terminating the current task is different than
terminating a not-current task (the former gets its Exit handler called,
the latter not).

> > I'm wondering why we don't have after the 'pageintask' call a SWI OS_Exit
> > call as well.
> Having thought about it, I can see why not. OS_Exit will flatten the SVC
> stack - and since we're inside a transient callback, the SVC stack may have
> quite a lot on it. When the exit handlers bubble out to the Wimp's exit
> handler, that will try to exit via Wimp_Poll, which has no way to know it
> needs to resume the task that was active when the key event went off, even
> if it could do so (which it can't because the SVC stack is trashed).
> However, I believe this *could* be fixed if the Wimp had a state flag that
> was flipped which affected the behaviour of the Wimp's exit handler. The
> Watchdog could then store away a copy of the SVC stack, do a context and
> environment switch, set the flag, call OS_Exit, and then when the Wimp's
> exit handler is called, it would switch the environment and context back
> again, close down the dying task, restore the SVC stack and exit the
> callback.

I don't follow.  Currently when the watchdog kills the current task, the
task's Exit handler gets called by the Wimp doing an OS_Exit.  That seems
to work and I think that's a good approach.  Why can't we do the same
for killing a task which happens not to be the current task at the moment
Alt-Break is pressed ? The only thing what needs to be done as extra is to
first make that task the current one by calling 'pageintask' (and
dealing with sprite redirection + pdriver is probably not relevant in this

> Would this be useful enough behaviour to warrant the effort to implement it
> though? We've managed without since RISC OS 3.5, but it's potentially a Bad
> Thing that we've lacked it, because it can cause all sorts of resource
> leaks. (Also, I assume UnixLib's atexit functions are called from its exit
> handler - that's certainly the case with the Shared C Library - because
> you'd probably want these to be called on an Alt-Break too.)

Yes, UnixLib atexit functions are called too.

> It could be argued that this would be a retrograde step, because if an
> application has a rogue exit handler which refuses to terminate while the
> task is not the active task, then you would no longer be able to kill it
> after such a change.

But if we're considering the case of a task with rogue exit handler you
won't be able to kill that task when it happens to be the current task.
And that's the situation today since RISC OS 3.5.  So why are we seeing
this as an argument for killing the not-current task ?

> So it's probably a good idea for an Alt-Break during
> the exit handler to revert to the old behaviour by reinstalling the Wimp's
> exit handler and trying again.

I'm not sure if I fully understand your suggestion.  Is it something like
the first Alt-Break for a task gets its Exit handler called, and a 2nd
Alt-Break the Wimp Exit handler gets called and the task gets killed
straightaway ?

John Tytgat, in his comfy chair at home                                 BASS
John.Tytgat at aaug.net                             ARM powered, RISC OS driven

More information about the gcc mailing list