[vlc-commits] modules: clean up vlc_dl(open|close|sym) wrappers

Rémi Denis-Courmont git at videolan.org
Thu Mar 1 21:25:08 CET 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Mar  1 20:33:24 2018 +0200| [77b641f79bc05478044b119143e94a5445d72903] | committer: Rémi Denis-Courmont

modules: clean up vlc_dl(open|close|sym) wrappers

Rename functions and match the usual prototypes, which works basically
everywhere (except for naming differences). Also fix and deduplicate
Doxygen.

Functions are not exported for now (no portable use case as of yet).

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=77b641f79bc05478044b119143e94a5445d72903
---

 src/modules/bank.c    | 36 ++++++++++++++++++------------
 src/modules/modules.h | 50 +++++++++++++++++++++++++++++++++++------
 src/os2/plugin.c      | 61 +++++++++++++-------------------------------------
 src/posix/plugin.c    | 62 +++++++++++++++------------------------------------
 src/win32/plugin.c    | 27 ++++++++--------------
 5 files changed, 108 insertions(+), 128 deletions(-)

diff --git a/src/modules/bank.c b/src/modules/bank.c
index 693e514a29..3adaae8bd6 100644
--- a/src/modules/bank.c
+++ b/src/modules/bank.c
@@ -207,14 +207,18 @@ static const char vlc_entry_name[] = "vlc_entry" MODULE_SUFFIX;
 static vlc_plugin_t *module_InitDynamic(vlc_object_t *obj, const char *path,
                                         bool fast)
 {
-    module_handle_t handle;
-
-    if (module_Load (obj, path, &handle, fast))
+    void *handle = vlc_dlopen(path, fast);
+    if (handle == NULL)
+    {
+        char *errmsg = vlc_dlerror();
+        msg_Err(obj, "cannot load plug-in %s: %s", path,
+                errmsg ? errmsg : "unknown error");
+        free(errmsg);
         return NULL;
+    }
 
     /* Try to resolve the symbol */
-    vlc_plugin_cb entry =
-        (vlc_plugin_cb) module_Lookup(handle, vlc_entry_name);
+    vlc_plugin_cb entry = vlc_dlsym(handle, vlc_entry_name);
     if (entry == NULL)
     {
         msg_Warn (obj, "cannot find plug-in entry point in %s", path);
@@ -235,7 +239,7 @@ static vlc_plugin_t *module_InitDynamic(vlc_object_t *obj, const char *path,
     atomic_init(&plugin->loaded, true);
     return plugin;
 error:
-    module_Unload( handle );
+    vlc_dlclose(handle);
     return NULL;
 }
 
@@ -500,19 +504,23 @@ int module_Map(vlc_object_t *obj, vlc_plugin_t *plugin)
         return 0; /* fast path: already loaded */
 
     /* Try to load the plug-in (without locks, so read-only) */
-    module_handle_t handle;
-
     assert(plugin->abspath != NULL);
 
-    if (module_Load(obj, plugin->abspath, &handle, false))
+    void *handle = vlc_dlopen(plugin->abspath, false);
+    if (handle == NULL)
+    {
+        char *errmsg = vlc_dlerror();
+        msg_Err(obj, "cannot load plug-in %s: %s", plugin->abspath,
+                errmsg ? errmsg : "unknown error");
+        free(errmsg);
         return -1;
+    }
 
-    vlc_plugin_cb entry =
-        (vlc_plugin_cb) module_Lookup(handle, vlc_entry_name);
+    vlc_plugin_cb entry = vlc_dlsym(handle, vlc_entry_name);
     if (entry == NULL)
     {
         msg_Err(obj, "cannot find plug-in entry point in %s", plugin->abspath);
-        module_Unload(handle);
+        vlc_dlclose(handle);
         return -1;
     }
 
@@ -529,7 +537,7 @@ int module_Map(vlc_object_t *obj, vlc_plugin_t *plugin)
         atomic_store_explicit(&plugin->loaded, true, memory_order_release);
     }
     else /* Another thread won the race to load the plugin */
-        module_Unload(handle);
+        vlc_dlclose(handle);
     vlc_mutex_unlock(&lock);
 
     return 0;
@@ -550,7 +558,7 @@ static void module_Unmap(vlc_plugin_t *plugin)
         return;
 
     assert(plugin->handle != NULL);
-    module_Unload(plugin->handle);
+    vlc_dlclose(plugin->handle);
 }
 #else
 int module_Map(vlc_object_t *obj, vlc_plugin_t *plugin)
diff --git a/src/modules/modules.h b/src/modules/modules.h
index dd30db3495..505629dfbd 100644
--- a/src/modules/modules.h
+++ b/src/modules/modules.h
@@ -26,9 +26,6 @@
 
 # include <stdatomic.h>
 
