Index: libroar/roardl.c
===================================================================
--- libroar/roardl.c	(revision 5313)
+++ libroar/roardl.c	(revision 5317)
@@ -41,4 +41,7 @@
 
 struct roar_dl_lhandle {
+ size_t refc; // currently unused.
+ int flags;
+ char * libname; // only used for ROAR_DL_FLAG_STATIC.
  struct roar_dl_librarypara * para;
  struct roar_dl_libraryinst * lib;
@@ -47,4 +50,5 @@
   void *  global_data;
   void *  global_data_state;
+  struct roar_notify_core * notifycore;
  } context;
 #if defined(ROAR_HAVE_LIBDL)
@@ -118,11 +122,16 @@
  para->refc--;
 
- if ( para->refc == 0 ) {
-  if ( para->args_store != NULL ) {
-   roar_mm_free(para->args_store);
-   roar_mm_free(para->argv);
-  }
-  roar_mm_free(para);
- }
+ if ( para->refc )
+  return 0;
+
+ if ( para->notifycore != NULL )
+  roar_notify_core_unref(para->notifycore);
+
+ if ( para->args_store != NULL ) {
+  roar_mm_free(para->args_store);
+  roar_mm_free(para->argv);
+ }
+
+ roar_mm_free(para);
 
  return 0;
@@ -165,10 +174,17 @@
 #if defined(ROAR_HAVE_LIBDL)
 static void * _roardl2ldl (struct roar_dl_lhandle * lhandle) {
- if ( lhandle == ROAR_DL_HANDLE_DEFAULT )
+ ROAR_DBG("_roardl2ldl(lhandle=%p) = ?", lhandle);
+
+ if ( lhandle == ROAR_DL_HANDLE_DEFAULT ) {
+  ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_DEFAULT);
   return RTLD_DEFAULT;
-
- if ( lhandle == ROAR_DL_HANDLE_NEXT )
+ }
+
+ if ( lhandle == ROAR_DL_HANDLE_NEXT ) {
+  ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_NEXT);
   return RTLD_NEXT;
-
+ }
+
+ ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)(lhandle->handle));
  return lhandle->handle;
 }
@@ -178,12 +194,15 @@
                                       int ra_init, struct roar_dl_librarypara * para) {
  struct roar_dl_lhandle * ret = NULL;
+#if defined(ROAR_HAVE_LIBDL)
+#ifdef RTLD_DEEPBIND
+ int libdl_flags = RTLD_NOW|RTLD_DEEPBIND;
+#else
+ int libdl_flags = RTLD_NOW;
+#endif
+#endif
  int err;
 
- // early errors just return.
-
- if ( flags != ROAR_DL_FLAG_DEFAUTS ) {
-  roar_err_set(ROAR_ERROR_NOTSUP);
-  return NULL;
- }
+ if ( flags == ROAR_DL_FLAG_DEFAULTS )
+  flags = ROAR_DL_FLAG_NONE;
 
  if ( (ret = roar_mm_malloc(sizeof(struct roar_dl_lhandle))) == NULL )
@@ -194,22 +213,27 @@
  roar_err_initstore(&(ret->context.error_state));
 
-#if defined(ROAR_HAVE_LIBDL)
- flags  = RTLD_NOW;
-
-#ifdef RTLD_DEEPBIND
- flags |= RTLD_DEEPBIND;
-#endif
-
- ret->handle = dlopen(filename, flags);
-
- if ( ret->handle == NULL ) {
+ ret->flags = flags;
+
+ if ( flags & ROAR_DL_FLAG_STATIC ) {
+  if ( filename == NULL ) {
+   ret->libname = NULL;
+  } else {
+   ret->libname = roar_mm_strdup(filename);
+  }
+ } else {
+#if defined(ROAR_HAVE_LIBDL)
+  ret->handle = dlopen(filename, libdl_flags);
+
+  if ( ret->handle == NULL ) {
+   ROAR_DBG("roar_dl_open(filename='%s', flags=%i, ra_init=%i, para=%p): Can not load library: %s", filename, flags, ra_init, para, roar_dl_errstr(ret));
+   roar_mm_free(ret);
+   return NULL;
+  }
+#else
   roar_mm_free(ret);
-  return NULL;
- }
-#else
- roar_mm_free(ret);
- roar_err_set(ROAR_ERROR_NOSYS);
- return NULL;
-#endif
+  roar_err_set(ROAR_ERROR_NOSYS);
+  return NULL;
+#endif
+ }
 
  ret->para = para;
@@ -220,5 +244,6 @@
    ROAR_WARN("roar_dl_open(filename='%s', flags=%i, ra_init=%i, para=%p): Can not init RA lib: %s", filename, flags, ra_init, para, roar_error2str(err));
 #if defined(ROAR_HAVE_LIBDL)
-   dlclose(ret->handle);
+   if ( ret->handle != NULL )
+    dlclose(ret->handle);
 #endif
    roar_mm_free(ret);
@@ -242,9 +267,16 @@
  }
 
- if ( lhandle->lib != NULL && lhandle->lib->unload != NULL )
+ if ( lhandle->lib != NULL && lhandle->lib->unload != NULL ) {
+  roar_dl_context_restore(lhandle);
   lhandle->lib->unload(lhandle->para, lhandle->lib);
-
-#if defined(ROAR_HAVE_LIBDL)
- ret = dlclose(_roardl2ldl(lhandle));
+  roar_dl_context_store(lhandle);
+ }
+
+#if defined(ROAR_HAVE_LIBDL)
+ if ( lhandle->handle == NULL ) {
+  ret = 0;
+ } else {
+  ret = dlclose(_roardl2ldl(lhandle));
+ }
 #else
  ret = -1;
