Diff for /libaitrpc/src/lists.c between versions 1.8 and 1.16

version 1.8, 2012/03/29 01:34:16 version 1.16, 2014/01/28 14:05:43
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012Copyright 2004 - 2014
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 47  SUCH DAMAGE. Line 47  SUCH DAMAGE.
   
   
 /*  /*
  * rpc_srv_allocVars() - Allocate array for call variables  
  *  
  * @call = RPC function call  
  * @varnum = Number of variables, if ==0 return already allocated variables number  
  * return: -1 error, !=-1 return varnum value  
  */  
 static inline int  
 rpc_srv_allocVars(rpc_func_t * __restrict call, int varnum)  
 {  
         if (!call || varnum < 0) {  
                 rpc_SetErr(EINVAL, "Invalid parameter can`t allocate variables for RPC call");  
                 return -1;  
         }  
   
         if (varnum) {  
                 call->func_vars = io_allocVars(varnum);  
                 if (!call->func_vars)  
                         return -1;  
         }  
   
         return io_arraySize(call->func_vars);  
 }  
   
 /*  
  * rpc_srv_getVars() - Get variables array for RPC call  
  *  
  * @call = RPC function call  
  * @vars = Returned variables array, may be NULL  
  * return: -1 error, !=-1 Number of returned variables  
  */  
 inline int  
 rpc_srv_getVars(rpc_func_t * __restrict call, array_t ** __restrict vars)  
 {  
         if (!call) {  
                 rpc_SetErr(EINVAL, "Invalid parameter can`t get variables");  
                 return -1;  
         }  
   
         if (vars)  
                 *vars = call->func_vars;  
         return io_arraySize(call->func_vars);  
 }  
   
 /* --------------------------------------------------------- */  
   
 /*  
  * rpc_srv_registerCall() - Register call to RPC server   * rpc_srv_registerCall() - Register call to RPC server
  *   *
  * @srv = RPC Server instance   * @srv = RPC Server instance
 * @csModule = Module name, if NULL self binary * @tag = Function tag
 * @csFunc = Function name * @funcaddr = Function address
 * @args = Number of return function arguments, use for restriction case! * return: -1 error, 0 already registered tag or 1 register ok
 * return: -1 error or 0 register ok 
  */   */
 int  int
rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, rpc_srv_registerCall(rpc_srv_t * __restrict srv, u_short tag, void *funcaddr)
                const char *csFunc, u_short args) 
 {  {
         rpc_func_t *func;          rpc_func_t *func;
   
        if (!srv || !csFunc) {        if (!srv || !funcaddr) {
                 rpc_SetErr(EINVAL, "Invalid parameter can`t register function");                  rpc_SetErr(EINVAL, "Invalid parameter can`t register function");
                 return -1;                  return -1;
         }          }
        if (!(func = malloc(sizeof(rpc_func_t)))) {
         if (!(func = e_malloc(sizeof(rpc_func_t)))) {
                 LOGERR;                  LOGERR;
                 return -1;                  return -1;
        } else        } else {
                 memset(func, 0, sizeof(rpc_func_t));                  memset(func, 0, sizeof(rpc_func_t));
                   AIT_KEY(&func->func_name) = tag;
           }
   
        /* calculate hashes */        /* search for duplicate */
        if (rpc_calcHashes(func, csModule, csFunc) == -1) {        if (AVL_FIND(tagRPCFuncs, &srv->srv_funcs, func)) {
                AIT_FREE_VAL(&func->func_name);                e_free(func);
                AIT_FREE_VAL(&func->func_file);                return 0;
                free(func); 
                return -1; 
         }          }
   
         func->func_parent = srv;          func->func_parent = srv;
           AIT_SET_PTR(&func->func_name, funcaddr, 0);
   
         /* allocate return variables */  
         if (args > 0 && rpc_srv_allocVars(func, args) == -1) {  
                 AIT_FREE_VAL(&func->func_name);  
                 AIT_FREE_VAL(&func->func_file);  
                 free(func);  
                 return -1;  
         }  
   
         /* add to list of functions */          /* add to list of functions */
        pthread_mutex_lock(&srv->srv_mtx);        RPC_FUNCS_LOCK(&srv->srv_funcs);
        func->func_next = srv->srv_funcs;        SLIST_INSERT_HEAD(&srv->srv_funcs, func, func_next);
        srv->srv_funcs = func;        AVL_INSERT(tagRPCFuncs, &srv->srv_funcs, func);
        pthread_mutex_unlock(&srv->srv_mtx);        RPC_FUNCS_UNLOCK(&srv->srv_funcs);
        return 0;        return 1;
 }  }
   
 /*  /*
  * rpc_srv_unregisterCall() - Unregister call from RPC server   * rpc_srv_unregisterCall() - Unregister call from RPC server
  *   *
  * @srv = RPC Server instance   * @srv = RPC Server instance
 * @csModule = Module name, if NULL self binary * @tag = Function tag
 * @csFunc = Function name 
  * return: -1 error, 0 not found call, 1 unregister ok   * return: -1 error, 0 not found call, 1 unregister ok
  */   */
 int  int
rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, u_short tag)
 {  {
        rpc_func_t func, *f, *curr;        rpc_func_t *f;
   
        if (!srv || !csFunc) {        if (!srv) {
                 rpc_SetErr(EINVAL, "Invalid parameter can`t unregister function");                  rpc_SetErr(EINVAL, "Invalid parameter can`t unregister function");
                 return -1;                  return -1;
        } else        }
                memset(&func, 0, sizeof func); 
   
        /* calculate hashes */        f = rpc_srv_getCall(srv, tag);
        if (rpc_calcHashes(&func, csModule, csFunc) == -1)        if (!f)                 /* not found element for unregister */
                return -1; 
 
        pthread_mutex_lock(&srv->srv_mtx); 
        f = rpc_srv_getCall(srv, func.func_tag, func.func_hash); 
        AIT_FREE_VAL(&func.func_name); 
        AIT_FREE_VAL(&func.func_file); 
        if (!f) {                       /* not found element for unregister */ 
                pthread_mutex_unlock(&srv->srv_mtx); 
                 return 0;                  return 0;
         }  
   
        /* remove from list of functions */        RPC_FUNCS_LOCK(&srv->srv_funcs);
        if (srv->srv_funcs == f)   /* if is 1st element */        AVL_REMOVE(tagRPCFuncs, &srv->srv_funcs, f);
                srv->srv_funcs = srv->srv_funcs->func_next;        SLIST_REMOVE(&srv->srv_funcs, f, tagRPCFunc, func_next);
        else {        RPC_FUNCS_UNLOCK(&srv->srv_funcs);
                for (curr = srv->srv_funcs; curr->func_next != f; curr = curr->func_next); 
                curr->func_next = curr->func_next->func_next; 
        } 
        io_freeVars(&f->func_vars); 
        AIT_FREE_VAL(&f->func_name); 
        AIT_FREE_VAL(&f->func_file); 
        free(f); 
        pthread_mutex_unlock(&srv->srv_mtx); 
   
           AIT_FREE_VAL(&f->func_name);
           e_free(f);
         return 1;          return 1;
 }  }
   
Line 196  rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, con Line 125  rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, con
  *   *
  * @srv = RPC Server instance   * @srv = RPC Server instance
  * @tag = tag for function   * @tag = tag for function
  * @hash = hash for function  
  * return: NULL not found call, !=NULL return call   * return: NULL not found call, !=NULL return call
  */   */
inline rpc_func_t *rpc_func_t *
rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash)rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag)
 {  {
        rpc_func_t *f;        rpc_func_t tmp;
   
         if (!srv) {          if (!srv) {
                 rpc_SetErr(EINVAL, "Invalid parameter can`t get function");                  rpc_SetErr(EINVAL, "Invalid parameter can`t get function");
                 return NULL;                  return NULL;
         }  
   
         for (f = srv->srv_funcs; f; f = f->func_next)  
                 if (f->func_tag == tag && f->func_hash == hash)  
                         break;  
   
         return f;  
 }  
   
 /*  
  * rpc_srv_getFunc() - Get registered call from RPC server by Name  
  *  
  * @srv = RPC Server instance  
  * @csModule = Module name, if NULL self binary  
  * @csFunc = Function name  
  * return: NULL not found call, !=NULL return call  
  */  
 rpc_func_t *  
 rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)  
 {  
         rpc_func_t func, *f = NULL;  
   
         if (!srv || !csFunc) {  
                 rpc_SetErr(EINVAL, "Invalid parameter can`t get function");  
                 return NULL;  
         } else          } else
                memset(&func, 0, sizeof(rpc_func_t));                memset(&tmp, 0, sizeof tmp);
   
        /* calculate hashes */        AIT_KEY(&tmp.func_name) = tag;
        if (rpc_calcHashes(&func, csModule, csFunc) == -1)        return AVL_FIND(tagRPCFuncs, &srv->srv_funcs, &tmp);
                return NULL; 
 
        f = rpc_srv_getCall(srv, func.func_tag, func.func_hash); 
 
        AIT_FREE_VAL(&func.func_name); 
        AIT_FREE_VAL(&func.func_file); 
        return f; 
 }  }
   
// ---------------------------------------------------------/* --------------------------------------------------------- */
   
 /*  /*
  * rpc_srv_getBLOB() - Get registered BLOB    * rpc_srv_getBLOB() - Get registered BLOB 
Line 255  rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char Line 151  rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char
  * @var = hash for variable   * @var = hash for variable
  * return: NULL not found, !=NULL return blob var   * return: NULL not found, !=NULL return blob var
  */   */
