[D-runtime] A mechanism to kill threads

Fawzi Mohamed fawzi at gmx.ch
Fri May 18 05:46:27 PDT 2012


Hi Alex,

I still think that you don't really understand the constraint that your
code has to follow to be able to call kill safely.

I had said that you basically can use only signal safe functions after
calling kill.

Sean and Brad pointed out already some possible pitfalls: holding
resources (locks,...) allocating gc memory,... but to avoid
constraining the subsequent program to be able to use only signal
safe functions, the thread must *not* be executing any signal unsafe
function.

A signal unsafe function might be using resources within the kernel,
and those resource will also never be released.
Even if you are sure that your thread is not using any resource that
you care about later, unless you restrict yourself to signal safe
functions you cannot know what resources might be used by the kernel.

As a real life example aquiring or even releaseing! a lock is non
signal safe, and indeed on OSX to optimize the usage of "fat" locks,
the os tries to spinlock and uses a fat lock from a common pool only
when required.
When releasing the lock the fat lock might go back to the pool.
Now the pool obviously needs to be guarded, and it uses a spinlock for
it.
Now imagine you suspend or kill a thread while the spinlock to the
common pool of fat locks is being held in the kernel...
Any subsequent lock/unlock on *any* lock that requires access to the
common pool will block.
OSX is perfectly standard compliant in doing that optimization, because
indeed those functions are not signal safe.
This is not theoretical, I actually had this probelm, and is now fixed
in druntime (at least my fixes to the tango runtime were included in
druntime).

A consequence of this is that in general it is *not* ok to kill a
thread that is idle and holds a lock (likely what you thought of your
thread in a know state).

As said the only thread that could be safely killed is a thread that has
no resources you care abount and might remain uncollected, and executes
no signal unsafe functions.
Are there suche cases? yes indeed a purely computational thread that
allocates nothing might well fall into that category.
I am not sure your "managed code" thread does.
Normally probably you had better to fork and have a separate *process*
to kill, or accept that you have cooperative killing wich might take
some time (depending how often the thread checks if it should stop.

ciao
Fawzi


More information about the D-runtime mailing list