-/** The plugin handle type */
-typedef void *module_handle_t;
-
 /** VLC plugin */
 typedef struct vlc_plugin_t
 {
@@ -52,7 +49,7 @@ typedef struct vlc_plugin_t
 #ifdef HAVE_DYNAMIC_PLUGINS
     atomic_bool loaded; /**< Whether the plug-in is mapped in memory */
     bool unloadable; /**< Whether the plug-in can be unloaded safely */
-    module_handle_t handle; /**< Run-time linker handle (if loaded) */
+    void *handle; /**< Run-time linker handle (if loaded) */
     char *abspath; /**< Absolute path */
 
     char *path; /**< Relative path (within plug-in directory) */
@@ -122,9 +119,48 @@ ssize_t module_list_cap (module_t ***, const char *);
 int vlc_bindtextdomain (const char *);
 
 /* Low-level OS-dependent handler */
-int module_Load (vlc_object_t *, const char *, module_handle_t *, bool);
-void *module_Lookup (module_handle_t, const char *);
-void module_Unload (module_handle_t);
+
+/**
+ * Loads a dynamically linked library.
+ *
+ * \param path library file path
+ * \param lazy whether to resolve the symbols lazily
+ * \return a module handle on success, or NULL on error.
+ */
+void *vlc_dlopen(const char *path, bool) VLC_USED;
+
+/**
+ * Unloads a dynamic library.
+ *
+ * This function unloads a previously opened dynamically linked library
+ * using a system dependent method.
+ * \param handle handle of the library
+ * \retval 0 on success
+ * \retval -1 on error (none are defined though)
+ */
+int vlc_dlclose(void *);
+
+/**
+ * Looks up a symbol from a dynamically loaded library
+ *
+ * This function looks for a named symbol within a loaded library.
+ *
+ * \param handle handle to the library
+ * \param name function name
+ * \return the address of the symbol on success, or NULL on error
+ *
+ * \note If the symbol address is NULL, errors cannot be detected. However,
+ * normal symbols such as function or global variables cannot have NULL as
+ * their address.
+ */
+void *vlc_dlsym(void *handle, const char *) VLC_USED;
+
+/**
+ * Formats an error message for vlc_dlopen() or vlc_dlsym().
+ *
+ * \return a heap-allocated nul-terminated error string, or NULL.
+ */
+char *vlc_dlerror(void) VLC_USED;
 
 /* Plugins cache */
 vlc_plugin_t *vlc_cache_load(vlc_object_t *, const char *, block_t **);
diff --git a/src/os2/plugin.c b/src/os2/plugin.c
index c57180cfa7..9473501ee9 100644
--- a/src/os2/plugin.c
+++ b/src/os2/plugin.c
@@ -31,69 +31,40 @@
 #endif
 
 #include <string.h>
+#include <sys/types.h>
+#include <dlfcn.h>
 
 #include <vlc_common.h>
 #include <vlc_charset.h>
 #include "modules/modules.h"
 
-#include <sys/types.h>
-#include <dlfcn.h>
-
-/**
- * Load a dynamically linked library using a system dependent method.
- *
- * \param p_this vlc object
- * \param psz_file library file
- * \param p_handle the module handle returned
- * \return 0 on success as well as the module handle.
- */
-int module_Load( vlc_object_t *p_this, const char *psz_file,
-                 module_handle_t *p_handle, bool lazy )
+void *vlc_dlopen(const char *psz_file, bool lazy )
 {
     const int flags = lazy ? RTLD_LAZY : RTLD_NOW;
     char *path = ToLocaleDup( psz_file );
+    if (unlikely(path == NULL))
+        return NULL;
 
-    module_handle_t handle = dlopen( path, flags );
-    if( handle == NULL )
-    {
-        msg_Warn( p_this, "cannot load module `%s' (%s)", path, dlerror() );
-        free( path );
-        return -1;
-    }
+    void *handle = dlopen( path, flags );
     free( path );
-    *p_handle = handle;
-    return 0;
+    return handle;
 }
 
-/**
- * CloseModule: unload a dynamic library
- *
- * This function unloads a previously opened dynamically linked library
- * using a system dependent method. No return value is taken in consideration,
- * since some libraries sometimes refuse to close properly.
- * \param handle handle of the library
- * \return nothing
- */
-void module_Unload( module_handle_t handle )
+int vlc_dlclose(void *handle)
 {
-    dlclose( handle );
+    return dlclose( handle );
 }
 
-/**
- * Looks up a symbol from a dynamically loaded library
- *
- * This function queries a loaded library for a symbol specified in a
- * string, and returns a pointer to it. We don't check for dlerror() or
- * similar functions, since we want a non-NULL symbol anyway.
- *
- * @param handle handle to the module
- * @param psz_function function name
- * @return NULL on error, or the address of the symbol
- */
-void *module_Lookup( module_handle_t handle, const char *psz_function )
+void *vlc_dlsym(void *handle, const char *psz_function)
 {
     char buf[strlen(psz_function) + 2];
     buf[0] = '_';
     strcpy(buf + 1, psz_function);
     return dlsym( handle, buf );
 }
+
+char *vlc_dlerror(void)
+{
+    const char *errmsg = dlerror();
+    return (errmsg != NULL) ? FromLocaleDup(errmsg) : NULL;
+}
diff --git a/src/posix/plugin.c b/src/posix/plugin.c
index 4f30da184e..65db4ee702 100644
--- a/src/posix/plugin.c
+++ b/src/posix/plugin.c
@@ -28,6 +28,7 @@
 # include "config.h"
 #endif
 
+#include <assert.h>
 #include <vlc_common.h>
 #include "modules/modules.h"
 
@@ -38,16 +39,7 @@
 # include <valgrind/valgrind.h>
 #endif
 
-/**
- * Load a dynamically linked library using a system dependent method.
- *
- * \param p_this vlc object
- * \param path library file
- * \param p_handle the module handle returned
- * \return 0 on success as well as the module handle.
- */
-int module_Load (vlc_object_t *p_this, const char *path,
-                 module_handle_t *p_handle, bool lazy)
+void *vlc_dlopen(const char *path, bool lazy)
 {
 #if defined (RTLD_NOW)
     const int flags = lazy ? RTLD_LAZY : RTLD_NOW;
@@ -56,51 +48,33 @@ int module_Load (vlc_object_t *p_this, const char *path,
 #else
     const int flags = 0;
 #endif
-
-    module_handle_t handle = dlopen (path, flags);
-    if( handle == NULL )
-    {
-        msg_Warn( p_this, "cannot load module `%s' (%s)", path, dlerror() );
-        return -1;
-    }
-    *p_handle = handle;
-    return 0;
+    return dlopen (path, flags);
 }
 
-/**
- * CloseModule: unload a dynamic library
- *
- * This function unloads a previously opened dynamically linked library
- * using a system dependent method. No return value is taken in consideration,
- * since some libraries sometimes refuse to close properly.
- * \param handle handle of the library
- * \return nothing
- */
-void module_Unload( module_handle_t handle )
+int vlc_dlclose(void *handle)
 {
 #if !defined(__SANITIZE_ADDRESS__)
 #ifdef HAVE_VALGRIND_VALGRIND_H
     if( RUNNING_ON_VALGRIND > 0 )
-        return; /* do not dlclose() so that we get proper stack traces */
+        return 0; /* do not dlclose() so that we get proper stack traces */
 #endif
-    dlclose( handle );
+    int err = dlclose( handle );
+    assert(err == 0);
+    return err;
 #else
     (void) handle;
+    return 0;
 #endif
 }
 
-/**
- * Looks up a symbol from a dynamically loaded library
- *
- * This function queries a loaded library for a symbol specified in a
- * string, and returns a pointer to it. We don't check for dlerror() or
- * similar functions, since we want a non-NULL symbol anyway.
- *
- * @param handle handle to the module
- * @param psz_function function name
- * @return NULL on error, or the address of the symbol
- */
-void *module_Lookup( module_handle_t handle, const char *psz_function )
+void *vlc_dlsym(void *handle, const char *name)
+{
+    return dlsym(handle, name);
+}
+
+char *vlc_dlerror(void)
 {
-    return dlsym( handle, psz_function );
+    const char *errmsg = dlerror();
+    /* XXX: This is not thread-safe at all. POSIX is helpless here. */
+    return (errmsg != NULL) ? strdup(errmsg) : NULL;
 }
diff --git a/src/win32/plugin.c b/src/win32/plugin.c
index 3a3be16d3c..a0d392e6e0 100644
--- a/src/win32/plugin.c
+++ b/src/win32/plugin.c
@@ -33,7 +33,7 @@
 #include <windows.h>
 #include <wchar.h>
 
-static char *GetWindowsError( void )
+char *vlc_dlerror(void)
 {
     wchar_t wmsg[256];
     int i = 0, i_error = GetLastError();
@@ -50,14 +50,13 @@ static char *GetWindowsError( void )
     return FromWide( wmsg );
 }
 
-int module_Load( vlc_object_t *p_this, const char *psz_file,
-                 module_handle_t *p_handle, bool lazy )
+void *vlc_dlopen(const char *psz_file, bool lazy)
 {
     wchar_t *wfile = ToWide (psz_file);
     if (wfile == NULL)
-        return -1;
+        return NULL;
 
-    module_handle_t handle = NULL;
+    HMODULE handle = NULL;
 #if !VLC_WINSTORE_APP
     DWORD mode;
     if (SetThreadErrorMode (SEM_FAILCRITICALERRORS, &mode) != 0)
@@ -70,25 +69,17 @@ int module_Load( vlc_object_t *p_this, const char *psz_file,
 #endif
     free (wfile);
 
-    if( handle == NULL )
-    {
-        char *psz_err = GetWindowsError();
-        msg_Warn( p_this, "cannot load module `%s' (%s)", psz_file, psz_err );
-        free( psz_err );
-        return -1;
-    }
-
-    *p_handle = handle;
     (void) lazy;
-    return 0;
+    return handle;
 }
 
-void module_Unload( module_handle_t handle )
+int vlc_dlclose(void *handle)
 {
     FreeLibrary( handle );
+    return 0;
 }
 
-void *module_Lookup( module_handle_t handle, const char *psz_function )
+void *vlc_dlsym(void *handle, const char *psz_function)
 {
-    return (void *)GetProcAddress( handle, (char *)psz_function );
+    return (void *)GetProcAddress(handle, psz_function);
 }



More information about the vlc-commits mailing list