inline rpc_blob_t *rpc_blob_t *
 rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var)  rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var)
 {  {
        rpc_blob_t *b;        rpc_blob_t *b, *tmp;
   
         if (!srv) {          if (!srv) {
                 rpc_SetErr(EINVAL, "Invalid parameter can`t get BLOB variable");                  rpc_SetErr(EINVAL, "Invalid parameter can`t get BLOB variable");
                 return NULL;                  return NULL;
         }          }
   
        for (b = srv->srv_blob.blobs; b; b = b->blob_next) {        TAILQ_FOREACH_SAFE(b, &srv->srv_blob.blobs, blob_node, tmp)
                 if (b->blob_var == var)                  if (b->blob_var == var)
                         break;                          break;
         }  
   
         return b;          return b;
 }  }
Line 278  rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t v Line 173  rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t v
  *   *
  * @srv = RPC Server instance   * @srv = RPC Server instance
  * @len = BLOB length   * @len = BLOB length
    * @tout = BLOB live timeout in seconds
  * return: NULL error or new registered BLOB   * return: NULL error or new registered BLOB
  */   */
 rpc_blob_t *  rpc_blob_t *
rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_t len)rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_t len, int tout)
 {  {
         rpc_blob_t *blob = NULL;          rpc_blob_t *blob = NULL;
   
Line 290  rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_ Line 186  rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_
                 return blob;                  return blob;
         }          }
   
        blob = rpc_srv_blobCreate(srv, len);        blob = rpc_srv_blobCreate(srv, len, tout);
        if (blob) { 
                pthread_mutex_lock(&srv->srv_blob.mtx); 
                blob->blob_next = srv->srv_blob.blobs; 
                srv->srv_blob.blobs = blob; 
                pthread_mutex_unlock(&srv->srv_blob.mtx); 
        } 
   
           TAILQ_INSERT_TAIL(&srv->srv_blob.blobs, blob, blob_node);
   
         return blob;          return blob;
 }  }
   
Line 311  rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_ Line 203  rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_
 int  int
 rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uint32_t var)  rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uint32_t var)
 {  {
        rpc_blob_t *b, *curr;        rpc_blob_t *b;
   
         if (!srv) {          if (!srv) {
                 rpc_SetErr(EINVAL, "Invalid parameter can`t unregister BLOB variable");                  rpc_SetErr(EINVAL, "Invalid parameter can`t unregister BLOB variable");
Line 321  rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uin Line 213  rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uin
         b = rpc_srv_getBLOB(srv, var);          b = rpc_srv_getBLOB(srv, var);
         if (!b)                         /* not found element for unregister */          if (!b)                         /* not found element for unregister */
                 return 0;                  return 0;
         /* if BLOB is unmapped force to unmap object */  
         if (b->blob_data)  
                 rpc_srv_blobUnmap(b);  
   
        pthread_mutex_lock(&srv->srv_blob.mtx);        TAILQ_REMOVE(&srv->srv_blob.blobs, b, blob_node);
        if (srv->srv_blob.blobs == b) { /* if is 1st element */ 
                srv->srv_blob.blobs = srv->srv_blob.blobs->blob_next; 
        } else { 
                for (curr = srv->srv_blob.blobs; curr->blob_next != b; curr = curr->blob_next); 
                curr->blob_next = curr->blob_next->blob_next; 
        } 
        pthread_mutex_unlock(&srv->srv_blob.mtx); 
        rpc_srv_blobFree(srv, b); 
        free(b); 
   
           rpc_srv_blobFree(srv, b);
           e_free(b);
         return 1;          return 1;
 }  }
   
 /*  
  * rpc_calcHashes() - Calculate hashes for RPC call  
  *  
  * @func = function  
  * @csModule = Module name, if NULL self binary  
  * @csFunc = Function name  
  * return: -1 error or 0 ok  
  */  
 int  
 rpc_calcHashes(rpc_func_t * __restrict func, const char *csModule, const char *csFunc)  
 {  
         char *str = NULL;  
         int len = 0;  
   
         assert(func && csFunc);  
   
         /* set function name */  
         AIT_SET_STR(&func->func_name, csFunc);  
         len = strlen(csFunc) + 3;       /* extra 3 bytes, because add string "__" and 0 */  
         /* set module name if exists */  
         if (csModule) {  
                 AIT_SET_STR(&func->func_file, csModule);  
                 len += strlen(csModule);  
         }  
         /* align len to 2 */  
         len = io_align(len, 1);  
   
         /* prepare hash source string */  
         str = malloc(len);  
         if (!str) {  
                 LOGERR;  
                 return -1;  
         } else {  
                 memset(str, 0, len);  
                 if (csModule)  
                         strlcpy((char*) str, csModule, len);  
                 strlcat((char*) str, "__", len);  
                 strlcat((char*) str, csFunc, len);  
         }  
   
         func->func_tag = crcFletcher16((u_short*) str, len / 2);  
         func->func_hash = hash_fnv((char*) str, len);  
   
         free(str);  
         return len;  
 }  
   

Removed from v.1.8  
changed lines
  Added in v.1.16


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>