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

version 1.8, 2012/03/29 01:34:16 version 1.11, 2012/07/22 20:44:13
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;
           } else {
                   /* search for duplicate */
                   TAILQ_FOREACH(func, &srv->srv_funcs, func_node)
                           if (AIT_KEY(&func->func_name) == tag)
                                   return 0;
         }          }
        if (!(func = malloc(sizeof(rpc_func_t)))) {
         if (!(func = io_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));
                func->func_parent = srv;
        /* calculate hashes */ 
        if (rpc_calcHashes(func, csModule, csFunc) == -1) { 
                AIT_FREE_VAL(&func->func_name); 
                AIT_FREE_VAL(&func->func_file); 
                free(func); 
                return -1; 
         }          }
   
        func->func_parent = srv;        AIT_KEY(&func->func_name) = tag;
         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);        TAILQ_INSERT_TAIL(&srv->srv_funcs, func, func_node);
        func->func_next = srv->srv_funcs;        return 1;
        srv->srv_funcs = func; 
        pthread_mutex_unlock(&srv->srv_mtx); 
        return 0; 
 }  }
   
 /*  /*
  * 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 */        TAILQ_REMOVE(&srv->srv_funcs, f, func_node);
        if (srv->srv_funcs == f)   /* if is 1st element */ 
                srv->srv_funcs = srv->srv_funcs->func_next; 
        else { 
                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);
           io_free(f);
         return 1;          return 1;
 }  }
   
Line 196  rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, con Line 118  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 *  inline 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 *f, *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)        TAILQ_FOREACH_SAFE(f, &srv->srv_funcs, func_node, tmp)
                if (f->func_tag == tag && f->func_hash == hash)                if (AIT_KEY(&f->func_name) == tag)
                         break;                          break;
   
         return f;          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  
                 memset(&func, 0, sizeof(rpc_func_t));  
   
         /* calculate hashes */  
         if (rpc_calcHashes(&func, csModule, csFunc) == -1)  
                 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 258  rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char Line 149  rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char
 inline rpc_blob_t *  inline 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 291  rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_ Line 181  rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_
         }          }
   
         blob = rpc_srv_blobCreate(srv, len);          blob = rpc_srv_blobCreate(srv, len);
         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 196  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 206  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);
           io_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.11


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