bug-libtool
[Top][All Lists]
Advanced

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

Re: ltdl bugs


From: Ralf Wildenhues
Subject: Re: ltdl bugs
Date: Mon, 4 Apr 2005 14:16:07 +0200
User-agent: Mutt/1.4.1i

Jeff,

* Ralf Wildenhues wrote on Sun, Apr 03, 2005 at 05:33:12PM CEST:
> 
> I'll try to rephrase:  You may actually do what you intend in
> lt_dlexit(), because that is (like MPI_Finalize) final in the sense,
> that after as many lt_dlexit's as lt_dlinit's we may completely shut
> down our stuff and free every data we own.
> 
> You may _not_ do this in lt_dlclose(), however, because the user may
> issue another lt_dlopen() of the very same module (which may be NULL, or
> "foo.la" made resident), which in fact is already open.

So, here's a different try at a patch, against branch-1-5,
which does what I think is correct: free only in lt_dlexit,
not in lt_dlclose.

Could you try it?

Regards,
Ralf

        Free all remaining handles and our associated storage, even for
        resident modules, at lt_dlexit time (cosmetic change to please
        memory checkers).

        * libltdl/ltdl.c (lt_dlclose): Make wrapper, rename to..
        (do_dlclose): Accept new parameter force_free to enable mere
        deallocation and delisting, but not unloading of resident
        modules.  Do not error out in force_free case.
        (lt_dlexit): Call do_dlclose with force_free, for all modules,
        not just non-resident ones.

Index: libltdl/ltdl.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v
retrieving revision 1.174.2.13
diff -u -r1.174.2.13 ltdl.c
--- libltdl/ltdl.c      1 Feb 2005 13:57:11 -0000       1.174.2.13
+++ libltdl/ltdl.c      4 Apr 2005 12:14:41 -0000
@@ -2145,6 +2145,7 @@
                                                 lt_ptr data2));
 
 
+static int     do_dlclose            LT_PARAMS((lt_dlhandle handle, int 
force_free));
 static int     canonicalize_path     LT_PARAMS((const char *path,
                                                 char **pcanonical));
 static int     argzize_path          LT_PARAMS((const char *path,
@@ -2306,11 +2307,6 @@
     {
       int      level;
 
-      while (handles && LT_DLIS_RESIDENT (handles))
-       {
-         handles = handles->next;
-       }
-
       /* close all modules */
       for (level = 1; handles; ++level)
        {
@@ -2323,9 +2319,9 @@
              cur = cur->next;
              if (!LT_DLIS_RESIDENT (tmp))
                saw_nonresident = 1;
-             if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
+             if (tmp->info.ref_count <= level)
                {
-                 if (lt_dlclose (tmp))
+                 if (do_dlclose (tmp, 1))
                    {
                      ++errors;
                    }
@@ -3768,9 +3764,10 @@
   return is_done;
 }
 
-int
-lt_dlclose (handle)
+static int
+do_dlclose (handle, force_free)
      lt_dlhandle handle;
+     int force_free;
 {
   lt_dlhandle cur, last;
   int errors = 0;
@@ -3798,10 +3795,10 @@
      correctly incase the user decides to reset the residency flag
      later (even though the API makes no provision for that at the
      moment).  */
-  if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
+  if (handle->info.ref_count <= 0
+      && (!LT_DLIS_RESIDENT (cur) || force_free))
     {
-      lt_user_data data = handle->loader->dlloader_data;
-
+      /* Remove this handle from the list of handles */
       if (handle != handles)
        {
          last->next = handle->next;
@@ -3811,9 +3808,14 @@
          handles = handle->next;
        }
 
-      errors += handle->loader->module_close (data, handle->module);
-      errors += unload_deplibs(handle);
+      /* If the module is not resident, then unload, etc. */
+      if (!LT_DLIS_RESIDENT (handle))
+       {
+         lt_user_data data = handle->loader->dlloader_data;
+         errors += handle->loader->module_close (data, handle->module);
+         errors += unload_deplibs(handle);
 
+       }
       /* It is up to the callers to free the data itself.  */
       LT_DLFREE (handle->caller_data);
 
@@ -3824,7 +3826,7 @@
       goto done;
     }
 
-  if (LT_DLIS_RESIDENT (handle))
+  if (LT_DLIS_RESIDENT (handle) && !force_free)
     {
       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
       ++errors;
@@ -3836,6 +3838,13 @@
   return errors;
 }
 
+int
+lt_dlclose (handle)
+     lt_dlhandle handle;
+{
+  return do_dlclose (handle, 0);
+}
+
 lt_ptr
 lt_dlsym (handle, symbol)
      lt_dlhandle handle;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]