Doxygen Book
nnstreamer_subplugin.c
Go to the documentation of this file.
1 
26 #include <glib.h>
27 #include <gmodule.h>
28 
29 #include "nnstreamer_log.h"
30 #include "nnstreamer_subplugin.h"
31 #include "nnstreamer_conf.h"
32 #include <nnstreamer_util.h>
33 
35 static GPtrArray *handles = NULL;
36 
37 static void init_subplugin (void) __attribute__((constructor));
38 static void fini_subplugin (void) __attribute__((destructor));
39 
40 typedef struct
41 {
42  char *name;
43  const void *data;
44  GData *custom_dlist;
46 
47 static GHashTable *subplugins[NNS_SUBPLUGIN_END] = { 0 };
48 
50 G_LOCK_DEFINE_STATIC (splock);
51 
53 static void
54 _spdata_destroy (gpointer _data)
55 {
56  subpluginData *data = _data;
57 
58  g_datalist_clear (&data->custom_dlist);
59 
60  g_free (data->name);
61  g_free (data);
62 }
63 
64 typedef enum
65 {
70 
81 };
82 
86 static subpluginData *
87 _get_subplugin_data (subpluginType type, const gchar * name)
88 {
89  subpluginData *spdata = NULL;
90 
91  G_LOCK (splock);
92  if (subplugins[type] == NULL) {
93  subplugins[type] =
94  g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
96  } else {
97  spdata = g_hash_table_lookup (subplugins[type], name);
98  }
99  G_UNLOCK (splock);
100 
101  return spdata;
102 }
103 
107 static subpluginData *
108 _search_subplugin (subpluginType type, const gchar * name, const gchar * path)
109 {
110  subpluginData *spdata = NULL;
111  GModule *module;
112 
113  g_return_val_if_fail (name != NULL, NULL);
114  g_return_val_if_fail (path != NULL, NULL);
115 
116  module = g_module_open (path, G_MODULE_BIND_LOCAL);
117  /* If this is a correct subplugin, it will register itself */
118  if (module == NULL) {
119  ml_loge ("Cannot open %s(%s) with error %s.", name, path,
120  g_module_error ());
121  return NULL;
122  }
123 
124  spdata = _get_subplugin_data (type, name);
125  if (spdata) {
126  G_LOCK (splock);
127  g_ptr_array_add (handles, (gpointer) module);
128  G_UNLOCK (splock);
129  } else {
130  ml_loge
131  ("nnstreamer_subplugin of %s(%s) is broken. It does not call register_subplugin with its init function.",
132  name, path);
133  g_module_close (module);
134  }
135 
136  return spdata;
137 }
138 
140 const void *
141 get_subplugin (subpluginType type, const char *name)
142 {
143  subpluginData *spdata = NULL;
144 
145  g_return_val_if_fail (name, NULL);
146 
149  subplugin_info_s info;
150  guint i;
151  guint ret = nnsconf_get_subplugin_info (conf_type, &info);
152 
153  for (i = 0; i < ret; i++) {
154  _search_subplugin (type, info.names[i], info.paths[i]);
155  }
156 
158  }
159 
160  spdata = _get_subplugin_data (type, name);
161  if (spdata == NULL && searchAlgorithm[type] == NNS_SEARCH_FILENAME) {
164  const gchar *fullpath = nnsconf_get_fullpath (name, conf_type);
165 
166  if (nnsconf_validate_file (conf_type, fullpath)) {
167  spdata = _search_subplugin (type, name, fullpath);
168  }
169  }
170 
171  return (spdata != NULL) ? spdata->data : NULL;
172 }
173 
175 gchar **
177 {
178  GString *names;
179  subplugin_info_s info;
180  gchar **list = NULL;
181  gchar *name;
182  guint i, total;
183 
184  names = g_string_new (NULL);
185 
186  /* get registered subplugins */
187  G_LOCK (splock);
188  if (subplugins[type]) {
189  list = (gchar **) g_hash_table_get_keys_as_array (subplugins[type], NULL);
190  }
191  G_UNLOCK (splock);
192 
193  if (list) {
194  name = g_strjoinv (",", list);
195  g_string_append (names, name);
196  g_free (name);
197  }
198 
199  /* get subplugins from configuration */
201 
202  for (i = 0; i < total; i++) {
203  name = info.names[i];
204 
205  if (!list || !g_strv_contains ((const gchar * const *) list, name)) {
206  if (list || i > 0)
207  g_string_append (names, ",");
208 
209  g_string_append (names, name);
210  }
211  }
212 
213  g_free (list);
214 
215  /* finally get the list of subplugins */
216  name = g_string_free (names, FALSE);
217  list = g_strsplit (name, ",", -1);
218  g_free (name);
219 
220  return list;
221 }
222 
224 gboolean
225 register_subplugin (subpluginType type, const char *name, const void *data)
226 {
228  subpluginData *spdata = NULL;
229  gchar *sp_name = NULL;
230  gboolean ret;
231 
232  g_return_val_if_fail (name, FALSE);
233  g_return_val_if_fail (data, FALSE);
234 
235  switch (type) {
241  case NNS_CUSTOM_DECODER:
242  case NNS_IF_CUSTOM:
244  break;
245  default:
246  /* unknown sub-plugin type */
247  return FALSE;
248  }
249 
250  /* check the sub-pugin name */
251  if (g_ascii_strcasecmp (name, "any") == 0 ||
252  g_ascii_strcasecmp (name, "auto") == 0) {
253  ml_loge ("Failed, the name %s is not allowed.", name);
254  return FALSE;
255  }
256 
257  spdata = _get_subplugin_data (type, name);
258  if (spdata) {
259  /* already exists */
260  ml_logw ("Subplugin %s is already registered.", name);
261  return FALSE;
262  }
263 
264  spdata = g_new0 (subpluginData, 1);
265  if (spdata == NULL) {
266  ml_loge ("Failed to allocate memory for subplugin registration.");
267  return FALSE;
268  }
269 
270  spdata->name = g_strdup (name);
271  spdata->data = data;
272  g_datalist_init (&spdata->custom_dlist);
273 
274  G_LOCK (splock);
275  sp_name = g_strdup (name);
276  ret = g_hash_table_insert (subplugins[type], sp_name, spdata);
277  if (!ret) {
278  _spdata_destroy (spdata);
279  g_free (sp_name);
280  ml_loge ("Failed to add subplugin data into the table.");
281  }
282  G_UNLOCK (splock);
283 
284  return ret;
285 }
286 
288 gboolean
290 {
291  gboolean ret;
292 
293  g_return_val_if_fail (name, FALSE);
294  g_return_val_if_fail (subplugins[type], FALSE);
295 
296  G_LOCK (splock);
297  ret = g_hash_table_remove (subplugins[type], name);
298  G_UNLOCK (splock);
299 
300  return ret;
301 }
302 
304 static void
305 _close_handle (gpointer data)
306 {
317 #if defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 24)
318  UNUSED (data);
319  return; /* Do not call close and return */
320 #else
321  g_module_close ((GModule *) data);
322 #endif
323 }
324 
328 void
330  const gchar * prop, va_list varargs)
331 {
332  subpluginData *spdata;
333 
334  g_return_if_fail (name != NULL);
335  g_return_if_fail (subplugins[type] != NULL);
336 
337  spdata = _get_subplugin_data (type, name);
338  g_return_if_fail (spdata != NULL);
339 
340  g_datalist_clear (&spdata->custom_dlist);
341 
342  while (prop) {
343  gchar *desc = va_arg (varargs, gchar *);
344 
345  if (G_UNLIKELY (desc == NULL)) {
346  ml_logw ("No description for %s", prop);
347  return;
348  }
349 
350  g_datalist_set_data (&spdata->custom_dlist, prop, desc);
351  prop = va_arg (varargs, gchar *);
352  }
353 }
354 
358 GData *
360 {
361  subpluginData *spdata;
362 
363  g_return_val_if_fail (name != NULL, NULL);
364  g_return_val_if_fail (subplugins[type] != NULL, NULL);
365 
366  spdata = _get_subplugin_data (type, name);
367  if (spdata)
368  return spdata->custom_dlist;
369 
370  return NULL;
371 }
372 
374 static void
375 init_subplugin (void)
376 {
377  G_LOCK (splock);
378  g_assert (NULL == handles);
379  handles = g_ptr_array_new_full (16, _close_handle);
380  G_UNLOCK (splock);
381 }
382 
384 static void
386 {
387  G_LOCK (splock);
388  g_assert (handles);
390  /* iterate and call close by calling g_array_clear */
391  g_ptr_array_free (handles, TRUE);
392  handles = NULL;
393  G_UNLOCK (splock);
394 }
NNS_SUBPLUGIN_DECODER
@ NNS_SUBPLUGIN_DECODER
Definition: nnstreamer_subplugin.h:42
g_assert
g_assert(sizeof(DTYPE_UNSIGNED)==sizeof(DTYPE_SIGNED))
NNS_IF_CUSTOM
@ NNS_IF_CUSTOM
Definition: nnstreamer_subplugin.h:48
NNS_SUBPLUGIN_FILTER
@ NNS_SUBPLUGIN_FILTER
Definition: nnstreamer_subplugin.h:41
data
svtc_1 data
Definition: gsttensor_if.c:844
ml_logw
#define ml_logw
Definition: nnstreamer_log.h:77
handles
static GPtrArray * handles
Array of dynamic loaded handles.
Definition: nnstreamer_subplugin.c:35
FALSE
return FALSE
Definition: gsttensor_transform.c:590
nnstreamer_subplugin.h
Subplugin Manager for NNStreamer.
nnstreamer_conf.h
Internal header for conf/env-var management.
NNS_SEARCH_FILENAME
@ NNS_SEARCH_FILENAME
Definition: nnstreamer_subplugin.c:66
NNS_EASY_CUSTOM_FILTER
@ NNS_EASY_CUSTOM_FILTER
Definition: nnstreamer_subplugin.h:43
prop
GstTensorSrcIIOChannelProperties * prop
DTYPE_UNSIGNED ( .
Definition: gsttensor_srciio.c:110
subplugin_set_custom_property_desc
void subplugin_set_custom_property_desc(subpluginType type, const char *name, const gchar *prop, va_list varargs)
common interface to set custom property description of a sub-plugin.
Definition: nnstreamer_subplugin.c:329
nnstreamer_log.h
Internal log util for NNStreamer plugins and native APIs.
subplugins
static GHashTable * subplugins[NNS_SUBPLUGIN_END]
Definition: nnstreamer_subplugin.c:47
NNS_CUSTOM_CONVERTER
@ NNS_CUSTOM_CONVERTER
Definition: nnstreamer_subplugin.h:46
NNS_SUBPLUGIN_TRAINER
@ NNS_SUBPLUGIN_TRAINER
Definition: nnstreamer_subplugin.h:45
_search_subplugin
static subpluginData * _search_subplugin(subpluginType type, const gchar *name, const gchar *path)
Internal function to scan sub-plugin.
Definition: nnstreamer_subplugin.c:108
subpluginData
subpluginData
Definition: nnstreamer_subplugin.c:45
NNS_SEARCH_NO_OP
@ NNS_SEARCH_NO_OP
Definition: nnstreamer_subplugin.c:68
NNS_SUBPLUGIN_CONVERTER
@ NNS_SUBPLUGIN_CONVERTER
Definition: nnstreamer_subplugin.h:44
g_free
g_free(self->option[(opnum) - 1])
opnum: \
init_subplugin
static void init_subplugin(void)
Create handles at the start of library.
Definition: nnstreamer_subplugin.c:37
subplugin_info_s::names
gchar ** names
Definition: nnstreamer_conf.h:77
__attribute__
__attribute__((__format__(__printf__, 1, 2)))
overwrites the error message buffer with the new message.
Definition: nnstreamer_log.c:97
nnsconf_validate_file
gboolean nnsconf_validate_file(nnsconf_type_path type, const gchar *fullpath)
Public function to validate sub-plugin library is available.
Definition: nnstreamer_conf.c:503
NNS_SEARCH_GETALL
@ NNS_SEARCH_GETALL
Definition: nnstreamer_subplugin.c:67
_get_subplugin_data
static subpluginData * _get_subplugin_data(subpluginType type, const gchar *name)
Internal function to get sub-plugin data.
Definition: nnstreamer_subplugin.c:87
nnsconf_type_path
nnsconf_type_path
Definition: nnstreamer_conf.h:63
subpluginType
subpluginType
Definition: nnstreamer_subplugin.h:40
register_subplugin
gboolean register_subplugin(subpluginType type, const char *name, const void *data)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:225
NNS_CUSTOM_DECODER
@ NNS_CUSTOM_DECODER
Definition: nnstreamer_subplugin.h:47
get_all_subplugins
gchar ** get_all_subplugins(subpluginType type)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:176
ml_loge
#define ml_loge
Definition: nnstreamer_log.h:78
NNS_SUBPLUGIN_END
@ NNS_SUBPLUGIN_END
Definition: nnstreamer_subplugin.h:50
TRUE
return TRUE
Definition: gsttensor_if.c:897
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
nnsconf_get_subplugin_info
guint nnsconf_get_subplugin_info(nnsconf_type_path type, subplugin_info_s *info)
Public function to get the list of sub-plugins name and path.
Definition: nnstreamer_conf.c:528
subplugin_info_s
Definition: nnstreamer_conf.h:75
G_LOCK_DEFINE_STATIC
G_LOCK_DEFINE_STATIC(splock)
Protects handles and subplugins.
_spdata_destroy
static void _spdata_destroy(gpointer _data)
Private function for g_hash_table data destructor, GDestroyNotify.
Definition: nnstreamer_subplugin.c:54
subplugin_get_custom_property_desc
GData * subplugin_get_custom_property_desc(subpluginType type, const char *name)
common interface to get custom property description of a sub-plugin.
Definition: nnstreamer_subplugin.c:359
type
svtc_1 type
Definition: gsttensor_if.c:843
subpluginSearchLogic
subpluginSearchLogic
Definition: nnstreamer_subplugin.c:64
subplugin_info_s::paths
gchar ** paths
Definition: nnstreamer_conf.h:78
searchAlgorithm
static subpluginSearchLogic searchAlgorithm[]
Definition: nnstreamer_subplugin.c:71
nnsconf_get_fullpath
const gchar * nnsconf_get_fullpath(const gchar *subpluginname, nnsconf_type_path type)
Public function defined in the header.
Definition: nnstreamer_conf.c:483
get_subplugin
const void * get_subplugin(subpluginType type, const char *name)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:141
unregister_subplugin
gboolean unregister_subplugin(subpluginType type, const char *name)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:289
_close_handle
static void _close_handle(gpointer data)
dealloc function for handles
Definition: nnstreamer_subplugin.c:305
fini_subplugin
static void fini_subplugin(void)
Free handles at the start of library.
Definition: nnstreamer_subplugin.c:385