libdl will refcount objects for us just fine, thanks.

Signed-off-by: Adam Jackson <[email protected]>
---
 hw/xfree86/loader/loader.c      |  167 +++------------------------------------
 hw/xfree86/loader/loader.h      |   18 +----
 hw/xfree86/loader/loaderProcs.h |    5 +-
 hw/xfree86/loader/loadmod.c     |   78 +++++++++----------
 4 files changed, 51 insertions(+), 217 deletions(-)

diff --git a/hw/xfree86/loader/loader.c b/hw/xfree86/loader/loader.c
index 22d8273..8921831 100644
--- a/hw/xfree86/loader/loader.c
+++ b/hw/xfree86/loader/loader.c
@@ -96,41 +96,6 @@
 
 extern void *xorg_symbols[];
 
-#define MAX_HANDLE 256
-static int refCount[MAX_HANDLE];
-
-/* Prototypes for static functions. */
-static loaderPtr listHead = NULL;
-
-static loaderPtr
-_LoaderListPush(void)
-{
-    loaderPtr item = calloc(1, sizeof(struct _loader));
-
-    item->next = listHead;
-    listHead = item;
-
-    return item;
-}
-
-static loaderPtr
-_LoaderListPop(int handle)
-{
-    loaderPtr item = listHead;
-    loaderPtr *bptr = &listHead;       /* pointer to previous node */
-
-    while (item) {
-       if (item->handle == handle) {
-           *bptr = item->next; /* remove this from the list */
-           return item;
-       }
-       bptr = &(item->next);
-       item = item->next;
-    }
-
-    return 0;
-}
-
 void
 LoaderInit(void)
 {
@@ -171,130 +136,41 @@ LoaderInit(void)
 #endif
 }
 
-static void *
-do_dlopen(loaderPtr modrec, int flags)
-{
-    void *dlfile;
-    int dlopen_flags;
-
-    if (flags & LD_FLAG_GLOBAL)
-       dlopen_flags = DLOPEN_LAZY | DLOPEN_GLOBAL;
-    else
-       dlopen_flags = DLOPEN_LAZY;
-
-    dlfile = dlopen(modrec->name, dlopen_flags);
-
-    if (dlfile == NULL) {
-       ErrorF("dlopen: %s\n", dlerror());
-       return NULL;
-    }
-
-    return dlfile;
-}
-
 /* Public Interface to the loader. */
 
