Add hook in dynamically loaded modules for unloading actions.
authorTaylor R Campbell <campbell@mumble.net>
Thu, 7 Oct 2010 15:26:15 +0000 (15:26 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Thu, 7 Oct 2010 15:26:15 +0000 (15:26 +0000)
Dynamically loaded modules can't use reload cleanups, because they
may be unloaded by pruxdld's reload cleanup before their reload
cleanups get to run, causing DISK-RESTORE to attempt to execute
unmapped code.  Instead, pruxdld will now call dload_finalize_file
if it is defined in the file.

Use this mechanism in prx11.  Fixes DISK-RESTORE after launching
and exiting Edwin.  (Does not fix DISK-RESTORE of an image that was
saved while Edwin was running.  That is much harder.)

src/microcode/pruxdld.c
src/microcode/prx11.c
src/microcode/x11base.c

index 13f35f8469f1d40302924960cdaa7b3a6ebb1db7..35c719a4c9c16ce2300dfce9e0ae987442f13df3 100644 (file)
@@ -145,9 +145,21 @@ dld_load (const char * path)
   return (handle);
 }
 
+static void
+dld_finalize (void * handle)
+{
+  void * address = (dlsym (handle, "dld_finalize_file"));
+  if (address != 0)
+    {
+      void (*finalize) (void) = address;
+      (*finalize) ();
+    }
+}
+
 static void
 dld_unload (void * handle)
 {
+  dld_finalize (handle);
   if ((dlclose (handle)) != 0)
     {
       SCHEME_OBJECT v = (allocate_marked_vector (TC_VECTOR, 3, 1));
@@ -177,7 +189,11 @@ dld_unload_all (void)
       void ** scan = loaded_handles;
       void ** end = (scan + n_loaded_handles);
       while (scan < end)
-       dlclose (*scan++);
+       {
+         void * handle = (*scan++);
+         dld_finalize (handle);
+         dlclose (handle);
+       }
 
       OS_free (loaded_handles);
       loaded_handles_size = 0;
index 2f4068d3ef526644cb69295cb2ed01741066471e..61c44e391145cb3fb9aeba472779bbfa547d28f7 100644 (file)
@@ -35,7 +35,6 @@ extern void dload_initialize_x11term (void);
 const char *
 dload_initialize_file (void)
 {
-
   dload_initialize_x11base ();
   dload_initialize_x11color ();
   dload_initialize_x11graph ();
@@ -43,4 +42,12 @@ dload_initialize_file (void)
   return ("#prx11");
 }
 
+extern void dload_finalize_x11base (void);
+
+void
+dload_finalize_file (void)
+{
+  dload_finalize_x11base ();
+}
+
 #endif /* defined (COMPILE_AS_MODULE) */
index 8a5ca33100b9c71275016728d634dfb014e4691f..9ef4bbe26e3e91b1ea718a963b5e87d9eba04136 100644 (file)
@@ -1571,7 +1571,9 @@ initialize_once (void)
   (x_error_info.code) = 0;
   XSetErrorHandler (x_error_handler);
   XSetIOErrorHandler (x_io_error_handler);
+#ifndef COMPILE_AS_MODULE
   add_reload_cleanup (x_close_all_displays);
+#endif
   initialization_done = 1;
 }
 
@@ -2815,4 +2817,11 @@ dload_initialize_x11base (void)
   declare_primitive ("X-WINDOW-Y-SIZE", Prim_x_window_y_size, 1, 1, 0);
 }
 
+void
+dload_finalize_x11base (void)
+{
+  if (initialization_done)
+    x_close_all_displays ();
+}
+
 #endif /* defined (COMPILE_AS_MODULE) */