00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
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 
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   
00106   df->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00107   MUTEX_INIT(df->lock);
00108 
00109   
00110   df->cond = (COND_T*)malloc(sizeof(COND_T));
00111   COND_INIT(df->cond);
00112 
00113   
00114   df->service_list = ListInitialize();
00115 
00116   
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   
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 
00170 
00171 
00172 
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   
00188   if(df->num_entries < 1) {
00189     *num_entries = 0;
00190     return MC_ERR_NOT_FOUND;
00191   }
00192 
00193   
00194   MUTEX_LOCK(df->lock);
00195    
00196 
00197 
00198   list_node = df->service_list->listhead;
00199   while (list_node != NULL) {
00200     
00201 
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         
00207         found_entries++;
00208       }
00209     }
00210     MUTEX_UNLOCK(df_node->lock);
00211     list_node = list_node->next;
00212   }
00213   if (found_entries == 0) {
00214     
00215     MUTEX_UNLOCK(df->lock);
00216     *num_entries = 0;
00217     return MC_ERR_NOT_FOUND;
00218   }
00219 
00220   
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   
00225   list_node = df->service_list->listhead;
00226   while (list_node != NULL) {
00227     
00228 
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         
00234         
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         
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         
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     
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 
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 
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   
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 
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         
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         
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     
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 
00486 
00487 int request_handler_REGISTER(struct mc_platform_s* global, void* data)
00488 {
00489   
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   
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             
00552             
00553           }
00554         }
00555       }
00556     }
00557     node = node->next;
00558   }
00559   MUTEX_UNLOCK(df->lock);
00560   return MC_SUCCESS;
00561 }