Changeset 5567:6ecf012d7063 in roaraudio for roard/clients.c


Ignore:
Timestamp:
07/16/12 17:02:17 (12 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

roard now tries to auto load missing protocols as plugins (Closes: #275)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • roard/clients.c

    r5452 r5567  
    3232// declared 'extern' 
    3333struct roar_client_server * g_clients[ROAR_CLIENTS_MAX]; 
    34 struct roard_proto g_proto[MAX_PROTOS]; 
    35  
    36  
    37 struct roard_proto g_proto[MAX_PROTOS] = { 
    38 #ifndef ROAR_WITHOUT_DCOMP_EMUL_ESD 
    39 #ifdef ROAR_HAVE_H_ESD 
    40  {ROAR_PROTO_ESOUND, ROAR_SUBSYS_WAVEFORM, "EsounD emulation", NULL, NULL, NULL, emul_esd_check_client, NULL, NULL}, 
    41 #endif 
     34 
     35static struct roard_proto_handle __protos[MAX_PROTOS] = { 
     36 {.proto = ROAR_PROTO_ROARAUDIO, .lhandle = NULL, .type = ROARD_PROTO_TYPE_BUILDIN, 
     37 .impl = {.buildin = 0}}, 
     38#if !defined(ROAR_WITHOUT_DCOMP_EMUL_ESD) && defined(ROAR_HAVE_H_ESD) 
     39 {.proto = ROAR_PROTO_ESOUND, .lhandle = NULL, .type = ROARD_PROTO_TYPE_ROARDPROTO, 
     40 .impl = {.roardproto = {ROAR_PROTO_ESOUND, ROAR_SUBSYS_WAVEFORM, "EsounD emulation", NULL, NULL, NULL, emul_esd_check_client, NULL, NULL}}}, 
    4241#endif 
    4342#ifndef ROAR_WITHOUT_DCOMP_EMUL_RPLAY 
    44  {ROAR_PROTO_RPLAY, ROAR_SUBSYS_WAVEFORM, "RPlay emulation", NULL, NULL, NULL, emul_rplay_check_client, NULL, NULL}, 
     43 {.proto = ROAR_PROTO_RPLAY, .lhandle = NULL, .type = ROARD_PROTO_TYPE_ROARDPROTO, 
     44 .impl = {.roardproto = {ROAR_PROTO_RPLAY, ROAR_SUBSYS_WAVEFORM, "RPlay emulation", NULL, NULL, NULL, emul_rplay_check_client, NULL, NULL}}}, 
    4545#endif 
    4646#ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER 
    47  {ROAR_PROTO_GOPHER, ROAR_SUBSYS_WAVEFORM, "The Internet Gopher Protocol", NULL, NULL, NULL, emul_gopher_check_client, NULL, emul_gopher_flushed_client}, 
    48 #endif 
    49  {-1, 0, NULL, NULL, NULL, NULL, NULL, NULL} 
     47 {.proto = ROAR_PROTO_GOPHER, .lhandle = NULL, .type = ROARD_PROTO_TYPE_ROARDPROTO, 
     48 .impl = {.roardproto = {ROAR_PROTO_GOPHER, ROAR_SUBSYS_WAVEFORM, "The Internet Gopher Protocol", NULL, NULL, NULL, emul_gopher_check_client, NULL, 
     49 emul_gopher_flushed_client}}}, 
     50#endif 
     51 {.proto = -1} 
    5052}; 
    5153 
     
    5961  g_clients[i] = NULL; 
    6062 
    61  for (i = 0; g_proto[i].proto != -1; i++); 
     63 for (i = 0; __protos[i].proto != -1; i++); 
    6264 
    6365 for (; i < MAX_PROTOS; i++) 
    64   g_proto[i].proto = -1; 
     66  __protos[i].proto = -1; 
    6567 
    6668 return 0; 
     
    164166int clients_delete (int id) { 
    165167 struct roar_client_server * cs; 
     168 const struct roard_proto_handle * proto; 
    166169 int i; 
    167170 int close_client_fh = 1; 
     
    173176 cs = g_clients[id]; 
    174177 
    175  for (i = 0; g_proto[i].proto != -1; i++) { 
    176   if ( g_proto[i].proto == ROAR_CLIENT(cs)->proto ) { 
    177    if ( g_proto[i].delete_client != NULL ) { 
    178     g_proto[i].delete_client(id); 
    179    } 
     178 proto = clients_get_protohandle(ROAR_CLIENT(cs)->proto); 
     179 if ( proto != NULL ) { 
     180  switch (proto->type) { 
     181   case ROARD_PROTO_TYPE_BUILDIN: 
     182     /* noop */ 
     183    break; 
     184   case ROARD_PROTO_TYPE_ROARDPROTO: 
     185     if ( proto->impl.roardproto.delete_client != NULL ) 
     186      proto->impl.roardproto.delete_client(id); 
     187    break; 
    180188  } 
    181189 } 
     
    558566 struct roar_vio_calls  vio; 
    559567 struct roar_error_state errstate; 
     568 const struct roard_proto_handle * proto; 
    560569 int command_error; 
    561570 char * data = NULL; 
     
    565574 uint32_t flags[2] = {COMMAND_FLAG_NONE, COMMAND_FLAG_NONE}; 
    566575 uint32_t event; 
    567  size_t i; 
    568576 
    569577 ROAR_DBG("clients_check(id=%i) = ?", id); 
     
    655663  default: 
    656664    rv = -1; 
    657     for (i = 0; g_proto[i].proto != -1; i++) { 
    658      if ( g_proto[i].proto == c->proto ) { 
    659       roar_vio_open_fh_socket(&vio, clients_get_fh(id)); 
    660       if ( g_proto[i].lhandle != NULL ) 
    661        roar_dl_context_restore(g_proto[i].lhandle); 
    662       rv = g_proto[i].check_client(id, &vio); 
    663       if ( g_proto[i].lhandle != NULL ) 
    664        roar_dl_context_store(g_proto[i].lhandle); 
     665    proto = clients_get_protohandle(c->proto); 
     666    if ( proto != NULL ) { 
     667     roar_vio_open_fh_socket(&vio, clients_get_fh(id)); 
     668     if ( proto->lhandle != NULL ) 
     669      roar_dl_context_restore(proto->lhandle); 
     670 
     671     switch (proto->type) { 
     672      case ROARD_PROTO_TYPE_BUILDIN: 
     673        ROAR_WARN("clients_check(id=%i): proto(%i) marked as buildin but isn't. BAD.", id, proto->proto); 
     674       break; 
     675      case ROARD_PROTO_TYPE_ROARDPROTO: 
     676        if ( proto->impl.roardproto.check_client != NULL ) 
     677         rv = proto->impl.roardproto.check_client(id, &vio); 
     678       break; 
    665679     } 
     680 
     681     if ( proto->lhandle != NULL ) 
     682      roar_dl_context_store(proto->lhandle); 
    666683    } 
    667684 } 
     
    675692 
    676693int clients_flush      (int id) { 
    677  struct roar_vio_calls         vio; 
    678  struct roar_client_server   * cs; 
    679  struct roar_client          * c; 
    680  struct roard_proto          * p = NULL; 
    681  size_t i; 
     694 struct roar_vio_calls             vio; 
     695 struct roar_client_server       * cs; 
     696 struct roar_client              * c; 
     697 const struct roard_proto_handle * p; 
    682698 size_t len; 
    683699 ssize_t ret; 
    684700 void * buf; 
     701 int rv; 
    685702 
    686703 _CHECK_CID(id); 
     
    688705 c = ROAR_CLIENT(cs = g_clients[id]); 
    689706 
    690  for (i = 0; g_proto[i].proto != -1; i++) { 
    691   if ( g_proto[i].proto == c->proto ) { 
    692    p = &(g_proto[i]); 
     707 p = clients_get_protohandle(c->proto); 
     708 
     709 if ( p == NULL ) 
     710  return -1; 
     711 
     712 roar_vio_open_fh_socket(&vio, clients_get_fh(id)); 
     713 
     714 switch (p->type) { 
     715  case ROARD_PROTO_TYPE_BUILDIN: 
     716    /* noop */ 
    693717   break; 
    694   } 
    695  } 
    696  
    697  if ( p == NULL ) 
    698   return -1; 
    699  
    700  roar_vio_open_fh_socket(&vio, clients_get_fh(id)); 
    701  
    702  if ( p->flush_client != NULL ) { 
    703   if ( p->lhandle != NULL ) 
    704    roar_dl_context_restore(p->lhandle); 
    705   return p->flush_client(id, &vio); 
    706   if ( p->lhandle != NULL ) 
    707    roar_dl_context_store(p->lhandle); 
     718  case ROARD_PROTO_TYPE_ROARDPROTO: 
     719    if ( p->impl.roardproto.flush_client != NULL ) { 
     720     if ( p->lhandle != NULL ) 
     721      roar_dl_context_restore(p->lhandle); 
     722     rv = p->impl.roardproto.flush_client(id, &vio); 
     723     if ( p->lhandle != NULL ) 
     724      roar_dl_context_store(p->lhandle); 
     725     return rv; 
     726    } 
     727   break; 
    708728 } 
    709729 
     
    734754 
    735755 if ( cs->outbuf == NULL ) { 
    736   if ( p->flushed_client != NULL ) { 
    737    if ( p->lhandle != NULL ) 
    738     roar_dl_context_restore(p->lhandle); 
    739    return p->flushed_client(id, &vio); 
    740    if ( p->lhandle != NULL ) 
    741     roar_dl_context_store(p->lhandle); 
     756  switch (p->type) { 
     757   case ROARD_PROTO_TYPE_BUILDIN: 
     758     /* noop */ 
     759    break; 
     760   case ROARD_PROTO_TYPE_ROARDPROTO: 
     761     if ( p->impl.roardproto.flushed_client != NULL ) { 
     762      if ( p->lhandle != NULL ) 
     763       roar_dl_context_restore(p->lhandle); 
     764      rv = p->impl.roardproto.flushed_client(id, &vio); 
     765      if ( p->lhandle != NULL ) 
     766       roar_dl_context_store(p->lhandle); 
     767      return rv; 
     768     } 
     769    break; 
    742770  } 
    743771 } 
     
    836864 
    837865// proto support 
     866const struct roard_proto_handle * clients_get_protohandle(const int proto) { 
     867 size_t i; 
     868 
     869 if ( proto < 0 ) { 
     870  roar_err_set(ROAR_ERROR_INVAL); 
     871  return NULL; 
     872 } 
     873 
     874 for (i = 0; i < (sizeof(__protos)/sizeof(*__protos)); i++) 
     875  if ( __protos[i].proto == proto ) 
     876   return &(__protos[i]); 
     877 
     878 roar_err_set(ROAR_ERROR_NOENT); 
     879 return NULL; 
     880} 
     881 
    838882int clients_register_proto(struct roard_proto * proto, struct roar_dl_lhandle * lhandle) { 
    839  const size_t len = sizeof(g_proto)/sizeof(*g_proto); 
     883 const size_t len = sizeof(__protos)/sizeof(*__protos); 
    840884 size_t i; 
    841885 
     
    843887  return -1; 
    844888 
    845  for (i = 0; g_proto[i].proto != -1; i++); 
     889 for (i = 0; __protos[i].proto != -1; i++); 
    846890 
    847891 // i is now at pos of current EOS entry. 
     
    851895  return -1; 
    852896 
    853  memcpy(&(g_proto[i]), proto, sizeof(*g_proto)); 
    854  
    855  g_proto[i].lhandle = lhandle; 
     897 memcpy(&(__protos[i].impl.roardproto), proto, sizeof(__protos[i].impl.roardproto)); 
     898 
     899 __protos[i].impl.roardproto.lhandle = lhandle; 
     900 
     901 __protos[i].proto   = proto->proto; 
     902 __protos[i].type    = ROARD_PROTO_TYPE_ROARDPROTO; 
     903 __protos[i].lhandle = lhandle; 
    856904 
    857905 return 0; 
     
    859907 
    860908int clients_unregister_proto(int proto) { 
    861  const size_t len = sizeof(g_proto)/sizeof(*g_proto); 
    862909 size_t i; 
    863910 
     
    867914 } 
    868915 
    869  for (i = 0; i < len; i++) { 
    870   if ( g_proto[i].proto == proto ) { 
    871    memset(&(g_proto[i]), 0, sizeof(*g_proto)); 
    872    g_proto[i].proto = -1; 
     916 for (i = 0; i < (sizeof(__protos)/sizeof(*__protos)); i++) { 
     917  if ( __protos[i].proto == proto ) { 
     918   memset(&(__protos[i]), 0, sizeof(*__protos)); 
     919   __protos[i].proto = -1; 
    873920   return 0; 
    874921  } 
     
    880927 
    881928void print_protolist        (enum output_format format) { 
    882  const size_t len = sizeof(g_proto)/sizeof(*g_proto); 
    883  struct roard_proto * p; 
     929 struct roard_proto_handle * p; 
    884930 char subsys[7] = "      "; 
     931 const char * description; 
    885932 size_t i; 
    886933 
     
    922969 } 
    923970 
    924  for (i = 0; i < len; i++) { 
    925   p = &(g_proto[i]); 
     971 for (i = 0; i < (sizeof(__protos)/sizeof(*__protos)); i++) { 
     972  p = &(__protos[i]); 
    926973  if ( p->proto == -1 ) 
    927974   continue; 
    928975 
    929976  strncpy(subsys, "      ", 6); 
    930  
    931   if ( p->subsystems & ROAR_SUBSYS_WAVEFORM ) 
    932    subsys[0] = 'W'; 
    933   if ( p->subsystems & ROAR_SUBSYS_MIDI ) 
    934    subsys[1] = 'M'; 
    935   if ( p->subsystems & ROAR_SUBSYS_CB ) 
    936    subsys[2] = 'C'; 
    937   if ( p->subsystems & ROAR_SUBSYS_LIGHT ) 
    938    subsys[3] = 'L'; 
    939   if ( p->subsystems & ROAR_SUBSYS_RAW ) 
    940    subsys[4] = 'R'; 
    941   if ( p->subsystems & ROAR_SUBSYS_COMPLEX ) 
    942    subsys[5] = 'X'; 
     977  description = "(none)"; 
     978 
     979  if ( p->type == ROARD_PROTO_TYPE_ROARDPROTO ) { 
     980   if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_WAVEFORM ) 
     981    subsys[0] = 'W'; 
     982   if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_MIDI ) 
     983    subsys[1] = 'M'; 
     984   if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_CB ) 
     985    subsys[2] = 'C'; 
     986   if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_LIGHT ) 
     987    subsys[3] = 'L'; 
     988   if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_RAW ) 
     989    subsys[4] = 'R'; 
     990   if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_COMPLEX ) 
     991    subsys[5] = 'X'; 
     992 
     993   description = p->impl.roardproto.description; 
     994  } 
    943995 
    944996  switch (format) { 
    945997   case FORMAT_NATIVE: 
    946      printf("  %-13s %s - %s\n", roar_proto2str(p->proto), subsys, p->description); 
     998     printf("  %-13s %s - %s\n", roar_proto2str(p->proto), subsys, description); 
    947999    break; 
    9481000   case FORMAT_WIKI: 
    949      printf("||%s || ||%s ||%s ||\n", roar_proto2str(p->proto), subsys, p->description); 
     1001     printf("||%s || ||%s ||%s ||\n", roar_proto2str(p->proto), subsys, description); 
    9501002    break; 
    9511003   case FORMAT_CSV: 
    952      printf("%s,,%s,%s\n", roar_proto2str(p->proto), subsys, p->description); 
     1004     printf("%s,,%s,%s\n", roar_proto2str(p->proto), subsys, description); 
    9531005    break; 
    9541006  } 
Note: See TracChangeset for help on using the changeset viewer.