source: roaraudio/libroar/roardl.c @ 5427:543c052527b2

Last change on this file since 5427:543c052527b2 was 5427:543c052527b2, checked in by phi, 12 years ago

support usage of plugin path also outside plugin containers

File size: 19.5 KB
Line 
1//roardl.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#ifdef ROAR_HAVE_H_DIRENT
39#include <dirent.h>
40#endif
41
42#if defined(ROAR_HAVE_LIBDL) && !defined(RTLD_NEXT)
43#define RTLD_NEXT ((void *) -1L)
44#endif
45
46struct roar_dl_lhandle {
47 size_t refc; // currently unused.
48 int flags;
49 char * libname; // only used for ROAR_DL_FLAG_STATIC.
50 struct roar_dl_librarypara * para;
51 struct roar_dl_libraryinst * lib;
52 struct {
53  struct roar_error_state error_state;
54  void *  global_data;
55  void *  global_data_state;
56  struct roar_notify_core * notifycore;
57 } context;
58#if defined(ROAR_HAVE_LIBDL)
59 void * handle;
60#endif
61};
62
63
64struct roar_dl_librarypara * roar_dl_para_new(const char * args, void * binargv,
65                                              const char * appname, const char * abiversion) {
66 struct roar_dl_librarypara * ret = roar_mm_malloc(sizeof(struct roar_dl_librarypara));
67 ssize_t argc;
68 int err;
69
70 if ( ret == NULL )
71  return NULL;
72
73 memset(ret, 0, sizeof(struct roar_dl_librarypara));
74
75 ret->version    = ROAR_DL_LIBPARA_VERSION;
76 ret->len        = sizeof(struct roar_dl_librarypara);
77 ret->refc       = 1;
78 ret->argc       = 0;
79 ret->argv       = NULL;
80 ret->args_store = NULL;
81 ret->binargv    = binargv;
82 ret->appname    = appname;
83 ret->abiversion = abiversion;
84
85 if ( args != NULL ) {
86  ret->args_store = roar_mm_strdup(args);
87  if ( ret->args_store == NULL ) {
88   err = roar_error;
89   roar_mm_free(ret);
90   roar_error = err;
91   return NULL;
92  }
93
94  argc = roar_keyval_split(&(ret->argv), ret->args_store, NULL, NULL, 0);
95  if ( argc == -1 ) {
96   err = roar_error;
97   roar_mm_free(ret->args_store);
98   roar_mm_free(ret);
99   roar_error = err;
100   return NULL;
101  }
102
103  ret->argc = argc;
104 }
105
106 return ret;
107}
108
109int roar_dl_para_ref                    (struct roar_dl_librarypara * para) {
110 if ( para == NULL ) {
111  roar_err_set(ROAR_ERROR_FAULT);
112  return -1;
113 }
114
115 para->refc++;
116
117 return 0;
118}
119
120int roar_dl_para_unref                  (struct roar_dl_librarypara * para) {
121 if ( para == NULL ) {
122  roar_err_set(ROAR_ERROR_FAULT);
123  return -1;
124 }
125
126 para->refc--;
127
128 if ( para->refc )
129  return 0;
130
131 if ( para->notifycore != NULL )
132  roar_notify_core_unref(para->notifycore);
133
134 if ( para->args_store != NULL ) {
135  roar_mm_free(para->args_store);
136  roar_mm_free(para->argv);
137 }
138
139 roar_mm_free(para);
140
141 return 0;
142}
143int roar_dl_para_check_version          (struct roar_dl_librarypara * para,
144                                         const char * appname, const char * abiversion) {
145 if ( para == NULL ) {
146  roar_err_set(ROAR_ERROR_FAULT);
147  return -1;
148 }
149
150 // check if both appnames are NULL or non-NULL.
151 if ( (para->appname == NULL && appname != NULL) || (para->appname != NULL && appname == NULL) ) {
152  roar_err_set(ROAR_ERROR_BADHOST);
153  return -1;
154 }
155
156 // check if the appname matches if given.
157 if ( para->appname != NULL && !!strcmp(para->appname, appname) ) {
158  roar_err_set(ROAR_ERROR_BADHOST);
159  return -1;
160 }
161
162 // check if both ABI versions are NULL or non-NULL.
163 if ( (para->abiversion == NULL && abiversion != NULL) || (para->abiversion != NULL && abiversion == NULL) ) {
164  roar_err_set(ROAR_ERROR_BADVERSION);
165  return -1;
166 }
167
168 // check if the ABI versions matches if given.
169 if ( para->abiversion != NULL && !!strcmp(para->abiversion, abiversion) ) {
170  roar_err_set(ROAR_ERROR_BADVERSION);
171  return -1;
172 }
173
174 return 0;
175}
176
177
178#if defined(ROAR_HAVE_LIBDL)
179static void * _roardl2ldl (struct roar_dl_lhandle * lhandle) {
180 ROAR_DBG("_roardl2ldl(lhandle=%p) = ?", lhandle);
181
182 if ( lhandle == ROAR_DL_HANDLE_DEFAULT ) {
183  ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_DEFAULT);
184  return RTLD_DEFAULT;
185 }
186
187 if ( lhandle == ROAR_DL_HANDLE_NEXT ) {
188  ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_NEXT);
189  return RTLD_NEXT;
190 }
191
192 ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)(lhandle->handle));
193 return lhandle->handle;
194}
195#endif
196
197#ifdef ROAR_HAVE_H_DIRENT
198// pvn = prefix, host vendor, host name
199static struct roar_dl_lhandle * _load_from_path_pvn(const char * name,
200                                                    int flags, int ra_init,
201                                                    struct roar_dl_librarypara * para,
202                                                    const char * prefix,
203                                                    const char * hostvendor,
204                                                    const char * hostname) {
205 struct roar_dl_lhandle * ret = NULL;
206 int i, j;
207 char path[1024];
208 const char * path_format[] = {"%s/%s/%s", "%s/%s/universal", "%s/universal/universal"};
209 DIR * dir;
210 struct dirent * dirent;
211 char file[1024];
212 const char * file_format[] = {"%s/%s/%s", "%s/%s/%s" ROAR_SHARED_SUFFIX, "%s/%s/lib%s" ROAR_SHARED_SUFFIX};
213//  cont->handle[idx] = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, para);
214//#vars: $PREFIX_PLUGINS, $hostvendor, $hostname, $name
215//#search order: $PREFIX_PLUGINS/{$hostvendor/{$hostname,universal},universal/universal}/*/{,lib}$name.so
216
217 for (i = 0; i < 3; i++) {
218  snprintf(path, sizeof(path), path_format[i], prefix, hostvendor, hostname);
219  dir = opendir(path);
220  if ( dir == NULL )
221   continue;
222
223  while ((dirent = readdir(dir)) != NULL) {
224   if ( !strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..") )
225    continue;
226
227   for (j = 0; j < 3; j++) {
228    snprintf(file, sizeof(file), file_format[j], path, dirent->d_name, name);
229    ret = roar_dl_open(file, flags, ra_init, para);
230    if ( ret != NULL ) {
231     closedir(dir);
232     return ret;
233    }
234   }
235  }
236
237  closedir(dir);
238 }
239
240 return NULL;
241}
242
243static struct roar_dl_lhandle * _load_from_path(const char * name, int flags, int ra_init,
244                                                struct roar_dl_librarypara * para) {
245 struct roar_dl_lhandle * ret = NULL;
246 char * host = NULL;
247 char * hostvendor_buffer = NULL;
248 char * hostvendor = NULL;
249 char * hostname = NULL;
250 char * c, * d;
251
252 if ( para != NULL && para->appname != NULL && para->appname[0] != 0 ) {
253  host = roar_mm_strdup(para->appname);
254
255  // if we are out of memory we will likely not pass the rest, so just return in error.
256  if ( host == NULL )
257   return NULL;
258
259  hostname = host;
260  c = strstr(host, "<");
261  if ( c != NULL ) {
262   while (c[-1] == ' ') c--;
263   *c = 0;
264   c++;
265   while (*c == ' ' || *c == '<') c++;
266   if ( *c ) {
267    d = strstr(c, ">");
268    if ( d != NULL )
269     *d = 0;
270
271    d = strstr(c, "/");
272    if ( d != NULL ) {
273     *d = '-';
274     hostvendor = c;
275    } else {
276     hostvendor_buffer = roar_mm_malloc(roar_mm_strlen(c) + 1 /* tailing \0 */ + 6 /* "unreg-" */);
277
278     // see above
279     if ( hostvendor_buffer == NULL ) {
280      roar_mm_free(host);
281      return NULL;
282     }
283
284     strcpy(hostvendor_buffer, "unreg-");
285     strcat(hostvendor_buffer, c);
286     hostvendor = hostvendor_buffer;
287    }
288   }
289  }
290 }
291
292 if ( hostvendor == NULL )
293  hostvendor = "universal";
294
295 if ( hostname == NULL )
296  hostname = "universal";
297
298 ret = _load_from_path_pvn(name, flags, ra_init, para, ROAR_PREFIX_PLUGINS, hostvendor, hostname);
299
300 if ( host != NULL )
301  roar_mm_free(host);
302 if ( hostvendor_buffer != NULL )
303  roar_mm_free(hostvendor_buffer);
304 return ret;
305}
306#endif
307
308static struct roar_dl_lhandle * _roar_dl_open_pluginpath(const char * filename, int flags,
309                                      int ra_init, struct roar_dl_librarypara * para) {
310 flags |= ROAR_DL_FLAG_PLUGINPATH;
311 flags -= ROAR_DL_FLAG_PLUGINPATH;
312
313#ifdef ROAR_HAVE_H_DIRENT
314 return _load_from_path(filename, flags, ra_init, para);
315#else
316 // fall back to system open function.
317 return roar_dl_open(filename, flags, ra_init, para);
318#endif
319}
320
321struct roar_dl_lhandle * roar_dl_open(const char * filename, int flags,
322                                      int ra_init, struct roar_dl_librarypara * para) {
323 struct roar_dl_lhandle * ret = NULL;
324#if defined(ROAR_HAVE_LIBDL)
325#ifdef RTLD_DEEPBIND
326 int libdl_flags = RTLD_DEEPBIND;
327#else
328 int libdl_flags = 0;
329#endif
330#endif
331 int err;
332
333 switch (flags) {
334  case ROAR_DL_FLAG_DEFAULTS: flags = ROAR_DL_FLAG_NONE;       break;
335  case ROAR_DL_FLAG_PLUGIN:   flags = ROAR_DL_FLAG_PLUGINPATH; break;
336 }
337
338 if ( flags & ROAR_DL_FLAG_PLUGINPATH )
339  return _roar_dl_open_pluginpath(filename, flags, ra_init, para);
340
341#if defined(ROAR_HAVE_LIBDL)
342 if ( flags & ROAR_DL_FLAG_LAZY ) {
343  libdl_flags |= RTLD_LAZY;
344 } else {
345  libdl_flags |= RTLD_NOW;
346 }
347#endif
348
349 if ( (ret = roar_mm_malloc(sizeof(struct roar_dl_lhandle))) == NULL )
350  return NULL;
351
352 memset(ret, 0, sizeof(struct roar_dl_lhandle));
353
354 roar_err_initstore(&(ret->context.error_state));
355
356 ret->flags = flags;
357 ret->refc  = 1;
358
359 if ( flags & ROAR_DL_FLAG_STATIC ) {
360  if ( filename == NULL ) {
361   ret->libname = NULL;
362  } else {
363   ret->libname = roar_mm_strdup(filename);
364  }
365 } else {
366#if defined(ROAR_HAVE_LIBDL)
367  ret->handle = dlopen(filename, libdl_flags);
368
369  if ( ret->handle == NULL ) {
370   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));
371   roar_mm_free(ret);
372   return NULL;
373  }
374#else
375  roar_mm_free(ret);
376  roar_err_set(ROAR_ERROR_NOSYS);
377  return NULL;
378#endif
379 }
380
381 ret->para = para;
382
383 if ( ra_init ) {
384  if ( roar_dl_ra_init(ret, NULL, para) == -1 ) {
385   err = roar_error;
386   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));
387#if defined(ROAR_HAVE_LIBDL)
388   if ( ret->handle != NULL )
389    dlclose(ret->handle);
390#endif
391   roar_mm_free(ret);
392   roar_error = err;
393   return NULL;
394  }
395 }
396
397 if ( para != NULL )
398  roar_dl_para_ref(para);
399
400 return ret;
401}
402
403int                      roar_dl_ref    (struct roar_dl_lhandle * lhandle) {
404 if ( (void*)lhandle < (void*)128 ) {
405  roar_err_set(ROAR_ERROR_BADFH);
406  return -1;
407 }
408
409 lhandle->refc++;
410
411 return 0;
412}
413
414int                      roar_dl_unref  (struct roar_dl_lhandle * lhandle) {
415 int ret = -1;
416
417 if ( (void*)lhandle < (void*)128 ) {
418  roar_err_set(ROAR_ERROR_BADFH);
419  return -1;
420 }
421
422 lhandle->refc++;
423
424 if ( lhandle->refc )
425  return 0;
426
427 if ( lhandle->lib != NULL && lhandle->lib->unload != NULL ) {
428  roar_dl_context_restore(lhandle);
429  lhandle->lib->unload(lhandle->para, lhandle->lib);
430  roar_dl_context_store(lhandle);
431 }
432
433#if defined(ROAR_HAVE_LIBDL)
434 if ( lhandle->handle == NULL ) {
435  ret = 0;
436 } else {
437  ret = dlclose(_roardl2ldl(lhandle));
438 }
439#else
440 ret = -1;
441#endif
442
443 if ( lhandle->context.global_data != NULL )
444  roar_mm_free(lhandle->context.global_data);
445
446 if ( lhandle->para != NULL )
447  roar_dl_para_unref(lhandle->para);
448
449 if ( lhandle->libname != NULL )
450  roar_mm_free(lhandle->libname);
451
452 roar_mm_free(lhandle);
453
454 return ret;
455}
456
457void                   * roar_dl_getsym(struct roar_dl_lhandle * lhandle, const char * sym, int type) {
458#if defined(ROAR_HAVE_LIBDL)
459 void * ret = dlsym(_roardl2ldl(lhandle), sym);
460
461 (void)type;
462
463 ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i): errno=%s, dlerror()='%s'", lhandle, sym, type, ret, strerror(errno), dlerror());
464 ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = %p", lhandle, sym, type, ret);
465
466 return ret;
467#else
468 ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = NULL // errno=NOSYS", lhandle, sym, type, ret);
469 roar_err_set(ROAR_ERROR_NOSYS);
470 return NULL;
471#endif
472}
473
474int                      roar_dl_ra_init(struct roar_dl_lhandle * lhandle,
475                                         const char * prefix,
476                                         struct roar_dl_librarypara * para) {
477#define _SUFFIX "_roaraudio_library_init"
478 char name[80] = _SUFFIX;
479 struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
480 struct roar_dl_libraryinst * lib;
481 struct roar_dl_lhandle     * getsymhandle = lhandle;
482 void * global_data_state = NULL;
483 int i;
484
485 if ( (void*)lhandle < (void*)128 ) {
486  if ( prefix == NULL )
487   return -1;
488 } else {
489  if ( prefix == NULL )
490   prefix = lhandle->libname;
491
492  if ( para == NULL )
493   para = lhandle->para;
494
495  if ( lhandle->flags & ROAR_DL_FLAG_STATIC )
496   getsymhandle = ROAR_DL_HANDLE_DEFAULT;
497 }
498
499
500 if ( prefix != NULL ) {
501  roar_mm_strscpy(name, "_");
502  roar_mm_strscat(name, prefix);
503  roar_mm_strscat(name, _SUFFIX);
504 }
505
506 ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): name='%s'", lhandle, prefix, name);
507
508 if ( (func = roar_dl_getsym(getsymhandle, name, -1)) == NULL ) {
509  ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s') = -1", lhandle, prefix);
510  return -1;
511 }
512
513 ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): func=%p", lhandle, prefix, func);
514
515 lib = func(para);
516
517 if ( lib == NULL )
518  return -1;
519
520 if ( lib->version != ROAR_DL_LIBINST_VERSION )
521  return -1;
522
523 if ( sizeof(struct roar_dl_libraryinst) > lib->len )
524  return -1;
525
526 if ( lib->host_appname != NULL || lib->host_abiversion != NULL ) {
527  // check for correct host.
528  if ( para == NULL ) {
529   roar_err_set(ROAR_ERROR_INVAL);
530   return -1;
531  }
532  if ( roar_dl_para_check_version(para, lib->host_appname, lib->host_abiversion) == -1 )
533   return -1;
534 }
535
536 if ( (lib->libdep == NULL && lib->libdep_len) || (lib->libdep != NULL && !lib->libdep_len) ) {
537  roar_err_set(ROAR_ERROR_BADLIB);
538  return -1;
539 }
540
541 if ( lib->libdep != NULL && lib->libdep_len ) {
542  // dynamic loader infos are currently not supported.
543  roar_err_set(ROAR_ERROR_NOTSUP);
544  return -1;
545 }
546
547 if ( !((void*)lhandle < (void*)128) ) {
548  lhandle->lib = lib;
549
550  if ( lib->global_data_len ) {
551   lhandle->context.global_data = roar_mm_malloc(lib->global_data_len);
552   if ( lhandle->context.global_data == NULL )
553    return -1;
554
555   if ( lib->global_data_init == NULL ) {
556    memset(lhandle->context.global_data, 0, lib->global_data_len);
557   } else {
558    memcpy(lhandle->context.global_data, lib->global_data_init, lib->global_data_len);
559   }
560  }
561 }
562
563 if ( lib->global_data_pointer != NULL ) {
564  global_data_state = *(lib->global_data_pointer);
565  if ( (void*)lhandle < (void*)128 ) {
566   *(lib->global_data_pointer) = lib->global_data_init;
567  } else {
568   *(lib->global_data_pointer) = lhandle->context.global_data;
569  }
570 }
571
572 for (i = 0; i < ROAR_DL_FN_MAX; i++) {
573  if ( lib->func[i] != NULL )
574   lib->func[i](para, lib);
575 }
576
577 if ( lib->global_data_pointer != NULL ) {
578  if ( !((void*)lhandle < (void*)128) ) {
579   *(lib->global_data_pointer) = global_data_state;
580  }
581 }
582
583 return 0;
584}
585
586const char * roar_dl_errstr(struct roar_dl_lhandle * lhandle) {
587#if defined(ROAR_HAVE_LIBDL)
588 (void)lhandle;
589 return dlerror();
590#else
591 return NULL;
592#endif
593}
594
595struct roar_dl_librarypara       * roar_dl_getpara(struct roar_dl_lhandle * lhandle) {
596 if ( (void*)lhandle < (void*)128 ) {
597  roar_err_set(ROAR_ERROR_NOTSUP);
598  return NULL;
599 }
600
601 if ( lhandle->para == NULL ) {
602  roar_err_set(ROAR_ERROR_NOENT);
603  return NULL;
604 }
605
606 if ( roar_dl_para_ref(lhandle->para) == -1 )
607  return NULL;
608
609 return lhandle->para;
610}
611
612const struct roar_dl_libraryname * roar_dl_getlibname(struct roar_dl_lhandle * lhandle) {
613 if ( (void*)lhandle < (void*)128 ) {
614  roar_err_set(ROAR_ERROR_NOTSUP);
615  return NULL;
616 }
617
618 if ( lhandle->lib == NULL ) {
619  roar_err_set(ROAR_ERROR_BADLIB);
620  return NULL;
621 }
622
623 if ( lhandle->lib->libname == NULL ) {
624  roar_err_set(ROAR_ERROR_NOENT);
625  return NULL;
626 }
627
628 if ( lhandle->lib->libname->version != ROAR_DL_LIBNAME_VERSION ) {
629  roar_err_set(ROAR_ERROR_BADVERSION);
630  return NULL;
631 }
632
633 if ( lhandle->lib->libname->len != sizeof(struct roar_dl_libraryname) ) {
634  roar_err_set(ROAR_ERROR_HOLE);
635  return NULL;
636 }
637
638 return lhandle->lib->libname;
639}
640
641int                      roar_dl_context_restore(struct roar_dl_lhandle * lhandle) {
642 struct roar_error_state error_state;
643
644 ROAR_DBG("roar_dl_context_restore(lhandle=%p) = ?", lhandle);
645
646 if ( (void*)lhandle < (void*)128 ) {
647  ROAR_DBG("roar_dl_context_restore(lhandle=%p) = -1 // errno=NOTSUP", lhandle);
648  roar_err_set(ROAR_ERROR_NOTSUP);
649  return -1;
650 }
651
652 roar_err_store(&error_state);
653 roar_err_restore(&(lhandle->context.error_state));
654 lhandle->context.error_state = error_state;
655
656 if ( lhandle->lib->global_data_pointer != NULL ) {
657  ROAR_DBG("roar_dl_context_restore(lhandle=%p): gptr(%p): %p -> %p", lhandle,
658           lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data);
659  lhandle->context.global_data_state = *(lhandle->lib->global_data_pointer);
660  *(lhandle->lib->global_data_pointer) = lhandle->context.global_data;
661 }
662
663 if ( lhandle->para->notifycore != NULL )
664  lhandle->context.notifycore = roar_notify_core_swap_global(lhandle->para->notifycore);
665
666 ROAR_DBG("roar_dl_context_restore(lhandle=%p) = 0", lhandle);
667 return 0;
668}
669
670int                      roar_dl_context_store(struct roar_dl_lhandle * lhandle) {
671 struct roar_error_state error_state;
672
673 ROAR_DBG("roar_dl_context_store(lhandle=%p) = ?", lhandle);
674
675 if ( (void*)lhandle < (void*)128 ) {
676  ROAR_DBG("roar_dl_context_store(lhandle=%p) = -1 // errno=NOTSUP", lhandle);
677  roar_err_set(ROAR_ERROR_NOTSUP);
678  return -1;
679 }
680
681 if ( lhandle->para->notifycore != NULL ) {
682  roar_notify_core_unref(roar_notify_core_swap_global(lhandle->context.notifycore));
683  roar_notify_core_unref(lhandle->context.notifycore);
684  lhandle->context.notifycore = NULL;
685 }
686
687 if ( lhandle->lib->global_data_pointer != NULL ) {
688  ROAR_DBG("roar_dl_context_store(lhandle=%p): gptr(%p): %p -> %p", lhandle,
689           lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data_state);
690  *(lhandle->lib->global_data_pointer) = lhandle->context.global_data_state;
691 }
692
693 roar_err_store(&error_state);
694 roar_err_restore(&(lhandle->context.error_state));
695 lhandle->context.error_state = error_state;
696
697 ROAR_DBG("roar_dl_context_store(lhandle=%p) = 0", lhandle);
698 return 0;
699}
700
701int                      roar_dl_appsched_trigger(struct roar_dl_lhandle * lhandle, enum roar_dl_appsched_trigger trigger) {
702 int (*func)  (struct roar_dl_librarypara * para) = NULL;
703 int ret;
704
705 if ( (void*)lhandle < (void*)128 ) {
706  roar_err_set(ROAR_ERROR_NOTSUP);
707  return -1;
708 }
709
710 if ( lhandle->lib->appsched == NULL ) {
711  roar_err_set(ROAR_ERROR_NOENT);
712  return -1;
713 }
714
715 switch (trigger) {
716#define _trig(lname,uname) \
717  case ROAR_DL_APPSCHED_ ## uname :             \
718    func = lhandle->lib->appsched->lname;       \
719   break;
720  _trig(init, INIT);
721  _trig(free, FREE);
722  _trig(update, UPDATE);
723  _trig(tick, TICK);
724  _trig(wait, WAIT);
725// use ifndef here so warnings of unhandled enum values will be shown in DEBUG mode.
726#ifndef DEBUG
727  default:
728    roar_err_set(ROAR_ERROR_BADRQC);
729    return -1;
730   break;
731#endif
732 }
733
734 if ( func == NULL ) {
735  roar_err_set(ROAR_ERROR_NOENT);
736  return -1;
737 }
738
739 roar_dl_context_restore(lhandle);
740 ret = func(lhandle->para);
741 roar_dl_context_store(lhandle);
742 return ret;
743}
744
745//ll
Note: See TracBrowser for help on using the repository browser.