Re: [AD] aRts "pure virtual function call" |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
> If I code a small C program with only artsc to reproduce the problem then
> I can get these warnings too (I think I mentioned them before), but when
> using allegro, I don't get to see them (don't know where they go...).
I don't get the warnings if arts_free() is not called either.
So I think we can simply not call arts_close_stream() and arts_free() if we
are being called by the exit mechanism. Patch attached.
Does it suit your needs?
--
Eric Botcazou
diff -up /home/eric/cvs/allegro/include/allegro/internal/aintern.h allegro/include/allegro/internal/aintern.h
--- /home/eric/cvs/allegro/include/allegro/internal/aintern.h Sat Feb 14 16:28:12 2004
+++ allegro/include/allegro/internal/aintern.h Sat Feb 14 16:42:00 2004
@@ -36,6 +36,10 @@
AL_VAR(int, _allegro_count);
+/* flag to know whether we are being called by the exit mechanism */
+AL_VAR(int, _allegro_in_exit);
+
+
/* flag to decide whether to disable the screensaver */
enum {
NEVER_DISABLED,
diff -urp /home/eric/cvs/allegro/src/allegro.c allegro/src/allegro.c
--- /home/eric/cvs/allegro/src/allegro.c Fri Jan 9 07:38:30 2004
+++ allegro/src/allegro.c Sat Feb 14 19:12:31 2004
@@ -45,6 +45,10 @@ int *allegro_errno = NULL;
int _allegro_count = 0;
+/* flag to know whether we are being called by the exit mechanism */
+int _allegro_in_exit = FALSE;
+
+
/* flag to decide whether to disable the screensaver */
int _screensaver_policy = FULLSCREEN_DISABLED;
@@ -269,6 +273,18 @@ void _remove_exit_func(void (*func)(void
+/* allegro_exit_stub:
+ * Stub function registered by the library via atexit.
+ */
+static void allegro_exit_stub(void)
+{
+ _allegro_in_exit = TRUE;
+
+ allegro_exit();
+}
+
+
+
/* install_allegro:
* Initialises the Allegro library, activating the system driver.
*/
@@ -364,7 +380,7 @@ int install_allegro(int system_id, int *
/* install shutdown handler */
if (_allegro_count == 0) {
if (atexit_ptr)
- atexit_ptr(allegro_exit);
+ atexit_ptr(allegro_exit_stub);
}
_allegro_count++;
diff -urp /home/eric/cvs/allegro/src/linux/svgalib.c allegro/src/linux/svgalib.c
--- /home/eric/cvs/allegro/src/linux/svgalib.c Thu Sep 18 11:04:54 2003
+++ allegro/src/linux/svgalib.c Sat Feb 14 19:29:22 2004
@@ -94,8 +94,7 @@ static int last_line;
#ifdef ALLEGRO_MODULE
-/* If this is non-zero, this module won't be unloaded. */
-int _module_dont_unload_me_dirty_hack = 0;
+int _module_has_registered_via_atexit = 0;
#endif
@@ -200,7 +199,7 @@ static int safe_vga_setmode(int num, int
/* A side-effect of vga_setmode() is that it will register an
* atexit handler. See umodules.c for this problem.
*/
- _module_dont_unload_me_dirty_hack = 1;
+ _module_has_registered_via_atexit = 1;
#endif
tcsetattr(__al_linux_console_fd, TCSANOW, &termio);
diff -urp /home/eric/cvs/allegro/src/unix/arts.c allegro/src/unix/arts.c
--- /home/eric/cvs/allegro/src/unix/arts.c Sat Jul 6 13:32:52 2002
+++ allegro/src/unix/arts.c Sat Feb 14 20:50:30 2004
@@ -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 @@ static int _al_arts_init(int input, int
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 @@ static void _al_arts_exit(int input)
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();
+ }
}
diff -urp /home/eric/cvs/allegro/src/unix/umodules.c allegro/src/unix/umodules.c
--- /home/eric/cvs/allegro/src/unix/umodules.c Wed Apr 9 11:31:40 2003
+++ allegro/src/unix/umodules.c Sat Feb 14 20:53:03 2004
@@ -17,6 +17,7 @@
#include "allegro.h"
+#include "allegro/internal/aintern.h"
#ifdef ALLEGRO_WITH_MODULES
@@ -156,8 +157,9 @@ void _unix_unload_modules(void)
{
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 @@ void _unix_unload_modules(void)
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);
}