At Tue, 19 Apr 2016 10:39:57 -0400, Deren Dohoda wrote:
> I have a thread that can only be shut down during certain points:

In general, you can't implement that safety in Racket, in much the same
way you can't implement that in Unix or Windows process.

As long as the thread might get shut down through
`custodian-shutdown-all` (like a Unix process might get terminated with
SIGKILL), there's nothing the thread can do about it --- at least not
safely.

There's also no way to register arbitrary code to run in the event that
a thread gets killed (in the same way that there's no API for
registering code to run if your process is killed in Unix). If there
were such a feature, then a thread could just put all of its work in
that callback, and there would be no way to reliably terminate a
thread's computation.


> [...] it does
> some writing operations on a port and this write must finish under normal
> circumstances. I worry that if this thread is managed by a custodian and
> custodian-shutdown-all is called that the thread may die in the middle of a
> write operation on a port. Is this where I would use a will?

Wills are unlikely to help. It depends on your situation, but in a
typical case where a thread might get shut down through a custodian, a
thread that's acting as a will executor can also get shut down.

There is an unsafe function, `register-finalizer`, which lets you
register a will that has an executor thread that can never get killed
(unless the whole Racket process is killed). That's probably not what
you want, but I mention it for completeness.


Using a particular pattern, you can use to make something "kill safe"
in the following sense: if multiple clients are using an object, and if
one of them is killed while manipulating the object, a later use by a
different client can pick up where the previous thread left off to
restore the object to usability. See the paper "Kill-Safe
Synchronization Abstractions" for more on that pattern.

Along those lines, if there's some thread X that won't get killed
relative to another set of threads, you can have X run the action or
have it start a new thread with X's custodian to ensure that the action
will complete. At least, it will complete relative to the threads that
might get killed. Whether you can arrange for such an X depends on how
much your program is in control from the start.


If you have something where you need an action to complete atomically
--- even if no future client touches the relevant object and you don't
have access to a thread that will definitely continue --- then it's not
possible to implement that safely. In the grand scheme of things, it's
not possible to implement at all, at least for an arbitrary action; the
Racket process might get killed, the power might go out, and so on.

If termination external to Racket run-time system is not a concern,
then you can implement atomic actions unsafely. See
`ffi/unsafe/atomic`. Please be aware that atomicity really is unsafe;
you need to know the full affect of any function called in atomic mode
to make sure that it cannot lead to deadlock or similar problems.
Generally, that's how actions like shutting down a custodian can be
implemented atomically relative to the rest of the Racket runtime
system; those primitives are implemented (carefully!) to run in atomic
mode.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to