]> git.ipfire.org Git - thirdparty/strongswan.git/blobdiff - src/libstrongswan/plugins/plugin_loader.c
plugin-loader: Add facility to register plugin constructors
[thirdparty/strongswan.git] / src / libstrongswan / plugins / plugin_loader.c
index e4698fac0900029963734a80b12d109f85fdb4f9..e78762b2c4f149df374840cf9fcff06463df4044 100644 (file)
@@ -40,6 +40,13 @@ typedef struct registered_feature_t registered_feature_t;
 typedef struct provided_feature_t provided_feature_t;
 typedef struct plugin_entry_t plugin_entry_t;
 
+#ifdef STATIC_PLUGIN_CONSTRUCTORS
+/**
+ * Statically registered constructors
+ */
+static hashtable_t *plugin_constructors = NULL;
+#endif
+
 /**
  * private data of plugin_loader
  */
@@ -298,6 +305,46 @@ static plugin_t *static_features_create(const char *name,
        return &this->public;
 }
 
+#ifdef STATIC_PLUGIN_CONSTRUCTORS
+/*
+ * Described in header.
+ */
+void plugin_constructor_register(char *name, void *constructor)
+{
+       bool old = FALSE;
+
+       if (lib && lib->leak_detective)
+       {
+               old = lib->leak_detective->set_state(lib->leak_detective, FALSE);
+       }
+
+       if (!plugin_constructors)
+       {
+               chunk_hash_seed();
+               plugin_constructors = hashtable_create(hashtable_hash_str,
+                                                                                          hashtable_equals_str, 32);
+       }
+       if (constructor)
+       {
+               plugin_constructors->put(plugin_constructors, name, constructor);
+       }
+       else
+       {
+               plugin_constructors->remove(plugin_constructors, name);
+               if (!plugin_constructors->get_count(plugin_constructors))
+               {
+                       plugin_constructors->destroy(plugin_constructors);
+                       plugin_constructors = NULL;
+               }
+       }
+
+       if (lib && lib->leak_detective)
+       {
+               lib->leak_detective->set_state(lib->leak_detective, old);
+       }
+}
+#endif
+
 /**
  * create a plugin
  * returns: NOT_FOUND, if the constructor was not found
@@ -309,7 +356,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
 {
        char create[128];
        plugin_t *plugin;
-       plugin_constructor_t constructor;
+       plugin_constructor_t constructor = NULL;
 
        if (snprintf(create, sizeof(create), "%s_plugin_create",
                                 name) >= sizeof(create))
@@ -317,8 +364,17 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
                return FAILED;
        }
        translate(create, "-", "_");
-       constructor = dlsym(handle, create);
-       if (constructor == NULL)
+#ifdef STATIC_PLUGIN_CONSTRUCTORS
+       if (plugin_constructors)
+       {
+               constructor = plugin_constructors->get(plugin_constructors, name);
+       }
+       if (!constructor)
+#endif
+       {
+               constructor = dlsym(handle, create);
+       }
+       if (!constructor)
        {
                return NOT_FOUND;
        }