source: roaraudio/libroar/roardl.c @ 5430:70a234a359df

Last change on this file since 5430:70a234a359df was 5430:70a234a359df, checked in by phi, 12 years ago

fix loading of plugins with full path name

File size: 19.7 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 // do normal open for everything with a path name.
315 if ( strstr(filename, "/") != NULL )
316  return roar_dl_open(filename, flags, ra_init, para);
317
318 return _load_from_path(filename, flags, ra_init, para);
319#else
320 // fall back to system open function.
321 return roar_dl_open(filename, flags, ra_init, para);
322#endif
323}
324
325struct roar_dl_lhandle * roar_dl_open(const char * filename, int flags,
326                                      int ra_init, struct roar_dl_librarypara * para) {
327 struct roar_dl_lhandle * ret = NULL;
328#if defined(ROAR_HAVE_LIBDL)
329#ifdef RTLD_DEEPBIND
330 int libdl_flags = RTLD_DEEPBIND;
331#else
332 int libdl_flags = 0;
333#endif
334#endif
335 int err;
336
337 switch (flags) {
338  case ROAR_DL_FLAG_DEFAULTS: flags = ROAR_DL_FLAG_NONE;       break;
339  case ROAR_DL_FLAG_PLUGIN:   flags = ROAR_DL_FLAG_PLUGINPATH; break;
340 }
341
342 if ( flags & ROAR_DL_FLAG_PLUGINPATH )
343  return _roar_dl_open_pluginpath(filename, flags, ra_init, para);
344
345#if defined(ROAR_HAVE_LIBDL)
346 if ( flags & ROAR_DL_FLAG_LAZY ) {
347  libdl_flags |= RTLD_LAZY;
348 } else {
349  libdl_flags |= RTLD_NOW;
350 }
351#endif
352
353 if ( (ret = roar_mm_malloc(sizeof(struct roar_dl_lhandle))) == NULL )
354  return NULL;
355
356 memset(ret, 0, sizeof(struct roar_dl_lhandle));
357
358 roar_err_initstore(&(ret->context.error_state));
359
360 ret->flags = flags;
361 ret->refc  = 1;
362
363 if ( flags & ROAR_DL_FLAG_STATIC ) {
364  if ( filename == NULL ) {
365   ret->libname = NULL;
366  } else {
367   ret->libname = roar_mm_strdup(filename);
368  }
369 } else {
370#if defined(ROAR_HAVE_LIBDL)
371  ret->handle = dlopen(filename, libdl_flags);
372
373  if ( ret->handle == NULL ) {
374   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));
375   roar_mm_free(ret);
376   return NULL;
377  }
378#else
379  roar_mm_free(ret);
380  roar_err_set(ROAR_ERROR_NOSYS);
381  return NULL;
382#endif
383 }
384
385 ret->para = para;
386
387 if ( ra_init ) {
388  if ( roar_dl_ra_init(ret, NULL, para) == -1 ) {
389   err = roar_error;
390   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));
391#if defined(ROAR_HAVE_LIBDL)
392   if ( ret->handle != NULL )
393    dlclose(ret->handle);
394#endif
395   roar_mm_free(ret);
396   roar_error = err;
397   return NULL;
398  }
399 }
400
401 if ( para != NULL )
402  roar_dl_para_ref(para);
403
404 return ret;
405}
406
407int                      roar_dl_ref    (struct roar_dl_lhandle * lhandle) {
408 if ( (void*)lhandle < (void*)128 ) {
409  roar_err_set(ROAR_ERROR_BADFH);
410  return -1;
411 }
412
413 lhandle->refc++;
414
415 return 0;
416}
417
418int                      roar_dl_unref  (struct roar_dl_lhandle * lhandle) {
419 int ret = -1;
420
421 if ( (void*)lhandle < (void*)128 ) {
422  roar_err_set(ROAR_ERROR_BADFH);
423  return -1;
424 }
425
426 lhandle->refc++;
427
428 if ( lhandle->refc )
429  return 0;
430
431 if ( lhandle->lib != NULL && lhandle->lib->unload != NULL ) {
432  roar_dl_context_restore(lhandle);
433  lhandle->lib->unload(lhandle->para, lhandle->lib);
434  roar_dl_context_store(lhandle);
435 }
436
437#if defined(ROAR_HAVE_LIBDL)
438 if ( lhandle->handle == NULL ) {
439  ret = 0;
440 } else {
441  ret = dlclose(_roardl2ldl(lhandle));
442 }
443#else
444 ret = -1;
445#endif
446
447 if ( lhandle->context.global_data != NULL )
448  roar_mm_free(lhandle->context.global_data);
449
450 if ( lhandle->para != NULL )
451  roar_dl_para_unref(lhandle->para);
452
453 if ( lhandle->libname != NULL )
454  roar_mm_free(lhandle->libname);
455
456 roar_mm_free(lhandle);
457
458 return ret;
459}
460
461void                   * roar_dl_getsym(struct roar_dl_lhandle * lhandle, const char * sym, int type) {
462#if defined(ROAR_HAVE_LIBDL)
463 void * ret = dlsym(_roardl2ldl(lhandle), sym);
464
465 (void)type;
466
467 ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i): errno=%s, dlerror()='%s'", lhandle, sym, type, ret, strerror(errno), dlerror());
468 ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = %p", lhandle, sym, type, ret);
469
470 return ret;
471#else
472 ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = NULL // errno=NOSYS", lhandle, sym, type, ret);
473 roar_err_set(ROAR_ERROR_NOSYS);
474 return NULL;
475#endif
476}
477
478int                      roar_dl_ra_init(struct roar_dl_lhandle * lhandle,
479                                         const char * prefix,
480                                         struct roar_dl_librarypara * para) {
481#define _SUFFIX "_roaraudio_library_init"
482 char name[80] = _SUFFIX;
483 struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
484 struct roar_dl_libraryinst * lib;
485 struct roar_dl_lhandle     * getsymhandle = lhandle;
486 void * global_data_state = NULL;
487 int i;
488
489 if ( (void*)lhandle < (void*)128 ) {
490  if ( prefix == NULL )
491   return -1;
492 } else {
493  if ( prefix == NULL )
494   prefix = lhandle->libname;
495
496  if ( para == NULL )
497   para = lhandle->para;
498
499  if ( lhandle->flags & ROAR_DL_FLAG_STATIC )
500   getsymhandle = ROAR_DL_HANDLE_DEFAULT;
501 }
502
503
504 if ( prefix != NULL ) {
505  roar_mm_strscpy(name, "_");
506  roar_mm_strscat(name, prefix);
507  roar_mm_strscat(name, _SUFFIX);
508 }
509
510 ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): name='%s'", lhandle, prefix, name);
511
512 if ( (func = roar_dl_getsym(getsymhandle, name, -1)) == NULL ) {
513  ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s') = -1", lhandle, prefix);
514  return -1;
515 }
516
517 ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): func=%p", lhandle, prefix, func);
518
519 lib = func(para);
520
521 if ( lib == NULL )
522  return -1;
523
524 if ( lib->version != ROAR_DL_LIBINST_VERSION )
525  return -1;
526
527 if ( sizeof(struct roar_dl_libraryinst) > lib->len )
528  return -1;
529
530 if ( lib->host_appname != NULL || lib->host_abiversion != NULL ) {
531  // check for correct host.
532  if ( para == NULL ) {
533   roar_err_set(ROAR_ERROR_INVAL);
534   return -1;
535  }
536  if ( roar_dl_para_check_version(para, lib->host_appname, lib->host_abiversion) == -1 )
537   return -1;
538 }
539
540 if ( (lib->libdep == NULL && lib->libdep_len) || (lib->libdep != NULL && !lib->libdep_len) ) {
541  roar_err_set(ROAR_ERROR_BADLIB);
542  return -1;
543 }
544
545 if ( lib->libdep != NULL && lib->libdep_len ) {
546  // dynamic loader infos are currently not supported.
547  roar_err_set(ROAR_ERROR_NOTSUP);
548  return -1;
549 }
550
551 if ( !((void*)lhandle < (void*)128) ) {
552  lhandle->lib = lib;
553
554  if ( lib->global_data_len ) {
555   lhandle->context.global_data = roar_mm_malloc(lib->global_data_len);
556   if ( lhandle->context.global_data == NULL )
557    return -1;
558
559   if ( lib->global_data_init == NULL ) {
560    memset(lhandle->context.global_data, 0, lib->global_data_len);
561   } else {
562    memcpy(lhandle->context.global_data, lib->global_data_init, lib->global_data_len);
563   }
564  }
565 }
566
567 if ( lib->global_data_pointer != NULL ) {
568  global_data_state = *(lib->global_data_pointer);
569  if ( (void*)lhandle < (void*)128 ) {
570   *(lib->global_data_pointer) = lib->global_data_init;
571  } else {
572   *(lib->global_data_pointer) = lhandle->context.global_data;
573  }
574 }
575
576 for (i = 0; i < ROAR_DL_FN_MAX; i++) {
577  if ( lib->func[i] != NULL )
578   lib->func[i](para, lib);
579 }
580
581 if ( lib->global_data_pointer != NULL ) {
582  if ( !((void*)lhandle < (void*)128) ) {
583   *(lib->global_data_pointer) = global_data_state;
584  }
585 }
586
587 return 0;
588}
589
590const char * roar_dl_errstr(struct roar_dl_lhandle * lhandle) {
591#if defined(ROAR_HAVE_LIBDL)
592 (void)lhandle;
593 return dlerror();
594#else
595 return NULL;
596#endif
597}
598
599struct roar_dl_librarypara       * roar_dl_getpara(struct roar_dl_lhandle * lhandle) {
600 if ( (void*)lhandle < (void*)128 ) {
601  roar_err_set(ROAR_ERROR_NOTSUP);
602  return NULL;
603 }
604
605 if ( lhandle->para == NULL ) {
606  roar_err_set(ROAR_ERROR_NOENT);
607  return NULL;
608 }
609
610 if ( roar_dl_para_ref(lhandle->para) == -1 )
611  return NULL;
612
613 return lhandle->para;
614}
615
616const struct roar_dl_libraryname * roar_dl_getlibname(struct roar_dl_lhandle * lhandle) {
617 if ( (void*)lhandle < (void*)128 ) {
618  roar_err_set(ROAR_ERROR_NOTSUP);
619  return NULL;
620 }
621
622 if ( lhandle->lib == NULL ) {
623  roar_err_set(ROAR_ERROR_BADLIB);
624  return NULL;
625 }
626
627 if ( lhandle->lib->libname == NULL ) {
628  roar_err_set(ROAR_ERROR_NOENT);
629  return NULL;
630 }
631
632 if ( lhandle->lib->libname->version != ROAR_DL_LIBNAME_VERSION ) {
633  roar_err_set(ROAR_ERROR_BADVERSION);
634  return NULL;
635 }
636
637 if ( lhandle->lib->libname->len != sizeof(struct roar_dl_libraryname) ) {
638  roar_err_set(ROAR_ERROR_HOLE);
639  return NULL;
640 }
641
642 return lhandle->lib->libname;
643}
644
645int                      roar_dl_context_restore(struct roar_dl_lhandle * lhandle) {
646 struct roar_error_state error_state;
647
648 ROAR_DBG("roar_dl_context_restore(lhandle=%p) = ?", lhandle);
649
650 if ( (void*)lhandle < (void*)128 ) {
651  ROAR_DBG("roar_dl_context_restore(lhandle=%p) = -1 // errno=NOTSUP", lhandle);
652  roar_err_set(ROAR_ERROR_NOTSUP);
653  return -1;
654 }
655
656 roar_err_store(&error_state);
657 roar_err_restore(&(lhandle->context.error_state));
658 lhandle->context.error_state = error_state;
659
660 if ( lhandle->lib->global_data_pointer != NULL ) {
661  ROAR_DBG("roar_dl_context_restore(lhandle=%p): gptr(%p): %p -> %p", lhandle,
662           lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data);
663  lhandle->context.global_data_state = *(lhandle->lib->global_data_pointer);
664  *(lhandle->lib->global_data_pointer) = lhandle->context.global_data;
665 }
666
667 if ( lhandle->para->notifycore != NULL )
668  lhandle->context.notifycore = roar_notify_core_swap_global(lhandle->para->notifycore);
669
670 ROAR_DBG("roar_dl_context_restore(lhandle=%p) = 0", lhandle);
671 return 0;
672}
673
674int                      roar_dl_context_store(struct roar_dl_lhandle * lhandle) {
675 struct roar_error_state error_state;
676
677 ROAR_DBG("roar_dl_context_store(lhandle=%p) = ?", lhandle);
678
679 if ( (void*)lhandle < (void*)128 ) {
680  ROAR_DBG("roar_dl_context_store(lhandle=%p) = -1 // errno=NOTSUP", lhandle);
681  roar_err_set(ROAR_ERROR_NOTSUP);
682  return -1;
683 }
684
685 if ( lhandle->para->notifycore != NULL ) {
686  roar_notify_core_unref(roar_notify_core_swap_global(lhandle->context.notifycore));
687  roar_notify_core_unref(lhandle->context.notifycore);
688  lhandle->context.notifycore = NULL;
689 }
690
691 if ( lhandle->lib->global_data_pointer != NULL ) {
692  ROAR_DBG("roar_dl_context_store(lhandle=%p): gptr(%p): %p -> %p", lhandle,
693           lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data_state);
694  *(lhandle->lib->global_data_pointer) = lhandle->context.global_data_state;
695 }
696
697 roar_err_store(&error_state);
698 roar_err_restore(&(lhandle->context.error_state));
699 lhandle->context.error_state = error_state;
700
701 ROAR_DBG("roar_dl_context_store(lhandle=%p) = 0", lhandle);
702 return 0;
703}
704
705int                      roar_dl_appsched_trigger(struct roar_dl_lhandle * lhandle, enum roar_dl_appsched_trigger trigger) {
706 int (*func)  (struct roar_dl_librarypara * para) = NULL;
707 int ret;
708
709 if ( (void*)lhandle < (void*)128 ) {
710  roar_err_set(ROAR_ERROR_NOTSUP);
711  return -1;
712 }
713
714 if ( lhandle->lib->appsched == NULL ) {
715  roar_err_set(ROAR_ERROR_NOENT);
716  return -1;
717 }
718
719 switch (trigger) {
720#define _trig(lname,uname) \
721  case ROAR_DL_APPSCHED_ ## uname :             \
722    func = lhandle->lib->appsched->lname;       \
723   break;
724  _trig(init, INIT);
725  _trig(free, FREE);
726  _trig(update, UPDATE);
727  _trig(tick, TICK);
728  _trig(wait, WAIT);
729// use ifndef here so warnings of unhandled enum values will be shown in DEBUG mode.
730#ifndef DEBUG
731  default:
732    roar_err_set(ROAR_ERROR_BADRQC);
733    return -1;
734   break;
735#endif
736 }
737
738 if ( func == NULL ) {
739  roar_err_set(ROAR_ERROR_NOENT);
740  return -1;
741 }
742
743 roar_dl_context_restore(lhandle);
744 ret = func(lhandle->para);
745 roar_dl_context_store(lhandle);
746 return ret;
747}
748
749//ll
Note: See TracBrowser for help on using the repository browser.