Skip to content
Browse files

Merge remote-tracking branch 'origin/gh363/dlclose'

  • Loading branch information...
2 parents 3e9ca81 + 6050332 commit 1c0e26caf98805aa8e81989758cb1252f8cb2f42 @leto leto committed Mar 29, 2012
Showing with 73 additions and 4 deletions.
  1. +73 −4 src/platform/generic/dl.c
View
77 src/platform/generic/dl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010, Parrot Foundation.
+ * Copyright (C) 2004-2012, Parrot Foundation.
*/
/*
@@ -23,11 +23,70 @@ Parrot functions which wrap around standard library functions for handling dynam
#include "parrot/parrot.h"
#ifdef PARROT_HAS_HEADER_DLFCN
+# include <stddef.h>
+# include <stdlib.h>
# include <dlfcn.h>
#endif
#define PARROT_DLOPEN_FLAGS RTLD_LAZY
+#ifdef PARROT_HAS_HEADER_DLFCN
+
+struct handle_entry {
+ void *handle;
+ struct handle_entry *next;
+};
+
+struct handle_entry *handle_list = NULL;
+
+static void
+push_handle_entry(void *handle)
+{
+ struct handle_entry *e;
+
+ e = (handle_entry *) malloc(sizeof(struct handle_entry));
+ if (!e) { return; }
+ e->handle = handle;
+ e->next = handle_list;
+ handle_list = e;
+}
+
+static void *
+find_handle_entry(void *handle)
+{
+ struct handle_entry *e;
+
+ for(e = handle_list; e; e = e->next) {
+ if (e->handle == handle)
+ return handle;
+ }
+ return NULL;
+}
+
+static void
+remove_handle_entry(void *handle)
+{
+ struct handle_entry *cur, *prev, *p;
+
+ if (handle_list) {
+ if (handle_list->handle == handle) {
+ p = handle_list;
+ handle_list = p->next;
+ free(p);
+ } else {
+ for (cur = handle_list; cur; prev = cur, cur = cur->next) {
+ if (cur->handle == handle) {
+ prev->next = cur->next;
+ free(cur);
+ }
+ }
+ }
+ }
+}
+#endif /* PARROT_HAS_HEADER_DLFCN */
+
+
+
/* HEADERIZER HFILE: none */
/*
@@ -46,8 +105,12 @@ void *
Parrot_dlopen(const char *filename, Parrot_dlopen_flags flags)
{
#ifdef PARROT_HAS_HEADER_DLFCN
- return dlopen(filename, PARROT_DLOPEN_FLAGS
- | ((flags & Parrot_dlopen_global_FLAG) ? RTLD_GLOBAL : 0));
+ void *h;
+
+ h = dlopen(filename, PARROT_DLOPEN_FLAGS |
+ ((flags & Parrot_dlopen_global_FLAG) ? RTLD_GLOBAL : 0));
+ push_handle_entry(h);
+ return h;
#else
return 0;
#endif
@@ -114,7 +177,13 @@ int
Parrot_dlclose(void *handle)
{
#ifdef PARROT_HAS_HEADER_DLFCN
- return dlclose(handle);
+ int rv;
+
+ if (find_handle_entry(handle)) {
+ remove_handle_entry(handle);
+ rv = dlclose(handle);
+ return rv;
+ }
#else
return -1;
#endif

0 comments on commit 1c0e26c

Please sign in to comment.
Something went wrong with that request. Please try again.