From ab7f057ce9df4e905b12cebc1e587b9a7f200418 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 17 Sep 2010 11:19:17 -0400 Subject: loader: Remove a silly layer of reference counting libdl will refcount objects for us just fine, thanks. Reviewed-by: Alan Coopersmith Reviewed-by: Julien Cristau Signed-off-by: Adam Jackson --- 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 22d8273d3..89218312a 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 4bb571e69..edea91133 100644 --- a/hw/xfree86/loader/loader.h +++ b/hw/xfree86/loader/loader.h @@ -57,21 +57,6 @@ #include #include -/* 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 a7925ecee..0b67c5f7a 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 e41e0c8d9..6e6522774 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); } -- cgit v1.2.3