Author: chromatic
Date: Wed Oct  3 15:08:54 2007
New Revision: 21801

Modified:
   trunk/src/dynext.c
   trunk/src/pmc/parrotlibrary.pmc

Log:
[dynext] Free shared libraries when the ParrotLibrary PMCs wrapping them get
collected.

Also don't poke around in the guts of ParrotLibrary; use the shiny new
set_pointer vtable entry to store the shared library handle.

Modified: trunk/src/dynext.c
==============================================================================
--- trunk/src/dynext.c  (original)
+++ trunk/src/dynext.c  Wed Oct  3 15:08:54 2007
@@ -334,8 +334,8 @@
     Parrot_block_DOD(interp);
     /* get load_func */
     if (lib_name != NULL) {
-        STRING * const load_func_name = Parrot_sprintf_c(interp, 
"Parrot_lib_%Ss_load",
-                                          lib_name);
+        STRING * const load_func_name = Parrot_sprintf_c(interp,
+                                        "Parrot_lib_%Ss_load", lib_name);
         char * const cload_func_name = string_to_cstring(interp, 
load_func_name);
         STRING *init_func_name;
 
@@ -358,20 +358,18 @@
     }
 
     lib_pmc = Parrot_init_lib(interp, load_func, init_func);
+    VTABLE_set_pointer(interp, lib_pmc, handle);
 
-    PMC_data(lib_pmc) = handle;
     if (!load_func)
         type = const_string(interp, "NCI");
     else {
         /* we could set a private flag in the PMC header too
          * but currently only ops files have struct_val set
          */
-        type = const_string(interp,
-                               PMC_struct_val(lib_pmc) ? "Ops" : "PMC");
+        type = const_string(interp, PMC_struct_val(lib_pmc) ? "Ops" : "PMC");
     }
-    /*
-     * remember lib_pmc in iglobals
-     */
+
+    /* remember lib_pmc in iglobals */
     store_lib_pmc(interp, lib_pmc, wo_ext, type, lib_name);
     /* UNLOCK */
     Parrot_unblock_DOD(interp);
@@ -463,8 +461,8 @@
 PMC *
 Parrot_load_lib(PARROT_INTERP, NULLOK(STRING *lib), SHIM(PMC *initializer))
 {
-    void * handle;
-    PMC *lib_pmc;
+    void   *handle;
+    PMC    *lib_pmc;
     STRING *path;
     STRING *lib_name, *wo_ext, *ext;    /* library stem without path
                                          * or extension.  */
@@ -474,19 +472,21 @@
      *
      * LOCK()
      */
-    if (lib == NULL) {
+    if (lib) {
+        lib_name = parrot_split_path_ext(interp, lib, &wo_ext, &ext);
+    }
+    else {
         wo_ext   = string_from_literal(interp, "");
         lib_name = NULL;
         ext      = NULL;
     }
-    else {
-        lib_name = parrot_split_path_ext(interp, lib, &wo_ext, &ext);
-    }
+
     lib_pmc = is_loaded(interp, wo_ext);
     if (!PMC_IS_NULL(lib_pmc)) {
         /* UNLOCK() */
         return lib_pmc;
     }
+
     path = get_path(interp, lib, &handle, wo_ext, ext);
     if (!path || !handle) {
         /*
@@ -496,8 +496,7 @@
         return pmc_new(interp, enum_class_Undef);
     }
 
-    lib_pmc = run_init_lib(interp, handle, lib_name, wo_ext);
-    return lib_pmc;
+    return run_init_lib(interp, handle, lib_name, wo_ext);
 }
 
 /*

Modified: trunk/src/pmc/parrotlibrary.pmc
==============================================================================
--- trunk/src/pmc/parrotlibrary.pmc     (original)
+++ trunk/src/pmc/parrotlibrary.pmc     Wed Oct  3 15:08:54 2007
@@ -47,11 +47,27 @@
 */
 
     void init() {
+        PObj_active_destroy_SET(SELF);
         PMC_struct_val(SELF) = NULL;
     }
 
 /*
 
+=item C<void destroy()>
+
+Destroys the library, closing the shared library.
+
+=cut
+
+*/
+
+    void destroy() {
+        if (PMC_data(SELF))
+            Parrot_dlclose(PMC_data(SELF));
+    }
+
+/*
+
 =item C<void morph(INTVAL type)>
 
 Morphs to C<type>.
@@ -116,6 +132,19 @@
         return VTABLE_get_string(INTERP, prop);
     }
 
+/*
+
+=item C<void set_pointer(void *handle)>
+
+Set the pointer to the shared library handle.
+
+=cut
+
+*/
+
+    void set_pointer(void *handle) {
+        PMC_data(SELF) = handle;
+    }
 }
 
 /*

Reply via email to