From: Eric B. <ebo...@us...> - 2004-02-28 16:26:38
|
Update of /cvsroot/alleg/allegro/src/unix In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5697/src/unix Modified Files: arts.c umodules.c Log Message: Julien Cugniere and I fixed the crash on exit with the aRts driver. Index: arts.c =================================================================== RCS file: /cvsroot/alleg/allegro/src/unix/arts.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- arts.c 6 Jul 2002 11:32:52 -0000 1.1 +++ arts.c 28 Feb 2004 16:17:03 -0000 1.2 @@ -25,6 +25,10 @@ #include <artsc.h> +#ifdef ALLEGRO_MODULE +int _module_has_registered_via_atexit = 0; +#endif + static int _al_arts_bits, _al_arts_rate, _al_arts_stereo; #define _al_arts_signed (TRUE) @@ -178,6 +182,14 @@ return -1; } +#ifdef ALLEGRO_MODULE + /* A side-effect of arts_init() is that it will register an + * atexit handler. See umodules.c for this problem. + * ??? this seems to be the case only for recent versions. + */ + _module_has_registered_via_atexit = 1; +#endif + /* Make a copy of the global sound settings. */ _al_arts_bits = (_sound_bits == 8) ? 8 : 16; _al_arts_stereo = (_sound_stereo) ? 1 : 0; @@ -274,10 +286,16 @@ free(_al_arts_bufdata); _al_arts_bufdata = NULL; - arts_close_stream(_al_arts_stream); - _al_arts_stream = NULL; + /* Do not call the cleanup routines if we are being + * called by the exit mechanism because they may have + * already been called by it (see above). + */ + if (!_allegro_in_exit) { + arts_close_stream(_al_arts_stream); + _al_arts_stream = NULL; - arts_free(); + arts_free(); + } } Index: umodules.c =================================================================== RCS file: /cvsroot/alleg/allegro/src/unix/umodules.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- umodules.c 9 Apr 2003 07:22:04 -0000 1.10 +++ umodules.c 28 Feb 2004 16:17:03 -0000 1.11 @@ -17,6 +17,7 @@ #include "allegro.h" +#include "allegro/internal/aintern.h" #ifdef ALLEGRO_WITH_MODULES @@ -156,8 +157,9 @@ { MODULE *m, *next; void (*shutdown)(void); - int *dont_unload; - + int *sym; + int has_registered; + for (m = module_list; m; m = next) { next = m->next; @@ -165,16 +167,17 @@ if (shutdown) shutdown(); - /* Dirty hack: If the loaded module registers its own cleanup - * function with atexit, we mustn't unload the module, otherwise - * the atexit machinery will end up referring to a function that - * won't exist by the end of the program. This problem only - * affects SVGAlib currently. + /* If a module has registered something via atexit, we can unload it + * only if we are being called by the exit mechanism because, in this + * case, we know that the registered routine has already been called; + * otherwise the atexit machinery would end up referring to a function + * that would not exist by the end of the program. */ - dont_unload = dlsym(m->handle, "_module_dont_unload_me_dirty_hack"); + sym = dlsym(m->handle, "_module_has_registered_via_atexit"); + has_registered = (sym ? *sym : 0); - if ((!dont_unload) || !(*dont_unload)) - dlclose(m->handle); + if (!has_registered || _allegro_in_exit) + dlclose(m->handle); free(m); } |