summaryrefslogtreecommitdiffstats
path: root/byterun/unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'byterun/unix.c')
-rw-r--r--byterun/unix.c65
1 files changed, 59 insertions, 6 deletions
diff --git a/byterun/unix.c b/byterun/unix.c
index d6927c05b..217c86124 100644
--- a/byterun/unix.c
+++ b/byterun/unix.c
@@ -170,16 +170,57 @@ char * caml_search_dll_in_path(struct ext_table * path, char * name)
static char *dlerror_string = "No error";
+/* Need to emulate dlopen behaviour by caching open libraries */
+typedef struct bundle_entry {
+ struct bundle_entry *next;
+ char *name;
+ void *handle;
+ int count;
+} entry_t;
+
+entry_t bundle_list = {NULL,NULL,NULL,0};
+
+entry_t *caml_lookup_bundle(const char *name)
+{
+ entry_t *current = bundle_list.next, *last = &bundle_list;
+
+ while (current !=NULL) {
+ if (!strcmp(name,current->name))
+ return current;
+ last = current;
+ current = current->next;
+ }
+ current = (entry_t*) malloc(sizeof(entry_t)+strlen(name)+1);
+ current->name = (char*)(current+1);
+ strcpy(current->name, name);
+ current->count = 0;
+ current->next = NULL;
+ last->next = current;
+ return current;
+}
+
void * caml_dlopen(char * libname)
{
NSObjectFileImage image;
- NSObjectFileImageReturnCode retCode =
- NSCreateObjectFileImageFromFile(libname, &image);
+ entry_t *bentry = caml_lookup_bundle(libname);
+ NSObjectFileImageReturnCode retCode;
+ void *result = NULL;
+
+ if (bentry->count > 0)
+ return bentry->handle;
+
+ retCode = NSCreateObjectFileImageFromFile(libname, &image);
switch (retCode) {
case NSObjectFileImageSuccess:
dlerror_string = NULL;
- return (void*)NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW
- | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+ result = (void*)NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW
+ | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+ if (result != NULL) {
+ bentry->count++;
+ bentry->handle = result;
+ }
+ else NSDestroyObjectFileImage(image);
+ break;
case NSObjectFileImageAccess:
dlerror_string = "cannot access this bundle"; break;
case NSObjectFileImageArch:
@@ -190,13 +231,25 @@ void * caml_dlopen(char * libname)
default:
dlerror_string = "could not read object file"; break;
}
- return NULL;
+ return result;
}
void caml_dlclose(void * handle)
{
+ entry_t *current = bundle_list.next;
+ int close = 1;
+
dlerror_string = NULL;
- NSUnLinkModule((NSModule)handle, NSUNLINKMODULE_OPTION_NONE);
+ while (current != NULL) {
+ if (current->handle == handle) {
+ current->count--;
+ close = (current->count == 0);
+ break;
+ }
+ current = current->next;
+ }
+ if (close)
+ NSUnLinkModule((NSModule)handle, NSUNLINKMODULE_OPTION_NONE);
}
void * caml_dlsym(void * handle, char * name)