In the tkgecko extension I wrote some code to keep a per thread list of
active widgets, and to detach them from mozilla's gecko when a thread exits.
BUT the problem is that the handler I have registered with
Tcl_CreateExitHandler() is called before the handlers registered with
Tcl_CreateThreadExitHandler().
Is this expected?
How can I arrange exit handlers per thread and then an exit handler when
all threads have finished?
George
Another work around for the work around: A global variable holds the
number of created widgets. The tcl exit handler sets a global flag that
the application is shutting down. The thread exit handlers are invoked,
each freeing the thread widgets, decrementing the global variable of
active widgets. When the count reaches 0 and the application is shutting
down, then mozilla & gtk are also shut down after the last widget has
been destroyed.
George
Earlier this year there has been a silent, but needed "exit
reform" (see bug 2001201). The idea is that thread-exit is a tricky
tool, essentially because in the general case no guarantee of timely
exit can be given. The only exception is the thread calling [exit],
whose state is safe by definition. So the decision was made to let
[exit] no longer do a full finalization, and just do the minimum, like
flushing the calling thread's channels.
This may sound like extreme therapy; actually it is a compromise doing
its best to satisfy a wide range of needs.
Now nothing prevents you from causing your threads to exit gracefully
_before_ [exit]_time, eg by instructing them to do so through
messages.
-Alex
Yes, but this is impossible in my case. Its a widget extension: I am not
the thread creator/owner, so I cannot make any assumptions about what
threads exist and how they will be terminated...
George
Can you describe the situation more precisely ? What exactly would
cause those threads to be "terminated", rather than a more explicit
(and gentle) [thread::exit] or [delete .wid] ?
-Alex
The situation is as follows: the extension embeds mozilla in tk widgets.
Under linux, mozilla needs GTK to run (this is a requirement). So, there
are two event loops to exist in the same application, so GTK has its own
thread. During shutdown, somebody has to terminate the GTK event loop.
If GTK is stopped while widgets are alive, you get either a crash or a
lock due to unhandled messages among threads. So, during exit I need to
shutdown all widgets (at least detach the mozilla engine from them) and
then shutdown GTK...
I have found a way to do it, but it is not so straight-forward as one
would think (and assuming that the tcl exit handler is the last thing
called before tcl exits...)
Yes, but again, the spirit of that exit reform is that exit() is the
very best way of exiting (hint, hint, Cameron ;-). IOW, instead of
painstakingly unwinding whatever has been wound in the process's life
by calling the destructor of every particle in the universe, just rely
on the OS to zap the whole context in a split millisecond without
deadlocks nor leaks (kernel objects like fds are well tracked and
never leak).
So, what will go wrong in your case if you don't register any exit
handler and the process just calls exit() ? I assume the GTK loop's
thread will die with the rest of the process, and that whatever IPC
channels used to talk to mozilla will get their side nuked, and the
other side reporting EOF in Mozilla. Am I missing something ?
-Alex