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);
    }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/