Closed
Description
I can't always guarantee that users are going to properly use a library (calling init methods, cleanup methods, etc.).
Occasionally things die horribly and you want to provide stronger guarantees about when things fail.
Is there a way to hook up to an exit signal of sorts to execute code when a program exits regardless of the exit mechanism? Something like Python atexit?
Activity
liigo commentedon Jan 21, 2014
Drop?
2014/1/21 Bryan Murphy notifications@github.com
by Liigo, http://blog.csdn.net/liigo/
Google+ https://plus.google.com/105597640837742873343/
bmurphy1976 commentedon Jan 21, 2014
By Drop do you mean the Drop destructor trait? I've used that to set a "static mut Option<>" variable, however the Drop destructor does not run on exit and I was told on irc that this was likely going to be disallowed in the future.
thestinger commentedon Jan 21, 2014
An
atexit
handler only runs when you can a specificexit
function tied to it. A user could always just run out of memory (causing anabort
) or callabort
themselves.pnkfelix commentedon Jan 21, 2014
@bmurphy1976 have you considered designing your library so that one must pass around a
Context
struct in order to use its core methods? Then the type system would force the user to call your library'sinit
function (since that would be how they would get their hands on a context), and you would implement theDrop
trait on the context struct.Alternatively, if you do not want to thread a context argument through your program logic, an alternative is to make the entry point of your library take a proc that it invokes for the rest of the program. In other words, a single instance of continuation-passing style (CPS), but without CPS-transforming the whole program. Then that initialization routine has a local variable at the base of the stack, and you put the impl of
Drop
on that, so that when the program either returns or fails, your destructor runs.Basically I'm just describing a couple ways that you could revise your library design so that you would be able to use the
Drop
trait.(As for the feature request itself, I'm ambivalent about whether to add this particular feature. If people find it useful then I will not object, but I'm not yet convinced this is dire need for it in the runtime.)
bmurphy1976 commentedon Jan 21, 2014
Thanks. I've considered the context approach and I'm not a big fan of the CPS approach (for this particular problem anyway).
At the moment I'm coming from the perspective of designing a wrapper for a very common C library. Ultimately, I would want to balance "ensuring things are done right" with "the simplest/easiest to use API possible."
Asking users to pass around a context everywhere, manually clean up on exit, or use CPS passing style are all "busywork" to me. Sometimes, our users just want to call a URL and fetch a json file. All this init, teardown, cleanup, nonsense is ceremony.
Anyway, something to consider.
dcbishop commentedon Mar 13, 2014
I'm considering this problem myself due to SDL requiring initialization of it's subsystems and needing to have sdl_Quit called at exit.
For my current approach I'm considering making a static. mutex locked reference count of objects using SDL and putting the code in the objects drop function that only runs when it's the last reference. Does require a little bit of unsafe code but other than that should work.
My main concern is whether or not SDL can be reinitialized after SDL_Quit is called (There are also functions like SDL_VideoInit and SDL_VideoQuit which could give more fine grained control over everything).
@pnkfelix
I was considering the context approach, but nothing would prevent someone creating 2 contexts and destroying one of them causing the global deinitilization stuff to fire while leaving a context that expects everything to still be initialized.
eddyb commentedon Oct 6, 2014
@dcbishop You could use an
Once
(or anAtomicBool
) in astatic mut
to ensure only one context can exist at any given time.After #17718 is fully implemented, such code could be safe, AFAIK.
As for the proposed feature, it seems similar to global destructors (which would require an RFC, but many devs are opposed to it, so I doubt it has much of a chance).
However, our TLD (
task_local
data) allows destructors (that run on task death, but not aborts), so that may be used instead (where thread locality is applicable/helpful).steveklabnik commentedon Jan 23, 2015
I'm pulling a massive triage effort to get us ready for 1.0. As part of this, I'm moving stuff that's wishlist-like to the RFCs repo, as that's where major new things should get discussed/prioritized.
This issue has been moved to the RFCs repo: rust-lang/rfcs#712
Update Zabbix Rust library
Auto merge of rust-lang#11744 - matthri:get-first-deque-fix, r=Jarcho