File:  [ELWIX - Embedded LightWeight unIX -] / libaitrpc / src / lists.c
Revision 1.1.2.9: download - view: text, annotated - select for diffs - revision graph
Tue Mar 15 16:48:31 2011 UTC (13 years, 3 months ago) by misho
Branches: rpc1_0
added close (cosmetic)

    1: #include "global.h"
    2: 
    3: 
    4: /*
    5:  * rpc_srv_retValsCall() Declare return variables for RPC call and zeroed values
    6: 					(for safe handling return values, use this!)
    7:  * @call = RPC function call
    8:  * @return_vals = Number of return variables
    9:  * return: NULL error, !=NULL array with return values for RPC call with return_vals items
   10:  */
   11: inline rpc_val_t *
   12: rpc_srv_retValsCall(rpc_func_t * __restrict call, int return_vals)
   13: {
   14: 	rpc_val_t *v = NULL;
   15: 
   16: 	if (rpc_srv_declValsCall(call, return_vals) == -1)
   17: 		return NULL;
   18: 	else
   19: 		rpc_srv_zeroValsCall(call);
   20: 	if (rpc_srv_getValsCall(call, &v) == -1)
   21: 		return NULL;
   22: 
   23: 	return v;
   24: }
   25: 
   26: /*
   27:  * rpc_srv_freeValsCall() Free return variables for RPC call
   28:  * @call = RPC function call
   29:  * return: none
   30:  */
   31: inline void
   32: rpc_srv_freeValsCall(rpc_func_t * __restrict call)
   33: {
   34: 	rpc_srv_declValsCall(call, 0);
   35: }
   36: 
   37: /*
   38:  * rpc_srv_declValsCall() Declare return variables for RPC call, 
   39: 				if already allocated memory for RPC call return values 
   40: 				function reallocate used space with return_vals count elements
   41:  * @call = RPC function call
   42:  * @return_vals = Number of return variables
   43:  * return: -1 error, !=-1 ok
   44:  */
   45: inline int
   46: rpc_srv_declValsCall(rpc_func_t * __restrict call, int return_vals)
   47: {
   48: 	void *ptr;
   49: 
   50: 	if (!call || return_vals < 0) {
   51: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t declare return variables for RPC call...\n");
   52: 		return -1;
   53: 	} else
   54: 		call->func_args = return_vals;
   55: 
   56: 	if (!return_vals) {
   57: 		if (call->func_vals) {
   58: 			free(call->func_vals);
   59: 			call->func_vals = NULL;
   60: 		}
   61: 	} else {
   62: 		ptr = realloc(call->func_vals, return_vals * sizeof(rpc_val_t));
   63: 		if (!ptr) {
   64: 			LOGERR;
   65: 			call->func_args = 0;
   66: 			return -1;
   67: 		} else
   68: 			call->func_vals = ptr;
   69: 	}
   70: 
   71: 	return return_vals;
   72: }
   73: 
   74: /*
   75:  * rpc_srv_zeroValsCall() Clean values from return variables of RPC call
   76:  * @call = RPC function call
   77:  * return: -1 error, !=-1 Returned number of cleaned RPC variables
   78:  */
   79: inline int
   80: rpc_srv_zeroValsCall(rpc_func_t * __restrict call)
   81: {
   82: 	if (!call) {
   83: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t delete return variables ...\n");
   84: 		return -1;
   85: 	}
   86: 
   87: 	memset(call->func_vals, 0, call->func_args * sizeof(rpc_val_t));
   88: 	return call->func_args;
   89: }
   90: 
   91: /*
   92:  * rpc_srv_copyValsCall() Copy return variables for RPC call to new variable
   93:  * @call = RPC function call
   94:  * @newvals = New allocated variables array, must be free after use
   95:  * return: -1 error, !=-1 Returned number of copied RPC variables
   96:  */
   97: inline int
   98: rpc_srv_copyValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict newvals)
   99: {
  100: 	if (!call || !newvals) {
  101: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t copy return variables to new array\n");
  102: 		return -1;
  103: 	}
  104: 
  105: 	*newvals = calloc(call->func_args, sizeof(rpc_val_t));
  106: 	if (!*newvals) {
  107: 		LOGERR;
  108: 		return -1;
  109: 	} else
  110: 		memcpy(*newvals, call->func_vals, call->func_args * sizeof(rpc_val_t));
  111: 
  112: 	return call->func_args;
  113: }
  114: 
  115: /*
  116:  * rpc_srv_getValsCall() Get return variables for RPC call
  117:  * @call = RPC function call
  118:  * @vals = Returned variables, may be NULL
  119:  * return: -1 error, !=-1 Number of returned variables
  120:  */
  121: inline int
  122: rpc_srv_getValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict vals)
  123: {
  124: 	if (!call) {
  125: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get return variables ...\n");
  126: 		return -1;
  127: 	}
  128: 
  129: 	if (vals)
  130: 		*vals = call->func_vals;
  131: 	return call->func_args;
  132: }
  133: 
  134: // ---------------------------------------------------------
  135: 
  136: /*
  137:  * rpc_srv_registerCall() Register call to RPC server
  138:  * @srv = RPC Server instance
  139:  * @csModule = Module name, if NULL self binary
  140:  * @csFunc = Function name
  141:  * @args = Number of return function arguments, use for restriction case!
  142:  * return: -1 error or 0 register ok
  143:  */
  144: int
  145: rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc, u_char args)
  146: {
  147: 	rpc_func_t *func;
  148: 	u_char str[MAXPATHLEN + UCHAR_MAX + 1];
  149: 
  150: 	memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
  151: 	if (!srv || !csFunc) {
  152: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register function to RPC server ...\n");
  153: 		return -1;
  154: 	}
  155: 	if (!(func = malloc(sizeof(rpc_func_t)))) {
  156: 		LOGERR;
  157: 		return -1;
  158: 	} else {
  159: 		memset(func, 0, sizeof(rpc_func_t));
  160: 		strlcpy((char*) func->func_name, csFunc, UCHAR_MAX + 1);
  161: 	}
  162: 	if (csModule) {
  163: 		strlcpy((char*) func->func_file, csModule, MAXPATHLEN);
  164: 		strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
  165: 	}
  166: 	strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
  167: 	strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
  168: 
  169: 	func->func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
  170: 	func->func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
  171: 
  172: 	func->func_parent = srv;
  173: 
  174: 	if (args > 0 && rpc_srv_declValsCall(func, args) == -1) {
  175: 		free(func);
  176: 		return -1;
  177: 	}
  178: 
  179: 	pthread_mutex_lock(&srv->srv_mtx);
  180: 	func->func_next = srv->srv_funcs;
  181: 	srv->srv_funcs = func;
  182: 	pthread_mutex_unlock(&srv->srv_mtx);
  183: 	return 0;
  184: }
  185: 
  186: /*
  187:  * rpc_srv_unregisterCall() Unregister call from RPC server
  188:  * @srv = RPC Server instance
  189:  * @csModule = Module name, if NULL self binary
  190:  * @csFunc = Function name
  191:  * return: -1 error, 0 not found call, 1 unregister ok
  192:  */
  193: int
  194: rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
  195: {
  196: 	rpc_func_t func, *f, *curr;
  197: 	u_char str[MAXPATHLEN + UCHAR_MAX + 1];
  198: 
  199: 	memset(&func, 0, sizeof(rpc_func_t));
  200: 	memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
  201: 	if (!srv || !csFunc) {
  202: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister function from RPC server ...\n");
  203: 		return -1;
  204: 	} else
  205: 		strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
  206: 	if (csModule) {
  207: 		strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
  208: 		strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
  209: 	}
  210: 	strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
  211: 	strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
  212: 
  213: 	func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
  214: 	func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
  215: 
  216: 	f = rpc_srv_getCall(srv, func.func_tag, func.func_hash);
  217: 	if (!f)		// not found element for unregister
  218: 		return 0;
  219: 
  220: 	pthread_mutex_lock(&srv->srv_mtx);
  221: 	if (srv->srv_funcs == f) {	// if is 1st element
  222: 		srv->srv_funcs = srv->srv_funcs->func_next;
  223: 
  224: 		if (f->func_args && f->func_vals)
  225: 			free(f->func_vals);
  226: 		free(f);
  227: 	} else {
  228: 		for (curr = srv->srv_funcs; curr->func_next != f; curr = curr->func_next);
  229: 		curr->func_next = curr->func_next->func_next;
  230: 
  231: 		if (f->func_args && f->func_vals)
  232: 			free(f->func_vals);
  233: 		free(f);
  234: 	}
  235: 	pthread_mutex_unlock(&srv->srv_mtx);
  236: 
  237: 	return 1;
  238: }
  239: 
  240: /*
  241:  * rpc_srv_getCall() Get registered call from RPC server
  242:  * @srv = RPC Server instance
  243:  * @tag = tag for function
  244:  * @hash = hash for function
  245:  * return: NULL not found call, !=NULL return call
  246:  */
  247: inline rpc_func_t *
  248: rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash)
  249: {
  250: 	rpc_func_t *f;
  251: 
  252: 	if (!srv) {
  253: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
  254: 		return NULL;
  255: 	}
  256: 
  257: 	for (f = srv->srv_funcs; f; f = f->func_next)
  258: 		if (f->func_tag == tag && f->func_hash == hash)
  259: 			break;
  260: 
  261: 	return f;
  262: }
  263: 
  264: /*
  265:  * rpc_srv_getFunc() Get registered call from RPC server by Name
  266:  * @srv = RPC Server instance
  267:  * @csModule = Module name, if NULL self binary
  268:  * @csFunc = Function name
  269:  * return: NULL not found call, !=NULL return call
  270:  */
  271: rpc_func_t *
  272: rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
  273: {
  274: 	rpc_func_t func;
  275: 	u_char str[MAXPATHLEN + UCHAR_MAX + 1];
  276: 
  277: 	memset(&func, 0, sizeof(rpc_func_t));
  278: 	memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
  279: 	if (!srv || !csFunc) {
  280: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
  281: 		return NULL;
  282: 	} else
  283: 		strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
  284: 	if (csModule) {
  285: 		strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
  286: 		strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
  287: 	}
  288: 	strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
  289: 	strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
  290: 
  291: 	func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
  292: 	func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
  293: 
  294: 	return rpc_srv_getCall(srv, func.func_tag, func.func_hash);
  295: }
  296: 
  297: // ---------------------------------------------------------
  298: 
  299: /*
  300:  * rpc_srv_getBLOB() Get registered BLOB 
  301:  * @srv = RPC Server instance
  302:  * @var = hash for variable
  303:  * return: NULL not found, !=NULL return blob var
  304:  */
  305: inline rpc_blob_t *
  306: rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var)
  307: {
  308: 	rpc_blob_t *b;
  309: 
  310: 	if (!srv) {
  311: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get variable from BLOB server ...\n");
  312: 		return NULL;
  313: 	}
  314: 
  315: 	pthread_mutex_lock(&srv->srv_blob.mtx);
  316: 	for (b = srv->srv_blob.blobs; b; b = b->blob_next) {
  317: 		if (b->blob_var == var)
  318: 			break;
  319: 	}
  320: 	pthread_mutex_unlock(&srv->srv_blob.mtx);
  321: 
  322: 	return b;
  323: }
  324: 
  325: /*
  326:  * rpc_srv_registerBLOB() Register new BLOB to server
  327:  * @srv = RPC Server instance
  328:  * @len = BLOB length
  329:  * return: NULL error or new registered BLOB
  330:  */
  331: rpc_blob_t *
  332: rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_t len)
  333: {
  334: 	rpc_blob_t *blob = NULL;
  335: 
  336: 	if (!srv || !len) {
  337: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register BLOB to server ...\n");
  338: 		return blob;
  339: 	}
  340: 
  341: 	blob = rpc_srv_blobCreate(srv, len);
  342: 	if (blob) {
  343: 		pthread_mutex_lock(&srv->srv_blob.mtx);
  344: 		blob->blob_next = srv->srv_blob.blobs;
  345: 		srv->srv_blob.blobs = blob;
  346: 		pthread_mutex_unlock(&srv->srv_blob.mtx);
  347: 	}
  348: 
  349: 	return blob;
  350: }
  351: 
  352: /*
  353:  * rpc_srv_unregisterBLOB() Unregister BLOB from server
  354:  * @srv = RPC Server instance
  355:  * @var = BLOB Variable for unregister
  356:  * return: -1 error, 0 not found call, 1 unregister ok
  357:  */
  358: int
  359: rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uint32_t var)
  360: {
  361: 	rpc_blob_t *b, *curr;
  362: 
  363: 	if (!srv) {
  364: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister BLOB from server ...\n");
  365: 		return -1;
  366: 	}
  367: 
  368: 	b = rpc_srv_getBLOB(srv, var);
  369: 	if (!b)		// not found element for unregister
  370: 		return 0;
  371: 
  372: 	pthread_mutex_lock(&srv->srv_blob.mtx);
  373: 	if (srv->srv_blob.blobs == b) {	// if is 1st element
  374: 		srv->srv_blob.blobs = srv->srv_blob.blobs->blob_next;
  375: 	} else {
  376: 		for (curr = srv->srv_blob.blobs; curr->blob_next != b; curr = curr->blob_next);
  377: 		curr->blob_next = curr->blob_next->blob_next;
  378: 	}
  379: 	rpc_srv_blobFree(srv, b);
  380: 	free(b);
  381: 	pthread_mutex_unlock(&srv->srv_blob.mtx);
  382: 
  383: 	return 1;
  384: }

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