[vlc-commits] commit: Support different prototype for plugin open/close callbacks ( =?UTF-8?Q?R=C3=A9mi=20Denis=2DCourmont=20?=)

git at videolan.org git at videolan.org
Tue Jan 11 21:31:51 CET 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jan 11 22:02:59 2011 +0200| [b7de335c4e4b2d2a34d176d5991cd49d46220c88] | committer: Rémi Denis-Courmont 

Support different prototype for plugin open/close callbacks

We can now pass any number and type of parameter to the callbacks.
This way, we do not need to clutter the object structure with
properties that only make sense during activation. In fact, we do
not need to use VLC objects at all anymore.

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

 include/vlc_modules.h |   10 ++++-
 src/libvlccore.sym    |    2 +
 src/modules/entry.c   |    6 +--
 src/modules/modules.c |  116 ++++++++++++++++++++++++++++++++++++++-----------
 src/modules/modules.h |    4 +-
 5 files changed, 105 insertions(+), 33 deletions(-)

diff --git a/include/vlc_modules.h b/include/vlc_modules.h
index e810f87..af982b2 100644
--- a/include/vlc_modules.h
+++ b/include/vlc_modules.h
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * modules.h : Module descriptor and load functions
  *****************************************************************************
- * Copyright (C) 2001 the VideoLAN team
+ * Copyright (C) 2001-2011 the VideoLAN team
  * $Id$
  *
  * Authors: Samuel Hocevar <sam at zoy.org>
@@ -26,10 +26,18 @@
  * This file defines functions for modules in vlc
  */
 
+typedef int (*vlc_activate_t)(void *func, va_list args);
+typedef void (*vlc_deactivate_t)(void *func, va_list args);
+
 /*****************************************************************************
  * Exported functions.
  *****************************************************************************/
 
+VLC_EXPORT( module_t *, vlc_module_load, ( vlc_object_t *obj, const char *cap, const char *name, bool strict, vlc_activate_t probe, ... ) );
+#define vlc_module_load(o,c,n,s,...) \
+        vlc_module_load(VLC_OBJECT(o),c,n,s,__VA_ARGS__)
+VLC_EXPORT( void, vlc_module_unload, ( module_t *, vlc_deactivate_t deinit, ... ) );
+
 VLC_EXPORT( module_t *, module_need, ( vlc_object_t *, const char *, const char *, bool ) );
 #define module_need(a,b,c,d) module_need(VLC_OBJECT(a),b,c,d)
 VLC_EXPORT( void, module_unneed, ( vlc_object_t *, module_t * ) );
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index dc888ed..c35e1c3 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -269,6 +269,8 @@ module_need
 module_provides
 module_release
 module_unneed
+vlc_module_load
+vlc_module_unload
 msg_DisableObjectPrinting
 msg_EnableObjectPrinting
 msg_Generic
