Changeset 5511:e2207bedaf0e in roaraudio for libroar


Ignore:
Timestamp:
05/28/12 12:25:20 (12 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

Added a way to register plugin parts with a universal API (Closes: #245)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libroar/roardl.c

    r5503 r5511  
    6868}; 
    6969 
     70// TODO: this should be removed on next SONAME change. 
     71static struct roar_dl_lhandle * __currently_inited = NULL; 
    7072 
    7173struct roar_dl_librarypara * roar_dl_para_new(const char * args, void * binargv, 
     
    193195 ROAR_DBG("_roardl2ldl(lhandle=%p) = ?", lhandle); 
    194196 
    195  if ( lhandle == ROAR_DL_HANDLE_DEFAULT ) { 
    196   ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_DEFAULT); 
    197   return RTLD_DEFAULT; 
    198  } 
    199  
    200  if ( lhandle == ROAR_DL_HANDLE_NEXT ) { 
    201   ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_NEXT); 
    202   return RTLD_NEXT; 
     197 if ( (void*)lhandle < (void*)128 ) { 
     198  switch ((int)(void*)lhandle) { 
     199   case (int)(void*)ROAR_DL_HANDLE_DEFAULT: 
     200   case (int)(void*)ROAR_DL_HANDLE_LIBROAR: 
     201   case (int)(void*)ROAR_DL_HANDLE_APPLICATION: 
     202     ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_DEFAULT); 
     203     return RTLD_DEFAULT; 
     204    break; 
     205   case (int)(void*)ROAR_DL_HANDLE_NEXT: 
     206     ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_NEXT); 
     207     return RTLD_NEXT; 
     208    break; 
     209  } 
    203210 } 
    204211 
     
    464471 } 
    465472 
     473 roar_dl_unregister_fn(lhandle); 
     474 
    466475 if ( lhandle->lib != NULL && lhandle->lib->unload != NULL ) { 
    467476  roar_dl_context_restore(lhandle); 
     
    528537                                         const char * prefix, 
    529538                                         struct roar_dl_librarypara * para) { 
     539 struct roar_dl_lhandle * old_init; 
    530540#define _SUFFIX "_roaraudio_library_init" 
    531541 char name[80] = _SUFFIX; 
     
    626636 } 
    627637 
     638 old_init = __currently_inited; 
     639 __currently_inited = lhandle; 
    628640 for (i = 0; i < ROAR_DL_FN_MAX; i++) { 
    629641  if ( lib->func[i] != NULL ) 
    630642   lib->func[i](para, lib); 
    631643 } 
     644 __currently_inited = old_init; 
     645 
    632646 
    633647 if ( lib->global_data_pointer != NULL ) { 
     
    838852} 
    839853 
     854 
     855#define __MAX_FNREGS 24 
     856static struct __fnregs { 
     857 struct roar_dl_lhandle * lhandle; 
     858 int subtype; 
     859 const void * object; 
     860 size_t objectlen; 
     861 int version; 
     862 int options; 
     863} __fnrefs[ROAR_DL_FN_MAX][__MAX_FNREGS]; 
     864 
     865static int  __fnreg_check_trigger(const struct __fnregs * handle) { 
     866 if ( handle->subtype != ROAR_DL_FNREG_SUBTYPE ) 
     867  return -1; 
     868 if ( handle->version != ROAR_DL_FNREG_VERSION ) 
     869  return -1; 
     870 if ( handle->objectlen != ROAR_DL_FNREG_SIZE ) 
     871  return -1; 
     872 
     873 return 0; 
     874} 
     875 
     876static void __fnreg_trigger_if_match(const struct roar_dl_fnreg * callback, 
     877                                     const struct __fnregs * reg, 
     878                                     int fn, 
     879                                     enum roar_dl_fnreg_action action) { 
     880 if ( callback->fn != -1 && callback->fn != fn ) 
     881  return; 
     882 if ( callback->subtype != -1 && callback->subtype != reg->subtype ) 
     883  return; 
     884 if ( callback->version != -1 && callback->version != reg->version ) 
     885  return; 
     886 
     887 if ( callback->callback == NULL ) 
     888  return; 
     889 
     890 callback->callback(action, fn, reg->subtype, reg->object, reg->objectlen, reg->version, reg->options, callback->userdata, reg->lhandle); 
     891} 
     892 
     893static void __fnreg_trigger_by_reg(const struct __fnregs * reg, enum roar_dl_fnreg_action action, int fn) { 
     894 size_t j; 
     895 
     896 for (j = 0; j < __MAX_FNREGS; j++) { 
     897  if ( __fnrefs[ROAR_DL_FN_REGFN][j].lhandle != NULL ) { 
     898   if ( __fnreg_check_trigger(&(__fnrefs[ROAR_DL_FN_REGFN][j])) == -1 ) 
     899    continue; 
     900   __fnreg_trigger_if_match(__fnrefs[ROAR_DL_FN_REGFN][j].object, reg, fn, action); 
     901  } 
     902 } 
     903} 
     904 
     905static void __fnreg_trigger_by_handler(const struct __fnregs * handle, enum roar_dl_fnreg_action action) { 
     906 size_t i, j; 
     907 
     908 if ( __fnreg_check_trigger(handle) == -1 ) 
     909  return; 
     910 
     911 for (i = 0; i < ROAR_DL_FN_MAX; i++) { 
     912  for (j = 0; j < __MAX_FNREGS; j++) { 
     913   if ( __fnrefs[i][j].lhandle != NULL ) { 
     914    __fnreg_trigger_if_match(handle->object, &(__fnrefs[i][j]), i, action); 
     915   } 
     916  } 
     917 } 
     918} 
     919 
     920int roar_dl_register_fn(struct roar_dl_lhandle * lhandle, int fn, int subtype, const void * object, size_t objectlen, int version, int options) { 
     921 struct __fnregs * c = NULL; 
     922 size_t i; 
     923 
     924 if ( lhandle == NULL ) 
     925  lhandle = __currently_inited; 
     926 
     927 if ( lhandle == NULL ) { 
     928  roar_err_set(ROAR_ERROR_FAULT); 
     929  return -1; 
     930 } 
     931 
     932 if ( fn < 0 || fn >= ROAR_DL_FN_MAX ) { 
     933  roar_err_set(ROAR_ERROR_RANGE); 
     934  return -1; 
     935 } 
     936 
     937 if ( object == NULL || objectlen == 0 ) { 
     938  roar_err_set(ROAR_ERROR_INVAL); 
     939  return -1; 
     940 } 
     941 
     942 for (i = 0; i < __MAX_FNREGS; i++) { 
     943  if ( __fnrefs[fn][i].lhandle != NULL ) 
     944   continue; 
     945  c = &(__fnrefs[fn][i]); 
     946  break; 
     947 } 
     948 
     949 if ( c == NULL ) { 
     950  roar_err_set(ROAR_ERROR_NOSPC); 
     951  return -1; 
     952 } 
     953 
     954 c->lhandle   = lhandle; 
     955 c->subtype   = subtype; 
     956 c->object    = object; 
     957 c->objectlen = objectlen; 
     958 c->version   = version; 
     959 
     960 if ( fn == ROAR_DL_FN_REGFN ) { 
     961  __fnreg_trigger_by_handler(c, ROAR_DL_FNREG); 
     962 } else { 
     963  __fnreg_trigger_by_reg(c, ROAR_DL_FNREG, fn); 
     964 } 
     965 
     966 return 0; 
     967} 
     968 
     969int roar_dl_unregister_fn(struct roar_dl_lhandle * lhandle) { 
     970 size_t i, j; 
     971 
     972//} __fnrefs[ROAR_DL_FN_MAX][__MAX_FNREGS]; 
     973 
     974 if ( lhandle == NULL ) { 
     975  roar_err_set(ROAR_ERROR_FAULT); 
     976  return -1; 
     977 } 
     978 
     979 for (i = 0; i < ROAR_DL_FN_MAX; i++) { 
     980  for (j = 0; j < __MAX_FNREGS; j++) { 
     981   if ( __fnrefs[i][j].lhandle == lhandle ) { 
     982    if ( i == ROAR_DL_FN_REGFN ) { 
     983     __fnreg_trigger_by_handler(&(__fnrefs[i][j]), ROAR_DL_FNUNREG); 
     984    } else { 
     985     __fnreg_trigger_by_reg(&(__fnrefs[i][j]), ROAR_DL_FNUNREG, i); 
     986    } 
     987    memset(&(__fnrefs[i][j]), 0, sizeof(__fnrefs[i][j])); 
     988    __fnrefs[i][j].lhandle = NULL; 
     989   } 
     990  } 
     991 } 
     992 
     993 return 0; 
     994} 
     995 
    840996//ll 
Note: See TracChangeset for help on using the changeset viewer.