@@ -257,4 +289,7 @@
   roar_dl_para_unref(lhandle->para);
 
+ if ( lhandle->libname != NULL )
+  roar_mm_free(lhandle->libname);
+
  roar_mm_free(lhandle);
 
@@ -268,8 +303,11 @@
  (void)type;
 
+ ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i): errno=%s, dlerror()='%s'", lhandle, sym, type, ret, strerror(errno), dlerror());
  ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = %p", lhandle, sym, type, ret);
 
  return ret;
 #else
+ ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = NULL // errno=NOSYS", lhandle, sym, type, ret);
+ roar_err_set(ROAR_ERROR_NOSYS);
  return NULL;
 #endif
@@ -283,4 +321,5 @@
  struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
  struct roar_dl_libraryinst * lib;
+ struct roar_dl_lhandle     * getsymhandle = lhandle;
  void * global_data_state = NULL;
  int i;
@@ -290,6 +329,12 @@
    return -1;
  } else {
+  if ( prefix == NULL )
+   prefix = lhandle->libname;
+
   if ( para == NULL )
    para = lhandle->para;
+
+  if ( lhandle->flags & ROAR_DL_FLAG_STATIC )
+   getsymhandle = ROAR_DL_HANDLE_DEFAULT;
  }
 
@@ -303,6 +348,8 @@
  ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): name='%s'", lhandle, prefix, name);
 
- if ( (func = roar_dl_getsym(lhandle, name, -1)) == NULL )
-  return -1;
+ if ( (func = roar_dl_getsym(getsymhandle, name, -1)) == NULL ) {
+  ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s') = -1", lhandle, prefix);
+  return -1;
+ }
 
  ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): func=%p", lhandle, prefix, func);
@@ -416,5 +463,8 @@
  struct roar_error_state error_state;
 
+ ROAR_DBG("roar_dl_context_restore(lhandle=%p) = ?", lhandle);
+
  if ( (void*)lhandle < (void*)128 ) {
+  ROAR_DBG("roar_dl_context_restore(lhandle=%p) = -1 // errno=NOTSUP", lhandle);
   roar_err_set(ROAR_ERROR_NOTSUP);
   return -1;
@@ -426,8 +476,14 @@
 
  if ( lhandle->lib->global_data_pointer != NULL ) {
+  ROAR_DBG("roar_dl_context_restore(lhandle=%p): gptr(%p): %p -> %p", lhandle,
+           lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data);
   lhandle->context.global_data_state = *(lhandle->lib->global_data_pointer);
   *(lhandle->lib->global_data_pointer) = lhandle->context.global_data;
  }
 
+ if ( lhandle->para->notifycore != NULL )
+  lhandle->context.notifycore = roar_notify_core_swap_global(lhandle->para->notifycore);
+
+ ROAR_DBG("roar_dl_context_restore(lhandle=%p) = 0", lhandle);
  return 0;
 }
@@ -436,10 +492,21 @@
  struct roar_error_state error_state;
 
+ ROAR_DBG("roar_dl_context_store(lhandle=%p) = ?", lhandle);
+
  if ( (void*)lhandle < (void*)128 ) {
+  ROAR_DBG("roar_dl_context_store(lhandle=%p) = -1 // errno=NOTSUP", lhandle);
   roar_err_set(ROAR_ERROR_NOTSUP);
   return -1;
  }
 
+ if ( lhandle->para->notifycore != NULL ) {
+  roar_notify_core_unref(roar_notify_core_swap_global(lhandle->context.notifycore));
+  roar_notify_core_unref(lhandle->context.notifycore);
+  lhandle->context.notifycore = NULL;
+ }
+
  if ( lhandle->lib->global_data_pointer != NULL ) {
+  ROAR_DBG("roar_dl_context_store(lhandle=%p): gptr(%p): %p -> %p", lhandle,
+           lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data_state);
   *(lhandle->lib->global_data_pointer) = lhandle->context.global_data_state;
  }
@@ -449,6 +516,41 @@
  lhandle->context.error_state = error_state;
 
+ ROAR_DBG("roar_dl_context_store(lhandle=%p) = 0", lhandle);
  return 0;
 }
 
+int                      roar_dl_appsched_trigger(struct roar_dl_lhandle * lhandle, enum roar_dl_appsched_trigger trigger) {
+ int ret;
+
+ if ( (void*)lhandle < (void*)128 ) {
+  roar_err_set(ROAR_ERROR_NOTSUP);
+  return -1;
+ }
+
+ if ( lhandle->lib->appsched == NULL ) {
+  roar_err_set(ROAR_ERROR_NOENT);
+  return -1;
+ }
+
+ switch (trigger) {
+#define _trig(lname,uname) \
+  case ROAR_DL_APPSCHED_ ## uname :             \
+    if ( lhandle->lib->appsched->lname == NULL ) {   \
+     roar_err_set(ROAR_ERROR_NOENT);            \
+     return -1;                                 \
+    }                                           \
+    roar_dl_context_restore(lhandle);           \
+    ret = lhandle->lib->appsched->lname(lhandle->para); \
+    roar_dl_context_store(lhandle);             \
+    return ret;                                 \
+   break;
+  _trig(init, INIT);
+  _trig(free, FREE);
+  _trig(update, UPDATE);
+ }
+
+ roar_err_set(ROAR_ERROR_BADRQC);
+ return -1;
+}
+
 //ll
