/home/dko/projects/mobilec/trunk/src/df.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008年06月24日 10:50:29 -0700 (2008年6月24日) $ : Last Committed Date */
00004 /*[
00005  * Copyright (c) 2007 Integration Engineering Laboratory
00006  University of California, Davis
00007  *
00008  * Permission to use, copy, and distribute this software and its
00009  * documentation for any purpose with or without fee is hereby granted,
00010  * provided that the above copyright notice appear in all copies and
00011  * that both that copyright notice and this permission notice appear
00012  * in supporting documentation.
00013  *
00014  * Permission to modify the software is granted, but not the right to
00015  * distribute the complete modified source code. Modifications are to
00016  * be distributed as patches to the released version. Permission to
00017  * distribute binaries produced by compiling modified sources is granted,
00018  * provided you
00019  * 1. distribute the corresponding source modifications from the
00020  * released version in the form of a patch file along with the binaries,
00021  * 2. add special version identification to distinguish your version
00022  * in addition to the base release version number,
00023  * 3. provide your name and address as the primary contact for the
00024  * support of your modified version, and
00025  * 4. retain our contact information in regard to use of the base
00026  * software.
00027  * Permission to distribute the released version of the source code along
00028  * with corresponding source modifications in the form of a patch file is
00029  * granted with same provisions 2 through 4 for binary distributions.
00030  *
00031  * This software is provided "as is" without express or implied warranty
00032  * to the extent permitted by applicable law.
00033 ]*/
00034 
00035 /* Filename: df.c */
00036 
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #ifndef _WIN32
00040 #include <unistd.h>
00041 #endif
00042 #include "include/mc_platform.h"
00043 #include "include/df.h"
00044 
00045 /* df functions */
00046 int 
00047 df_Add(struct df_s* df, struct df_node_s* node)
00048 {
00049 int err;
00050 
00051 SIGNAL(
00052 df->cond,
00053 df->lock,
00054 
00055 err = ListAdd(df->service_list, (void*) node);
00056 if (err == MC_SUCCESS) 
00057 df->num_entries++;
00058 );
00059 return err;
00060 }
00061 
00062 int 
00063 df_AddRequest(struct df_s* df, struct df_request_list_node_s* node)
00064 {
00065 int err;
00066 
00067 SIGNAL(
00068 df->request_list->cond,
00069 df->request_list->lock,
00070 
00071 err = ListAdd(
00072 df->request_list->request_list,
00073 (void*)node );
00074 df->request_list->size++;
00075 );
00076 return err;
00077 }
00078 
00079 int
00080 df_Destroy(df_p df)
00081 {
00082 df_node_p df_node;
00083 MUTEX_LOCK(df->lock);
00084 while ( (df_node = (df_node_p)ListPop(df->service_list)) != NULL) {
00085 df_node_Destroy(df_node);
00086 }
00087 ListTerminate(df->service_list);
00088 df_request_list_Destroy(df->request_list);
00089 MUTEX_DESTROY(df->lock);
00090 COND_DESTROY(df->cond);
00091 free(df->lock);
00092 free(df->cond);
00093 free(df);
00094 return MC_SUCCESS;
00095 }
00096 
00097 df_p 
00098 df_Initialize(mc_platform_p mc_platform)
00099 {
00100 df_p df;
00101 df = (df_p)malloc(sizeof(df_t)); 
00102 
00103 df->mc_platform = mc_platform;
00104 
00105 /* Mutex Init */
00106 df->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00107 MUTEX_INIT(df->lock);
00108 
00109 /* Cond Init */
00110 df->cond = (COND_T*)malloc(sizeof(COND_T));
00111 COND_INIT(df->cond);
00112 
00113 /* Initialize the Service List */
00114 df->service_list = ListInitialize();
00115 
00116 /* Initialize the Request List */
00117 df->request_list = df_request_list_New();
00118 
00119 df->num_entries = 0;
00120 df->waiting = 0;
00121 df->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00122 MUTEX_INIT(df->waiting_lock);
00123 df->waiting_cond = (COND_T*)malloc(sizeof(COND_T));
00124 COND_INIT(df->waiting_cond);
00125 return df;
00126 }
00127 
00128 int 
00129 df_ProcessRequest(
00130 struct mc_platform_s* global
00131 )
00132 {
00133 int return_code;
00134 int handler_code;
00135 enum df_request_list_index_e request_code;
00136 df_request_list_node_t *request;
00137 if ( 
00138 (
00139 request = df_request_list_Pop( global->df->request_list ) 
00140 ) == NULL
00141 )
00142 {
00143 printf("Empty.\n");
00144 return MC_ERR_EMPTY;
00145 }
00146 
00147 /* Process the request, call the correct handler */
00148 #define REQUEST(name, string, description) \
00149  if ( !strcmp(request->command, string ) ) { \
00150  return_code = MC_SUCCESS; \
00151  handler_code = request_handler_##name( \
00152  global, \
00153  request->data ); \
00154  request_code = REQUEST_##name; \
00155  } else
00156 #include "include/df_request.x.h"
00157 #undef REQUEST
00158 { 
00159 fprintf(stderr, "No such register command: %s. %s:%d\n",
00160 request->command,
00161 __FILE__,
00162 __LINE__ );
00163 return MC_ERR_INVALID;
00164 }
00165 
00166 return handler_code;
00167 }
00168 
00169 /* returns error code. */
00170 /* Third argument is a return argument: array of matching agent names. */
00171 /* Fourth argument is a return argument: Number of matching service names. */
00172 /* Fifth argument is a return argument: Array of matching agent IDs */
00173 int df_SearchForService(
00174 df_p df,
00175 const char* searchstring, 
00176 char*** agent_names,
00177 char*** service_names,
00178 int** agent_ids,
00179 int* num_entries)
00180 {
00181 int i=0;
00182 int j=0;
00183 int found_entries=0;
00184 listNode_p list_node;
00185 df_node_p df_node;
00186 
00187 /* check for empty df */
00188 if(df->num_entries < 1) {
00189 *num_entries = 0;
00190 return MC_ERR_NOT_FOUND;
00191 }
00192 
00193 /* Lock the list mutex to prevent simultaneous searches */
00194 MUTEX_LOCK(df->lock);
00195 /* We'll run the following loop twice. The first time to find
00196  * the number of elements we need to allocate, the second
00197  * to actually assign some values. */
00198 list_node = df->service_list->listhead;
00199 while (list_node != NULL) {
00200 /* Lock the df_node to prevent deletions/changes from happening
00201  * mid-search */
00202 MUTEX_LOCK( ((df_node_p)(list_node->node_data))->lock );
00203 df_node = (df_node_p)list_node->node_data;
00204 for(i = 0; i < df_node->num_services; i++) {
00205 if ( strstr(df_node->service_names[i], searchstring) ) {
00206 /* Found an entry. */
00207 found_entries++;
00208 }
00209 }
00210 MUTEX_UNLOCK(df_node->lock);
00211 list_node = list_node->next;
00212 }
00213 if (found_entries == 0) {
00214 /* Nothing was found. Unlock mutexes and return */
00215 MUTEX_UNLOCK(df->lock);
00216 *num_entries = 0;
00217 return MC_ERR_NOT_FOUND;
00218 }
00219 
00220 /* Allocate return arguments */
00221 *agent_names = (char**)malloc(sizeof(char*) * found_entries);
00222 *service_names = (char**)malloc(sizeof(char*) * found_entries);
00223 *agent_ids = (int*)malloc(sizeof(int) * found_entries);
00224 /* Re run the loop */
00225 list_node = df->service_list->listhead;
00226 while (list_node != NULL) {
00227 /* Lock the df_node to prevent deletions/changes from happening
00228  * mid-search */
00229 MUTEX_LOCK( ((df_node_p)(list_node->node_data))->lock );
00230 df_node = (df_node_p)list_node->node_data;
00231 for(i = 0; i < df_node->num_services; i++) {
00232 if ( strstr(df_node->service_names[i], searchstring) ) {
00233 /* Found an entry. */
00234 /* Copy name into return argument */
00235 (*agent_names)[j] = (char*)malloc(
00236 sizeof(char) * (strlen(df_node->agent_name)+1)
00237 );
00238 strcpy((*agent_names)[j], df_node->agent_name);
00239 /* Copy service name into return arg */
00240 (*service_names)[j] = (char*)malloc(
00241 sizeof(char) * (strlen((df_node->service_names)[i])+1)
00242 );
00243 strcpy((*service_names)[j], (df_node->service_names)[i]);
00244 /* Copy agent id into return arg */
00245 (*agent_ids)[j] = df_node->agent_id;
00246 j++;
00247 }
00248 }
00249 MUTEX_UNLOCK(df_node->lock);
00250 list_node = list_node->next;
00251 }
00252 MUTEX_UNLOCK(df->lock);
00253 *num_entries = found_entries;
00254 return MC_SUCCESS;
00255 }
00256 
00257 void 
00258 df_Start(mc_platform_p mc_platform)
00259 {
00260 #ifndef _WIN32
00261 pthread_attr_t attr;
00262 pthread_attr_init(&attr);
00263 if (mc_platform->stack_size[MC_THREAD_DF] != -1) {
00264 pthread_attr_setstacksize
00265 (
00266 &attr, 
00267 mc_platform->stack_size[MC_THREAD_DF]
00268 );
00269 }
00270 #else
00271 int stack_size;
00272 if (mc_platform->stack_size[MC_THREAD_DF] < 1) {
00273 /* In windows, 0 is default, not min */
00274 stack_size = mc_platform->stack_size[MC_THREAD_DF]+1; 
00275 } else {
00276 stack_size = mc_platform->stack_size[MC_THREAD_DF];
00277 }
00278 #endif
00279 THREAD_CREATE
00280 (
00281 &mc_platform->df->thread,
00282 df_Thread,
00283 mc_platform
00284 );
00285 }
00286 
00287 /* df_request_list_node functions */
00288 int 
00289 df_request_list_node_Destroy(df_request_list_node_p node)
00290 {
00291 MUTEX_DESTROY(node->lock);
00292 free(node->lock);
00293 COND_DESTROY(node->cond);
00294 free(node->cond);
00295 free(node);
00296 return MC_SUCCESS;
00297 }
00298 
00299 df_request_list_node_p 
00300 df_request_list_node_New(void)
00301 {
00302 df_request_list_node_p node;
00303 node = (df_request_list_node_p)
00304 malloc(sizeof(df_request_list_node_t));
00305 CHECK_NULL(node, return NULL;);
00306 node->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00307 MUTEX_INIT(node->lock);
00308 node->cond = (COND_T*)malloc(sizeof(COND_T));
00309 COND_INIT(node->cond);
00310 node->data_size = 0;
00311 node->command = NULL;
00312 node->data = NULL;
00313 return node;
00314 }
00315 
00316 /* df_request_list functions */
00317 int
00318 df_request_list_Destroy(df_request_list_p df_request_list)
00319 {
00320 df_request_list_node_p node;
00321 while 
00322 ( 
00323 (
00324 node = 
00325 (df_request_list_node_p)ListPop
00326 (
00327 df_request_list->request_list
00328 )
00329 ) != NULL
00330 )
00331 {
00332 df_request_list_node_Destroy(node);
00333 }
00334 ListTerminate(df_request_list->request_list);
00335 free(df_request_list);
00336 return MC_SUCCESS;
00337 }
00338 
00339 df_request_list_p 
00340 df_request_list_New(void)
00341 {
00342 df_request_list_p new_list;
00343 new_list = (df_request_list_p)malloc(sizeof(df_request_list_t));
00344 CHECK_NULL(new_list, return NULL;);
00345 
00346 /* Initialize sync */
00347 new_list->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00348 CHECK_NULL(new_list->lock, return NULL;);
00349 new_list->cond = (COND_T*)malloc(sizeof(COND_T));
00350 CHECK_NULL(new_list->cond, return NULL;);
00351 
00352 MUTEX_INIT(new_list->lock);
00353 COND_INIT(new_list->cond);
00354 
00355 new_list->size=0;
00356 
00357 new_list->request_list = ListInitialize();
00358 if (new_list->request_list == NULL) {
00359 return NULL;
00360 } else
00361 return new_list;
00362 }
00363 
00364 df_request_list_node_p 
00365 df_request_list_Pop(df_request_list_p requests)
00366 {
00367 df_request_list_node_t *node;
00368 MUTEX_LOCK( requests->lock );
00369 if (requests->size <= 0) {
00370 MUTEX_UNLOCK( requests->lock );
00371 return NULL;
00372 }
00373 node = ListPop(requests->request_list);
00374 requests->size--;
00375 MUTEX_UNLOCK( requests->lock );
00376 return node;
00377 }
00378 
00379 /*df_request_search functions */
00380 df_request_search_p 
00381 df_request_search_New(void)
00382 {
00383 df_request_search_p search;
00384 search = (df_request_search_p)malloc(sizeof(df_request_search_t));
00385 CHECK_NULL(search, return NULL;);
00386 search->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00387 CHECK_NULL(search->lock, return NULL;);
00388 search->cond = (COND_T*)malloc(sizeof(COND_T));
00389 CHECK_NULL(search->cond, return NULL;);
00390 MUTEX_INIT(search->lock);
00391 COND_INIT(search->cond);
00392 return search;
00393 }
00394 
00395 int 
00396 df_request_search_Destroy(df_request_search_p node)
00397 {
00398 MUTEX_DESTROY(node->lock);
00399 free(node->lock);
00400 COND_DESTROY(node->cond);
00401 free(node->cond);
00402 
00403 free(node);
00404 return MC_SUCCESS;
00405 }
00406 
00407 
00408 int
00409 df_node_Destroy(df_node_p df_node)
00410 {
00411 int i;
00412 MUTEX_LOCK(df_node->lock);
00413 free(df_node->agent_name);
00414 for(i = 0; i < df_node->num_services; i++) {
00415 free(df_node->service_names[i]);
00416 }
00417 free(df_node->service_names);
00418 free(df_node);
00419 return MC_SUCCESS;
00420 }
00421 
00422 #ifndef _WIN32
00423 void* df_Thread(void* arg)
00424 #else
00425 DWORD WINAPI df_Thread( LPVOID arg )
00426 #endif
00427 {
00428 int err_code;
00429 mc_platform_p global = (mc_platform_p)arg;
00430 while(1) {
00431 MUTEX_LOCK(global->df->request_list->lock);
00432 MUTEX_LOCK(global->quit_lock);
00433 while 
00434 (
00435 (global->df->request_list->size <= 0) &&
00436 !global->quit
00437 ) 
00438 {
00439 MUTEX_UNLOCK(global->quit_lock);
00440 /* Set waiting flag on */
00441 MUTEX_LOCK(global->df->waiting_lock);
00442 global->df->waiting = 1;
00443 COND_BROADCAST(global->df->waiting_cond);
00444 MUTEX_UNLOCK(global->df->waiting_lock);
00445 /* Wait for activity */
00446 COND_WAIT
00447 (
00448 global->df->request_list->cond,
00449 global->df->request_list->lock
00450 );
00451 MUTEX_LOCK(global->quit_lock);
00452 }
00453 /* Set waiting flag off */
00454 MUTEX_LOCK(global->df->waiting_lock);
00455 global->df->waiting = 0;
00456 COND_BROADCAST(global->df->waiting_cond);
00457 MUTEX_UNLOCK(global->df->waiting_lock);
00458 if 
00459 (
00460 global->df->request_list->size == 0 && global->quit
00461 ) {
00462 MUTEX_UNLOCK(global->quit_lock);
00463 MUTEX_UNLOCK(global->df->request_list->lock);
00464 return 0;
00465 }
00466 MUTEX_UNLOCK(global->quit_lock);
00467 MUTEX_UNLOCK(global->df->request_list->lock);
00468 if ( 
00469 (err_code = df_ProcessRequest(
00470 global
00471 )) != MC_SUCCESS ) {
00472 fprintf(stderr,
00473 "Error Code %d: %s:%d\n",
00474 err_code,
00475 __FILE__,
00476 __LINE__ );
00477 }
00478 }
00479 return 0;
00480 }
00481 
00482 
00483 
00484 
00485 /* Request Handlers */
00486 
00487 int request_handler_REGISTER(struct mc_platform_s* global, void* data)
00488 {
00489 /* Insert new struct into DF */
00490 return df_Add(global->df, (struct df_node_s*)data);
00491 }
00492 
00493 int request_handler_SEARCH(struct mc_platform_s* global, void* data)
00494 {
00495 df_request_search_p search;
00496 search = (df_request_search_p)data;
00497 df_SearchForService(
00498 global->df,
00499 search->search_string,
00500 &search->search_results->agent_names,
00501 &search->search_results->service_names,
00502 &search->search_results->agent_ids,
00503 &search->search_results->num_results
00504 );
00505 SIGNAL(search->cond,
00506 search->lock,
00507 NULL
00508 );
00509 return MC_SUCCESS;
00510 }
00511 
00512 int request_handler_SUBSCRIBE(struct mc_platform_s* global, void* data)
00513 {
00514 return 0;
00515 }
00516 
00517 int request_handler_DEREGISTER(struct mc_platform_s* global, void* data)
00518 {
00519 int i, j;
00520 df_deregister_p deregister;
00521 listNode_p node;
00522 df_node_p df_node;
00523 int num_deregistered=0;
00524 df_p df = global->df;
00525 deregister = (df_deregister_p)data;
00526 /* Find and remove all entries matching search terms. */
00527 MUTEX_LOCK(df->lock);
00528 if (df->service_list->listhead== NULL) {
00529 MUTEX_UNLOCK(df->lock);
00530 return 0;
00531 }
00532 node = df->service_list->listhead;
00533 while (node != NULL) {
00534 df_node = (df_node_p)node->node_data;
00535 if (df_node->agent_id == deregister->agent_id) {
00536 for (i = 0; i < df_node->num_services; i++) {
00537 if (!strcmp(
00538 df_node->service_names[i],
00539 deregister->service_name 
00540 ) 
00541 ) 
00542 {
00543 free(df_node->service_names[i]);
00544 for (j = i; j < df_node->num_services-1; j++) {
00545 df_node->service_names[j] = df_node->service_names[j+1];
00546 }
00547 df_node->num_services--;
00548 num_deregistered++;
00549 
00550 if (df_node->num_services == 0) {
00551 /* Just get rid of the entire node altogether */
00552 /* FIXME */
00553 }
00554 }
00555 }
00556 }
00557 node = node->next;
00558 }
00559 MUTEX_UNLOCK(df->lock);
00560 return MC_SUCCESS;
00561 }

Generated on Tue Oct 28 17:03:22 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /