Re: bonobo-activation; freeing base services ...



Maciej Stachowiak <mjs noisehavoc org> writes: 
> They run in the opposite of the order in which they were installed. If
> each library installs its atexit() handlers when initialized, and
> initializes all libraries it may need when shutting down before
> installing the handler, this will be the right order.

I'm worried more about apps tossing these in. You can rapidly have
circular dependencies in what the atexit() handlers are doing.

> >  - they run when the app is in an undefined state, because when people
> >    call exit() they aren't thinking "oh some wacky reentrancy will go
> >    on now", and because of the undefined order issue

exit() means "exit the app" not "run largish function with side effects"
  
> >  - they force apps to use _exit() when they do a fork/exec (this FAQ
> >    is why we ripped atexit() usage out of GTK, well, this and the fact
> >    that atexit() is an awful idea)
> 
> You mean in case of an error on exec()? There are still other reasons
> its more correct to call _exit() instead of exit().

If you have unflushed stdio buffers. Often you don't.

> >  - they are not particularly guaranteed to run (abnormal exits don't
> >    call them), so always indicate an unreliable bad hack
> 
> The gnome-vfs shutdown function, which I hope to turn into an atexit()
> handler for GNOME 2.0, cancels any outstanding threads. If you don't
> call it you can leak threads and the program does not exit
> properly. However, being killed by a signal will already kill all
> threads.
> 
> So in this case I think an atexit() handler is exactly the right
> approach.

I don't know the thread semantics; if you have a case where in all
cases where atexit() functions are called, you would get leaks, and in
all other termination cases the OS cleans up for you, then I would
agree atexit() makes sense. But the atexit() function should only mop
up those threads and nothing else.

> >  - there's a fixed limit to the number of them you can have on some
> >    platforms, Nautilus already overruns it, reported to GLib
> >    bugtracker recently, so it isn't portable
> 
> g_atexit()

Not a solution. It just calls system atexit() when it exists. (Having
g_atexit() register a single system atexit() which runs through a list
of handlers isn't a solution because it doesn't interoperate with
system atexit().)

See:
 http://bugzilla.gnome.org/show_bug.cgi?id=62806

> >  - there is no way to remove an atexit() function once it's installed
> 
> But you usually don't need to, or if you do, it wouldn't be hard to
> write an atexit wrapper that registers a single real atexit function
> and 

There are plenty of reasons you might want to keep a library from
doing goofy stuff in atexit(). Let's say you have a bunch of legacy
code involved in your app, for example.
 
> Shutdown functions that are necessary for correct operation of the
> program are even worse,

This is just a pointless comparison. If you need the shutdown function
for correct operation, you are _fucked_. Redesign the program. End of
story.

The gnome-vfs case you described is the only exception I've seen,
because the OS automatically fixes things on abnormal termination but
not normal termination.

> because programers will forget to call them
> before calling exit(), leading to obscure bugs.

Not obscure at all. The belief that bugs caused by failure to shut
down are obscure is _wrong_ and hoses GNOME 1.4. We do not deploy to
laboratory environments.

> If the library needs
> to do shutdown processing, I think it should use an atexit() handler
> rather than an explicit shutdown function.

If the library needs to do shut down processing, it is broken as all
hell, again with the possible exception of your gnome-vfs case.

> You seem to have strongly held opinions about the issue but I don't
> find them very convincing given that they are low on specifics and I
> have never run into actual problems with shutdown functions myself.

The problems I'm most concerned about are:
 - it was a very common FAQ when GTK had one
 - in general, libs should not be poking in global 
   C library stuff like signal handlers and atexit() functions,
   because these things should be in total control of apps
 - leaking processes, locks, and other resources

> Personally, I would rather have neither atexit handlers nor shutdown
> functions, but given the choice, I prefer the atexit handler.

OK, let's drop the atexit() thing - what I'm most worried about is
that we are potentially relying on either shutdown or atexit() to
clean stuff up, and failing to handle abnormal termination. If we are,
then dammit, fix the libraries. I don't care if you have to break API.
This is a must-fix bug for 2.0.

If we are not, then the shutdown function is purely optional, right?
So why have a lib do the questionable thing of installing an atexit()
function, for something that's totally optional?

Havoc





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]