diff --git a/src/modules/entry.c b/src/modules/entry.c
index 42f8449..be70bf8 100644
--- a/src/modules/entry.c
+++ b/src/modules/entry.c
@@ -160,8 +160,6 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
 {
     va_list ap;
     int ret = 0;
-    typedef int(*int_fp_vlcobjectt)(vlc_object_t *) ;
-    typedef void(*void_fp_vlcobjectt)(vlc_object_t *);
 
     va_start (ap, propid);
     switch (propid)
@@ -215,11 +213,11 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
             break;
 
         case VLC_MODULE_CB_OPEN:
-            module->pf_activate = va_arg (ap, int_fp_vlcobjectt);
+            module->pf_activate = va_arg (ap, void *);
             break;
 
         case VLC_MODULE_CB_CLOSE:
-            module->pf_deactivate = va_arg (ap, void_fp_vlcobjectt);
+            module->pf_deactivate = va_arg (ap, void *);
             break;
 
         case VLC_MODULE_NO_UNLOAD:
diff --git a/src/modules/modules.c b/src/modules/modules.c
index 4b3d9b1..0ec3b3b 100644
--- a/src/modules/modules.c
+++ b/src/modules/modules.c
@@ -1,13 +1,14 @@
 /*****************************************************************************
  * modules.c : Builtin and plugin modules management functions
  *****************************************************************************
- * Copyright (C) 2001-2007 the VideoLAN team
+ * Copyright (C) 2001-2011 the VideoLAN team
  * $Id$
  *
  * Authors: Sam Hocevar <sam at zoy.org>
  *          Ethan C. Baldridge <BaldridgeE at cadmus.com>
  *          Hans-Peter Jansen <hpj at urpla.net>
  *          Gildas Bazin <gbazin at videolan.org>
+ *          Rémi Denis-Courmont
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -330,14 +331,18 @@ void module_release (module_t *m)
 #undef module_start
 int module_start (vlc_object_t *obj, module_t *m)
 {
-   return m->pf_activate ? (m->pf_activate (obj)) : VLC_SUCCESS;
+   int (*activate) (vlc_object_t *) = m->pf_activate;
+
+   return (activate != NULL) ? activate (obj) : VLC_SUCCESS;
 }
 
 #undef module_stop
 void module_stop (vlc_object_t *obj, module_t *m)
 {
-    if (m->pf_deactivate)
-        m->pf_deactivate (obj);
+   void (*deactivate) (vlc_object_t *) = m->pf_deactivate;
+
+    if (deactivate != NULL)
+        deactivate (obj);
 }
 
 /**
@@ -406,21 +411,30 @@ static int modulecmp (const void *a, const void *b)
     return lb->i_score - la->i_score;
 }
 
-#undef module_need
+#undef vlc_module_load
 /**
- * module Need
+ * Finds and instantiates the best module of a certain type.
+ * All candidates modules having the specified capability and name will be
+ * sorted in decreasing order of priority. Then the probe callback will be
+ * invoked for each module, until it succeeds (returns 0), or all candidate
+ * module failed to initialize.
  *
- * Return the best module function, given a capability list.
+ * The probe callback first parameter is the address of the module entry point.
+ * Further parameters are passed as an argument list; it corresponds to the
+ * variable arguments passed to this function. This scheme is meant to
+ * support arbitrary prototypes for the module entry point.
  *
- * \param p_this the vlc object
- * \param psz_capability list of capabilities needed
- * \param psz_name name of the module asked
+ * \param p_this VLC object
+ * \param psz_capability capability, i.e. class of module
+ * \param psz_name name name of the module asked, if any
  * \param b_strict if true, do not fallback to plugin with a different name
  *                 but the same capability
+ * \param probe module probe callback
  * \return the module or NULL in case of a failure
  */
-module_t * module_need( vlc_object_t *p_this, const char *psz_capability,
-                        const char *psz_name, bool b_strict )
+module_t *vlc_module_load(vlc_object_t *p_this, const char *psz_capability,
+                          const char *psz_name, bool b_strict,
+                          vlc_activate_t probe, ...)
 {
     stats_TimerStart( p_this, "module_need()", STATS_TIMER_MODULE_NEED );
 
@@ -547,7 +561,11 @@ found_shortcut:
              count, count == 1 ? "" : "s" );
 
     /* Parse the linked list and use the first successful module */
+    va_list args;
+
+    va_start(args, probe);
     p_module = NULL;
+
     for (size_t i = 0; (i < count) && (p_module == NULL); i++)
     {
         module_t *p_cand = p_list[i].p_module;
@@ -569,10 +587,22 @@ found_shortcut:
             DeleteModule( p_module_bank, p_new_module );
         }
 #endif
-
         p_this->b_force = p_list[i].b_force;
 
-        switch( module_start( p_this, p_cand ) )
+        int ret;
+
+        if (likely(p_cand->pf_activate != NULL))
+        {
+            va_list ap;
+
+            va_copy(ap, args);
+            ret = probe(p_cand->pf_activate, ap);
+            va_end(ap);
+        }
+        else
+            ret = VLC_SUCCESS;
+
+        switch (ret)
         {
         case VLC_SUCCESS:
             /* good module! */
@@ -594,6 +624,7 @@ found_shortcut:
             module_release (p_list[i].p_module);
     }
 
+    va_end (args);
     free( p_list );
     p_this->b_force = b_force_backup;
 
@@ -622,21 +653,54 @@ found_shortcut:
     return p_module;
 }
 
-#undef module_unneed
+
 /**
- * Module unneed
- *
- * This function must be called by the thread that called module_need, to
- * decrease the reference count and allow for hiding of modules.
- * \param p_this vlc object structure
- * \param p_module the module structure
- * \return nothing
+ * Deinstantiates a module.
+ * \param module the module pointer as returned by vlc_module_load()
+ * \param deinit deactivation callback
  */
-void module_unneed( vlc_object_t * p_this, module_t * p_module )
+void vlc_module_unload(module_t *module, vlc_deactivate_t deinit, ...)
 {
-    msg_Dbg( p_this, "removing module \"%s\"", p_module->psz_object_name );
-    module_stop( p_this, p_module );
-    module_release( p_module );
+    if (module->pf_deactivate != NULL)
+    {
+        va_list ap;
+
+        va_start(ap, deinit);
+        deinit(module->pf_deactivate, ap);
+        va_end(ap);
+    }
+    module_release(module);
+}
+
+
+static int generic_start(void *func, va_list ap)
+{
+    vlc_object_t *obj = va_arg(ap, vlc_object_t *);
+    int (*activate)(vlc_object_t *) = func;
+
+    return activate(obj);
+}
+
+static void generic_stop(void *func, va_list ap)
+{
+    vlc_object_t *obj = va_arg(ap, vlc_object_t *);
+    void (*deactivate)(vlc_object_t *) = func;
+
+    deactivate(obj);
+}
+
+#undef module_need
+module_t *module_need(vlc_object_t *obj, const char *cap, const char *name,
+                      bool strict)
+{
+    return vlc_module_load(obj, cap, name, strict, generic_start, obj);
+}
+
+#undef module_unneed
+void module_unneed(vlc_object_t *obj, module_t *module)
+{
+    msg_Dbg(obj, "removing module \"%s\"", module->psz_object_name);
+    vlc_module_unload(module, generic_stop, obj);
 }
 
 /**
diff --git a/src/modules/modules.h b/src/modules/modules.h
index e42f23a..90e9f9e 100644
--- a/src/modules/modules.h
+++ b/src/modules/modules.h
@@ -114,8 +114,8 @@ struct module_t
     bool b_submodule;                        /**< Is this a submodule? */
 
     /* Callbacks */
-    int  ( * pf_activate )   ( vlc_object_t * );
-    void ( * pf_deactivate ) ( vlc_object_t * );
+    void *pf_activate;
+    void *pf_deactivate;
 
     /*
      * Variables set by the module to store its config options



More information about the vlc-commits mailing list