-int
-LoaderOpen(const char *module, int *errmaj, int *errmin, int *wasLoaded,
-           int flags)
+void *
+LoaderOpen(const char *module, int *errmaj, int *errmin)
 {
-    loaderPtr tmp;
-    int new_handle;
+    void *ret;
 
 #if defined(DEBUG)
     ErrorF("LoaderOpen(%s)\n", module);
 #endif
 
-    /* Is the module already loaded? */
-    tmp = listHead;
-    while (tmp) {
-#ifdef DEBUGLIST
-        ErrorF("strcmp(%x(%s),{%x} %x(%s))\n", module, module,
-               &(tmp->name), tmp->name, tmp->name);
-#endif
-        if (!strcmp(module, tmp->name)) {
-            refCount[tmp->handle]++;
-            if (wasLoaded)
-                *wasLoaded = 1;
-            xf86MsgVerb(X_INFO, 2, "Reloading %s\n", module);
-            return tmp->handle;
-        }
-        tmp = tmp->next;
-    }
-
-    /*
-     * OK, it's a new one. Add it.
-     */
     xf86Msg(X_INFO, "Loading %s\n", module);
-    if (wasLoaded)
-       *wasLoaded = 0;
-
-    /*
-     * Find a free handle.
-     */
-    new_handle = 1;
-    while (new_handle < MAX_HANDLE && refCount[new_handle])
-       new_handle++;
-
-    if (new_handle == MAX_HANDLE) {
-       xf86Msg(X_ERROR, "Out of loader space\n");      /* XXX */
-       if (errmaj)
-           *errmaj = LDR_NOSPACE;
-       if (errmin)
-           *errmin = LDR_NOSPACE;
-       return -1;
-    }
 
-    refCount[new_handle] = 1;
-
-    tmp = _LoaderListPush();
-    tmp->name = strdup(module);
-    tmp->handle = new_handle;
-
-    if ((tmp->private = do_dlopen(tmp, flags)) == NULL) {
-       xf86Msg(X_ERROR, "Failed to load %s\n", module);
-       _LoaderListPop(new_handle);
-       refCount[new_handle] = 0;
+    if (!(ret = dlopen(module, DLOPEN_LAZY | DLOPEN_GLOBAL))) {
+       xf86Msg(X_ERROR, "Failed to load %s: %s\n", module, dlerror());
        if (errmaj)
            *errmaj = LDR_NOLOAD;
        if (errmin)
            *errmin = LDR_NOLOAD;
-       return -1;
+       return NULL;
     }
 
-    return new_handle;
-}
-
-int
-LoaderHandleOpen(int handle)
-{
-    if (handle < 0 || handle >= MAX_HANDLE)
-       return -1;
-
-    if (!refCount[handle])
-       return -1;
-
-    refCount[handle]++;
-    return handle;
+    return ret;
 }
 
 void *
 LoaderSymbol(const char *name)
 {
     static void *global_scope = NULL;
-    loaderPtr l;
     void *p;
 
     p = dlsym(RTLD_DEFAULT, name);
     if (p != NULL)
        return p;
 
-    for (l = listHead; l != NULL; l = l->next) {
-        p = dlsym(l->private, name);
-       if (p)
-           return p;
-    }
-
     if (!global_scope)
        global_scope = dlopen(NULL, DLOPEN_LAZY | DLOPEN_GLOBAL);
 
@@ -304,32 +180,11 @@ LoaderSymbol(const char *name)
     return NULL;
 }
 
-int
-LoaderUnload(int handle)
+void
+LoaderUnload(const char *name, void *handle)
 {
-    loaderRec fakeHead;
-    loaderPtr tmp = &fakeHead;
-
-    if (handle < 0 || handle >= MAX_HANDLE)
-       return -1;
-
-    /*
-     * check the reference count, only free it if it goes to zero
-     */
-    if (--refCount[handle])
-       return 0;
-    /*
-     * find the loaderRecs associated with this handle.
-     */
-
-    while ((tmp = _LoaderListPop(handle)) != NULL) {
-       xf86Msg(X_INFO, "Unloading %s\n", tmp->name);
-       dlclose(tmp->private);
-       free(tmp->name);
-       free(tmp);
-    }
-
-    return 0;
+    xf86Msg(X_INFO, "Unloading %s\n", name);
+    dlclose(handle);
 }
 
 unsigned long LoaderOptions = 0;
diff --git a/hw/xfree86/loader/loader.h b/hw/xfree86/loader/loader.h
index 4bb571e..edea911 100644
--- a/hw/xfree86/loader/loader.h
+++ b/hw/xfree86/loader/loader.h
@@ -57,21 +57,6 @@
 #include <X11/Xfuncproto.h>
 #include <X11/Xmd.h>
 
-/* LoadModule proc flags; LD_FLAG_GLOBAL adds symbols to global
- * namespace, default is to keep symbols local to module. */
-#define LD_FLAG_GLOBAL 1
-
-typedef struct _loader *loaderPtr;
-
-/* Each module loaded has a loaderRec */
-typedef struct _loader {
-    int handle;                        /* Unique id used to remove symbols from
-                                * this module when it is unloaded */
-    char *name;
-    void *private;             /* format specific data */
-    loaderPtr next;
-} loaderRec;
-
 /* Compiled-in version information */
 typedef struct {
     int xf86Version;
@@ -86,7 +71,6 @@ extern const ModuleVersions LoaderVersionInfo;
 extern unsigned long LoaderOptions;
 
 /* Internal Functions */
-int LoaderOpen(const char *, int *, int *, int *, int);
-int LoaderHandleOpen(int);
+void * LoaderOpen(const char *, int *, int *);
 
 #endif /* _LOADER_H */
diff --git a/hw/xfree86/loader/loaderProcs.h b/hw/xfree86/loader/loaderProcs.h
index a7925ec..0b67c5f 100644
--- a/hw/xfree86/loader/loaderProcs.h
+++ b/hw/xfree86/loader/loaderProcs.h
@@ -60,7 +60,8 @@ typedef struct module_desc {
     struct module_desc *sib;
     struct module_desc *parent;
     char *name;
-    int handle;
+    char *path;
+    void *handle;
     ModuleSetupProc SetupProc;
     ModuleTearDownProc TearDownProc;
     void *TearDownData;                /* returned from SetupProc */
@@ -81,7 +82,7 @@ void UnloadDriver(ModuleDescPtr);
 void LoaderSetPath(const char *path);
 void LoaderSortExtensions(void);
 
-int LoaderUnload(int);
+void LoaderUnload(const char *, void *);
 unsigned long LoaderGetModuleVersion(ModuleDescPtr mod);
 
 void LoaderResetOptions(void);
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index e41e0c8..6e65227 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -83,8 +83,7 @@ static char *LoaderGetCanonicalName(const char *, PatternPtr);
 static void RemoveChild(ModuleDescPtr);
 static ModuleDescPtr doLoadModule(const char *, const char *, const char **,
                                  const char **, pointer,
-                                 const XF86ModReqInfo *, int *, int *,
-                                 int flags);
+                                 const XF86ModReqInfo *, int *, int *);
 
 const ModuleVersions LoaderVersionInfo = {
     XORG_VERSION_CURRENT,
@@ -765,7 +764,7 @@ LoadSubModule(pointer _parent, const char *module,
     }
 
     submod = doLoadModule(module, NULL, subdirlist, patternlist, options,
-                         modreq, errmaj, errmin, LD_FLAG_GLOBAL);
+                         modreq, errmaj, errmin);
     if (submod && submod != (ModuleDescPtr) 1) {
        parent->child = AddSibling(parent->child, submod);
        submod->parent = parent;
@@ -776,18 +775,10 @@ LoadSubModule(pointer _parent, const char *module,
 static ModuleDescPtr
 NewModuleDesc(const char *name)
 {
-    ModuleDescPtr mdp = malloc(sizeof(ModuleDesc));
+    ModuleDescPtr mdp = calloc(1, sizeof(ModuleDesc));
 
-    if (mdp) {
-       mdp->child = NULL;
-       mdp->sib = NULL;
-       mdp->parent = NULL;
+    if (mdp)
        mdp->name = xstrdup(name);
-       mdp->handle = -1;
-       mdp->SetupProc = NULL;
-       mdp->TearDownProc = NULL;
-       mdp->TearDownData = NULL;
-    }
 
     return mdp;
 }
@@ -796,6 +787,7 @@ ModuleDescPtr
 DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
 {
     ModuleDescPtr ret;
+    int errmaj, errmin;
 
     if (!mod)
        return NULL;
@@ -804,10 +796,11 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
     if (ret == NULL)
        return NULL;
 
-    if (LoaderHandleOpen(mod->handle) == -1)
-       return NULL;
+    if (!(ret->handle = LoaderOpen(mod->path, &errmaj, &errmin))) {
+        free(ret);
+        return NULL;
+    }
 
-    ret->handle = mod->handle;
     ret->SetupProc = mod->SetupProc;
     ret->TearDownProc = mod->TearDownProc;
     ret->TearDownData = NULL;
@@ -815,6 +808,7 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
     ret->sib = DuplicateModule(mod->sib, parent);
     ret->parent = parent;
     ret->VersionInfo = mod->VersionInfo;
+    ret->path = strdup(mod->path);
 
     return ret;
 }
@@ -830,7 +824,7 @@ static ModuleDescPtr
 doLoadModule(const char *module, const char *path, const char **subdirlist,
             const char **patternlist, pointer options,
             const XF86ModReqInfo * modreq,
-            int *errmaj, int *errmin, int flags)
+            int *errmaj, int *errmin)
 {
     XF86ModuleData *initdata = NULL;
     char **pathlist = NULL;
@@ -839,7 +833,6 @@ doLoadModule(const char *module, const char *path, const 
char **subdirlist,
     char **path_elem = NULL;
     char *p = NULL;
     ModuleDescPtr ret = NULL;
-    int wasLoaded = 0;
     PatternPtr patterns = NULL;
     int noncanonical = 0;
     char *m = NULL;
@@ -926,9 +919,10 @@ doLoadModule(const char *module, const char *path, const 
char **subdirlist,
            *errmin = 0;
        goto LoadModule_fail;
     }
-    ret->handle = LoaderOpen(found, errmaj, errmin, &wasLoaded, flags);
+    ret->handle = LoaderOpen(found, errmaj, errmin);
     if (ret->handle < 0)
        goto LoadModule_fail;
+    ret->path = strdup(found);
 
     /* drop any explicit suffix from the module name */
     p = strchr(name, '.');
@@ -959,26 +953,24 @@ doLoadModule(const char *module, const char *path, const 
char **subdirlist,
        setup = initdata->setup;
        teardown = initdata->teardown;
 
-       if (!wasLoaded) {
-           if (vers) {
-               if (!CheckVersion(module, vers, modreq)) {
-                   if (errmaj)
-                       *errmaj = LDR_MISMATCH;
-                   if (errmin)
-                       *errmin = 0;
-                   goto LoadModule_fail;
-               }
-           } else {
-               xf86Msg(X_ERROR,
-                       "LoadModule: Module %s does not supply"
-                       " version information\n", module);
-               if (errmaj)
-                   *errmaj = LDR_INVALID;
-               if (errmin)
-                   *errmin = 0;
-               goto LoadModule_fail;
-           }
-       }
+        if (vers) {
+            if (!CheckVersion(module, vers, modreq)) {
+                if (errmaj)
+                    *errmaj = LDR_MISMATCH;
+                if (errmin)
+                    *errmin = 0;
+                goto LoadModule_fail;
+            }
+        } else {
+            xf86Msg(X_ERROR,
+                    "LoadModule: Module %s does not supply"
+                    " version information\n", module);
+            if (errmaj)
+                *errmaj = LDR_INVALID;
+            if (errmin)
+                *errmin = 0;
+            goto LoadModule_fail;
+        }
        if (setup)
            ret->SetupProc = setup;
        if (teardown)
@@ -1066,7 +1058,7 @@ LoadModule(const char *module, const char *path, const 
char **subdirlist,
           const XF86ModReqInfo * modreq, int *errmaj, int *errmin)
 {
   return doLoadModule(module, path, subdirlist, patternlist, options,
-                     modreq, errmaj, errmin, LD_FLAG_GLOBAL);
+                     modreq, errmaj, errmin);
 }
 
 void
@@ -1088,12 +1080,13 @@ UnloadModuleOrDriver(ModuleDescPtr mod)
 
     if ((mod->TearDownProc) && (mod->TearDownData))
        mod->TearDownProc(mod->TearDownData);
-    LoaderUnload(mod->handle);
+    LoaderUnload(mod->name, mod->handle);
 
     if (mod->child)
        UnloadModuleOrDriver(mod->child);
     if (mod->sib)
        UnloadModuleOrDriver(mod->sib);
+    free(mod->path);
     free(mod->name);
     free(mod);
 }
@@ -1110,13 +1103,14 @@ UnloadSubModule(pointer _mod)
 
     if ((mod->TearDownProc) && (mod->TearDownData))
        mod->TearDownProc(mod->TearDownData);
-    LoaderUnload(mod->handle);
+    LoaderUnload(mod->name, mod->handle);
 
     RemoveChild(mod);
 
     if (mod->child)
        UnloadModuleOrDriver(mod->child);
 
+    free(mod->path);
     free(mod->name);
     free(mod);
 }
-- 
1.7.2.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to