Changeset 5488:cd3f4f76a154 in roaraudio


Ignore:
Timestamp:
05/04/12 13:12:31 (12 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

Improved plugincontainer (pr1).

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r5484 r5488  
    1212        * Some small, general improvements to roarclients. 
    1313        * Changed roard plugin ABI version to 1.0beta1. 
    14         * Corrected usage of -Wextra (pr0). 
    15         * Updated build options for RAT (pr0). 
    16         * Work around bugs in win32 while using stdvios (pr0). 
    17         * Added support to load plugins on win32 (pr0). 
     14        * Corrected usage of -Wextra (pr1). 
     15        * Updated build options for RAT (pr1). 
     16        * Work around bugs in win32 while using stdvios (pr1). 
     17        * Added support to load plugins on win32 (pr1). 
    1818        * Added support for quotes strings to kv split and 
    19           roardl para argument splitting (pr0). 
    20         * Added support for an application mode in roarpluginrunner (pr0). 
     19          roardl para argument splitting (pr1). 
     20        * Added support for an application mode in roarpluginrunner (pr1). 
     21        * Improved plugincontainer (pr1). 
    2122 
    2223v. 1.0beta0 - Fri Mar 16 2012 19:39 CET 
  • include/libroar/plugincontainer.h

    r5487 r5488  
    4141struct roar_plugincontainer; 
    4242 
     43struct roar_plugincontainer_callbacks { 
     44 /* prefree() is called before the container is freed. 
     45  */ 
     46 int (*prefree)(struct roar_plugincontainer * cont, void ** userdata); 
     47 
     48 /* freeuserdata() is called when the userdata needs to be freed. 
     49  * This is the case then the container is freed. 
     50  * It is not called when the current userdata is NULL. 
     51  * If not set or userdata is still non-NULL after this call the userdata 
     52  * is freed using roar_mm_free(). 
     53  */ 
     54 int (*freeuserdata)(struct roar_plugincontainer * cont, void ** userdata); 
     55 
     56 /* freecontext() is called when the context needs to be freed. 
     57  * It is not called when the current context is NULL. 
     58  * If not set or context is still non-NULL after this call the context 
     59  * is freed using roar_mm_free(). 
     60  */ 
     61 int (*freecontext)(struct roar_plugincontainer * cont, void ** context); 
     62 
     63 /* preload() and postload() are called before and after a plugin is loaded. 
     64  */ 
     65 int (*preload) (struct roar_plugincontainer * cont, void ** context, 
     66                 const char * name, int flags, struct roar_dl_librarypara * para); 
     67 int (*postload)(struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle, 
     68                 const char * name, int flags, struct roar_dl_librarypara * para); 
     69 
     70 /* preunload() and postunload() are called before and after a plugin is unloaded. 
     71  * Those functions are also called if the plugin was loaded but ra_init was not yet done or failed. 
     72  */ 
     73 int (*preunload) (struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle); 
     74 int (*postunload)(struct roar_plugincontainer * cont, void ** context); 
     75 
     76 /* prera_init() and postra_init() are called before and after a plugin is ra_init-ed. 
     77  * This is also true if the plugin is ra_init-ed while being loaded. 
     78  * Note the limits of roar_plugincontainer_ra_init() if this is used 
     79  * with roar_plugincontainer_ra_init(). 
     80  * postra_init() is also called in case the ra_init failed. 
     81  */ 
     82 int (*prera_init) (struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle, 
     83                    struct roar_dl_librarypara * para); 
     84 int (*postra_init)(struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle, 
     85                    struct roar_dl_librarypara * para); 
     86}; 
     87 
     88struct roar_plugincontainer_plugininfo { 
     89 /* The name of the plugin. 
     90  */ 
     91 const char * libname; 
     92 /* The roardl's library handle. 
     93  */ 
     94 struct roar_dl_lhandle * handle; 
     95 /* The number of librarys/plugins depending on this plugin. 
     96  */ 
     97 size_t rdepends; 
     98 /* A pointer to the current user context. 
     99  */ 
     100 void ** context; 
     101}; 
     102 
    43103/* Create a new plugin container. 
    44104 * Takes a default parameter set. 
     
    58118int roar_plugincontainer_unref(struct roar_plugincontainer * cont); 
    59119 
    60 /* Get a lhandle by name of the loaded plugin 
     120/* Set callbacks. 
     121 */ 
     122int roar_plugincontainer_set_callbacks(struct roar_plugincontainer * cont, 
     123                                       const struct roar_plugincontainer_callbacks * callbacks); 
     124 
     125/* Set container's userdata. 
     126 */ 
     127int roar_plugincontainer_set_userdata(struct roar_plugincontainer * cont, void * userdata); 
     128 
     129/* Get container's userdata. 
     130 */ 
     131void * roar_plugincontainer_get_userdata(struct roar_plugincontainer * cont); 
     132 
     133/* Get a lhandle by name of the loaded plugin. 
    61134 */ 
    62135struct roar_dl_lhandle * roar_plugincontainer_get_lhandle_by_name (struct roar_plugincontainer * cont, 
    63136                                                                   const char * name); 
     137 
     138/* Get infos about current state of plugin. 
     139 */ 
     140struct roar_plugincontainer_plugininfo roar_plugincontainer_get_info_by_name (struct roar_plugincontainer * cont, 
     141                                                                              const char * name); 
    64142 
    65143// plugin loading and unloading: 
  • libroar/plugincontainer.c

    r5487 r5488  
    4040struct roar_plugincontainer { 
    4141 size_t refc; 
     42 const struct roar_plugincontainer_callbacks * callbacks; 
     43 void * userdata; 
    4244 struct roar_dl_librarypara * default_para; 
    4345 struct roar_dl_lhandle * handle[MAX_PLUGINS]; 
    4446 size_t deprefc[MAX_PLUGINS]; 
     47 void * context[MAX_PLUGINS]; 
    4548 size_t numhandles; 
    4649}; 
     50 
     51static inline void _unload(struct roar_plugincontainer * cont, size_t index) { 
     52 int err = roar_error; 
     53 
     54 if ( cont->callbacks != NULL && cont->callbacks->preunload != NULL ) 
     55  cont->callbacks->preunload(cont, &(cont->context[index]), cont->handle[index]); 
     56 
     57 roar_err_set(err); 
     58 roar_dl_unref(cont->handle[index]); 
     59 err = roar_error; 
     60 cont->handle[index] = NULL; 
     61 cont->numhandles--; 
     62 
     63 if ( cont->callbacks != NULL && cont->callbacks->postunload != NULL ) 
     64  cont->callbacks->postunload(cont, &(cont->context[index])); 
     65 
     66 if ( cont->context[index] != NULL ) 
     67  if ( cont->callbacks != NULL && cont->callbacks->freecontext != NULL ) 
     68  cont->callbacks->freecontext(cont, &(cont->context[index])); 
     69 
     70 if ( cont->context[index] != NULL ) { 
     71  roar_mm_free(cont->context[index]); 
     72  cont->context[index] = NULL; 
     73 } 
     74 
     75 roar_err_set(err); 
     76} 
    4777 
    4878static int _loader(struct roar_dl_librarypara * lhandle, void * loader_userdata, enum roar_dl_loadercmd cmd, void * argp) { 
     
    209239 } 
    210240 
     241 if ( cont->callbacks != NULL && cont->callbacks->prefree != NULL ) 
     242  cont->callbacks->prefree(cont, &(cont->userdata)); 
     243 
    211244 while (cont->numhandles) { 
    212245  for (i = 0; i < MAX_PLUGINS; i++) { 
     
    218251    continue; 
    219252 
    220    roar_dl_close(cont->handle[i]); 
    221    cont->handle[i] = NULL; 
    222    cont->numhandles--; 
    223   } 
    224  } 
     253   _unload(cont, i); 
     254  } 
     255 } 
     256 
     257 // try to free user data... 
     258 if ( cont->userdata != NULL ) { 
     259  if ( cont->callbacks != NULL && cont->callbacks->freeuserdata != NULL ) { 
     260   cont->callbacks->freeuserdata(cont, &(cont->userdata)); 
     261  } 
     262 } 
     263 
     264 // if still not freed by caller, free it using memmgr. 
     265 if ( cont->userdata != NULL ) 
     266  roar_mm_free(cont->userdata); 
    225267 
    226268 if ( cont->default_para != NULL ) 
     
    233275} 
    234276 
    235 struct roar_dl_lhandle * roar_plugincontainer_get_lhandle_by_name (struct roar_plugincontainer * cont, 
    236                                                                    const char * name) { 
     277int roar_plugincontainer_set_callbacks(struct roar_plugincontainer * cont, 
     278                                       const struct roar_plugincontainer_callbacks * callbacks) { 
     279 if ( cont == NULL ) { 
     280  roar_err_set(ROAR_ERROR_FAULT); 
     281  return -1; 
     282 } 
     283 
     284 cont->callbacks = callbacks; 
     285 
     286 return 0; 
     287} 
     288 
     289int roar_plugincontainer_set_userdata(struct roar_plugincontainer * cont, void * userdata) { 
     290 if ( cont == NULL ) { 
     291  roar_err_set(ROAR_ERROR_FAULT); 
     292  return -1; 
     293 } 
     294 
     295 cont->userdata = userdata; 
     296 
     297 return 0; 
     298} 
     299 
     300void * roar_plugincontainer_get_userdata(struct roar_plugincontainer * cont) { 
     301 if ( cont == NULL ) { 
     302  roar_err_set(ROAR_ERROR_FAULT); 
     303  return NULL; 
     304 } 
     305 
     306 if ( cont->userdata == NULL ) { 
     307  roar_err_set(ROAR_ERROR_NOENT); 
     308  return NULL; 
     309 } 
     310 
     311 return cont->userdata; 
     312} 
     313 
     314struct roar_plugincontainer_plugininfo roar_plugincontainer_get_info_by_name (struct roar_plugincontainer * cont, 
     315                                                                              const char * name) { 
     316 struct roar_plugincontainer_plugininfo ret; 
    237317 const struct roar_dl_libraryname * libname; 
    238318 size_t i; 
    239319 
     320 memset(&ret, 0, sizeof(ret)); 
     321 
    240322 if ( cont == NULL || name == NULL ) { 
    241323  roar_err_set(ROAR_ERROR_FAULT); 
    242   return NULL; 
     324  return ret; 
    243325 } 
    244326 
     
    252334  if ( !strcmp(libname->name, name) ) { 
    253335   if ( roar_dl_ref(cont->handle[i]) == -1 ) 
    254     return NULL; 
    255  
    256    return cont->handle[i]; 
     336    return ret; 
     337 
     338   ret.libname  = libname->name; 
     339   ret.handle   = cont->handle[i]; 
     340   ret.rdepends = cont->deprefc[i]; 
     341   ret.context  = &(cont->context[i]); 
     342   return ret; 
    257343  } 
    258344 } 
    259345 
    260346 roar_err_set(ROAR_ERROR_NOENT); 
    261  return NULL; 
     347 return ret; 
     348} 
     349 
     350struct roar_dl_lhandle * roar_plugincontainer_get_lhandle_by_name (struct roar_plugincontainer * cont, 
     351                                                                   const char * name) { 
     352 struct roar_plugincontainer_plugininfo info = roar_plugincontainer_get_info_by_name(cont, name); 
     353 
     354 if ( info.libname == NULL ) 
     355  return NULL; 
     356 
     357 return info.handle; 
    262358} 
    263359 
     
    316412 } 
    317413 
    318  cont->handle[idx] = roar_dl_open(name, flags, ra_init, para); 
     414 cont->context[idx] = NULL; // clear context. 
     415 cont->deprefc[idx] = 0; 
     416 
     417 if ( cont->callbacks != NULL && cont->callbacks->preload != NULL ) 
     418  cont->callbacks->preload(cont, &(cont->context[idx]), name, flags, para); 
     419 
     420 cont->handle[idx] = roar_dl_open(name, flags, 0, para); 
    319421 if ( cont->handle[idx] == NULL ) { 
    320422  err = roar_error; 
     
    324426 } 
    325427 
    326  cont->deprefc[idx] = 0; 
    327428 cont->numhandles++; 
     429 
     430 if ( cont->callbacks != NULL && cont->callbacks->postload != NULL ) 
     431  cont->callbacks->postload(cont, &(cont->context[idx]), cont->handle[idx], name, flags, para); 
     432 
     433 if ( ra_init ) { 
     434  if ( cont->callbacks != NULL && cont->callbacks->prera_init != NULL ) 
     435   cont->callbacks->prera_init(cont, &(cont->context[idx]), cont->handle[idx], para); 
     436  if ( roar_dl_ra_init(cont->handle[idx], NULL, para) == -1 ) { 
     437   err = roar_error; 
     438 
     439   if ( cont->callbacks != NULL && cont->callbacks->postra_init != NULL ) 
     440    cont->callbacks->postra_init(cont, &(cont->context[idx]), cont->handle[idx], para); 
     441 
     442   _unload(cont, idx); 
     443 
     444   roar_dl_para_unref(para); 
     445   cont->handle[idx] = NULL; 
     446   roar_error = err; 
     447   return NULL; 
     448  } 
     449 
     450  if ( cont->callbacks != NULL && cont->callbacks->postra_init != NULL ) 
     451   cont->callbacks->postra_init(cont, &(cont->context[idx]), cont->handle[idx], para); 
     452 } 
    328453 
    329454 roar_dl_para_unref(para); 
     
    369494    return -1; 
    370495   } 
    371    roar_dl_close(cont->handle[i]); 
    372    cont->handle[i] = NULL; 
    373    cont->numhandles--; 
     496   _unload(cont, i); 
    374497   return 0; 
    375498  } 
     
    391514  if ( cont->handle[i] == NULL ) 
    392515   continue; 
     516 
     517  if ( cont->callbacks != NULL && cont->callbacks->prera_init != NULL ) 
     518   cont->callbacks->prera_init(cont, &(cont->context[i]), cont->handle[i], cont->default_para); 
     519 
    393520  roar_dl_ra_init(cont->handle[i], NULL, cont->default_para); 
     521 
     522  if ( cont->callbacks != NULL && cont->callbacks->postra_init != NULL ) 
     523   cont->callbacks->postra_init(cont, &(cont->context[i]), cont->handle[i], cont->default_para); 
    394524 } 
    395525 
Note: See TracChangeset for help on using the changeset viewer.