(util concurrent)
which uses thread-terminate!
to finish tasks forcibly. As my understanding, as long as you free all resources held by the thread, terminating thread isn't that badly wrong. Well, if this was the conclusion, then I wouldn't write this. It actually works fine on POSIX environments I usually test, including Cygwin, however not working properly on Windows.Windows has the API which terminates a thread, called
TerminateThread
. I, however, don't use this because of the following reasons:- It may not release all resources
- There is no way to handle after termination
If you don't use
TerminateThread
, then there's, afaik, not many choice to do it. The way I've chosen is using CONTEXT
. The basic process is the followings:- Suspend the target thread
- Check if it's active
- Get thread context
- Set program counter to the function calls
RaiseException
- Resume the thread
_try
and _except
, so the thrown exception will be caught.Until here, there seems nothing wrong and works fine. Well no. This works most of the case however at some point you may get a context which contains no call frame of thread caller function. I think this means either thread is almost terminating or it's finished but still active. Then you'd get access violation error.
Now, what can I do? I think I'll try to compare stack pointer. Luckly, Boehm GC has base stack pointer on each thread. So if I can get this and compare with the thread context stack pointer, I might be able to detect if the thread is already finished (or at least returned from the thread function of Sagittarius) or not.
If you know better way, please let me know.
2 comments:
Very interesting. I wonder if it's safe when the thread you suspend is in middle of unwinding
exception handlers.
I think suspension itself is safe (though, may cause dead lock according to MSDN). The rest of the operation is not, unfortunately. I'm still getting occasional unexpected error (and crash).
Unwinding exception/invoking continuation captured outside of the thread can be unsafe but as long as in the Scheme world, I'd throw the responsibility to users. (terminating a thread is not a safe operation anyway.)
Post a Comment