TSP: The Transport Sample Protocol



Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

tsp_datapool.c

Go to the documentation of this file.
00001 
00040 #include "tsp_sys_headers.h"
00041 
00042 #include "tsp_datapool.h"
00043 
00044 #include "tsp_datastruct.h"
00045 
00046 #include "tsp_session.h"
00047 #include "tsp_time.h"
00048 
00049 /* Poll time waiting for  consumer connection (us) */
00050 #define TSP_LOCAL_WORKER_CONNECTION_POLL_TIME ((int)(1e5))
00051 
00052 /* Data Poll period (us) */
00053 #define TSP_DATAPOOL_POLL_PERIOD ((int)(1e4))
00054 
00055 
00056 /*-----------------------------------------------------*/
00057 
00058 struct TSP_datapool_item_t 
00059 {
00067   double user_value;
00068   int is_wanted;        /* Is the symbol wanted by some consummers */
00069 };
00070 
00071 typedef struct TSP_datapool_item_t TSP_datapool_item_t;
00072 
00073 struct TSP_datapool_table_t
00074 {
00075 
00077   int initialized;
00078 
00080   int terminated;
00081   
00083   GLU_handle_t h_glu;
00084 
00086   TSP_datapool_item_t* items;
00087   int size;
00088 
00090   int *reverse_index;
00091   int nb_wanted_items;
00092 
00093 };
00094 
00095 typedef struct TSP_datapool_table_t TSP_datapool_table_t;
00096 
00097 /*-----------------------------------------------------*/
00098 
00099 TSP_datapool_table_t X_global_datapool = {FALSE,FALSE,0,0,0};
00100 
00101 /*-----------------------------------------------------*/
00102 
00103 #define TSP_CHECK_PROVIDER_GLOBAL_INDEX(obj, index, ret) \
00104 { \
00105         if( (index) >= (obj).size ) \
00106         { \
00107                 STRACE_ERROR(("ERROR :-->OUT : provider_global_index %d does not exist !",(index))) \
00108                 return ret; \
00109         } \
00110 }
00111 
00112 
00118 void TSP_datapool_get_reverse_list (int *nb, int **list)
00119 {
00120   assert(nb!=NULL);
00121   assert(list!=NULL);
00122   *nb = X_global_datapool.nb_wanted_items;
00123   *list = X_global_datapool.reverse_index;
00124 }
00125 
00126 
00131 inline int TSP_datapool_push_next_item(glu_item_t* item)
00132 {
00133   X_global_datapool.items[item->provider_global_index].user_value = item->value;
00134   return 0;
00135 }
00136 
00142 int TSP_datapool_push_commit(time_stamp_t time_stamp, GLU_get_state_t state)
00143 {
00144   STRACE_DEBUG(("Datapool push new item time %d",time_stamp)); 
00145 
00146    /* Send end status message */
00147   switch(state)
00148     {
00149     case GLU_GET_NO_ITEM :
00150       /* nothing to do */
00151       break;
00152 
00153     case GLU_GET_NEW_ITEM :
00154       /* Yep ! throw data to all clients */
00155       /* For a global datapool, the thread must not end, even if a client is disconnected, so
00156          we do not check any returned value from TSP_session_all_session_send_data */
00157       TSP_session_all_session_send_data(time_stamp);              
00158       break;
00159 
00160     case GLU_GET_EOF :
00161       TSP_session_all_session_send_msg_ctrl(TSP_MSG_CTRL_EOF);
00162       STRACE_INFO(("GLU sent EOF"));
00163       /* End of flow. Our datapool is dead */
00164       X_global_datapool.terminated = TRUE;
00165       break;
00166 
00167     case GLU_GET_RECONF :
00168       TSP_session_all_session_send_msg_ctrl(TSP_MSG_CTRL_RECONF);
00169       STRACE_INFO(("GLU sent RECONF"));
00170       /* End of flow. Our datapool is dead */
00171       X_global_datapool.terminated = TRUE;
00172       break;
00173 
00174     case GLU_GET_DATA_LOST :
00175       TSP_session_all_session_send_msg_ctrl(TSP_MSG_CTRL_GLU_DATA_LOST);
00176       STRACE_INFO(("GLU sent DATA_LOST"));
00177       break;
00178 
00179     default:
00180       STRACE_ERROR(("?"));
00181       assert(0);
00182     }
00183 
00184 
00185   return 0;  
00186 }
00187 
00188 /* DON'T WANT ANYMORE this fucking thread passive callback f....cking philo */
00189 #define USE_DATA_POOL_THREAD 0 
00190 #if USE_DATA_POOL_THREAD
00191 
00195 void* TSP_datapool_thread(void* datapool)
00196 {
00197 
00198   time_stamp_t time_stamp;
00199   glu_item_t item;
00200   int more_items;
00201   TSP_datapool_table_t* obj_datapool = (TSP_datapool_table_t*)datapool;  
00202   GLU_get_state_t state;
00203   TSP_msg_ctrl_t msg_ctrl;  
00204   int data_link_ok = TRUE; 
00206   /* FIXME : The datapool might not be coherent when a client is already
00207      connected and this thread starts after the connection
00208      for the client */
00209   STRACE_DEBUG(("Data Pool is GLOBAL (active GLU)"));
00210 
00211   /* get first item */
00212   STRACE_DEBUG(("Waiting for First Item from GLU..."));
00213   while( ( GLU_GET_NEW_ITEM != (state=GLU_get_next_item(obj_datapool->h_glu, &item)))  )
00214     {
00215       tsp_usleep(TSP_DATAPOOL_POLL_PERIOD);
00216     }
00217 
00218   STRACE_DEBUG(("First Item from GLU received!"));
00219 
00220   time_stamp = item.time;
00221   /* Update datapool */
00222   obj_datapool->items[item.provider_global_index].user_value = item.value;           
00223   
00224   while( ((GLU_GET_NEW_ITEM == state) || (GLU_GET_NO_ITEM == state)) && data_link_ok )
00225     {
00226       while( (GLU_GET_NEW_ITEM == (state=GLU_get_next_item(obj_datapool->h_glu, &item))) && data_link_ok )
00227         {       
00228           /* is the datapool coherent ? */
00229           if( time_stamp != item.time )
00230             {
00231               /* Yep ! throw data to client */
00232               /* For a global datapool, the thread must not end, even if a client is disconnected, so
00233                  we do not check any returned value from TSP_session_all_session_send_data */
00234               TSP_session_all_session_send_data(time_stamp);              
00235               time_stamp = item.time;
00236             }
00237           /* Update datapool */
00238           obj_datapool->items[item.provider_global_index].user_value = item.value;     
00239         }
00240 
00241        tsp_usleep(TSP_DATAPOOL_POLL_PERIOD);
00242     }      
00243 
00244    /* Send end status message */
00245   if(data_link_ok)
00246     {
00247       switch(state)
00248         {
00249         case   GLU_GET_EOF :
00250           msg_ctrl = TSP_MSG_CTRL_EOF;
00251           STRACE_INFO(("GLU sent EOF"));
00252           break;
00253         case   GLU_GET_RECONF :
00254           msg_ctrl = TSP_MSG_CTRL_RECONF;
00255           STRACE_INFO(("GLU sent RECONF"));
00256           break;
00257         case   GLU_GET_DATA_LOST :
00258           msg_ctrl = TSP_MSG_CTRL_GLU_DATA_LOST;
00259           STRACE_INFO(("GLU sent DATA_LOST"));
00260           break;
00261         default:
00262           STRACE_ERROR(("?"));
00263           assert(0);
00264         }
00265 
00266       /* The lastest data were not sent coz we did not compare the latest timestamp. So, send them !*/
00267       /* Send data to all clients  */         
00268       TSP_session_all_session_send_data(time_stamp);              
00269       TSP_session_all_session_send_msg_ctrl(msg_ctrl);            
00270     }
00271 
00272   /* End of thread. Our datapool is dead */
00273   obj_datapool->terminated = TRUE;
00274 }
00275 
00276 
00277 
00283 int TSP_local_datapool_wait_for_end_thread(TSP_datapool_t datapool)
00284 {
00285   int status;
00286   TSP_datapool_table_t* obj_datapool = (TSP_datapool_table_t*)datapool;
00287 
00288   status = pthread_join(obj_datapool->worker_id, NULL);
00289   TSP_CHECK_THREAD(status, FALSE);
00290 
00291   return TRUE;
00292 }
00293 
00294 
00300 int TSP_local_datapool_start_thread(TSP_datapool_t datapool)
00301 {
00302   int status;
00303   TSP_datapool_table_t* obj_datapool = (TSP_datapool_table_t*)datapool;
00304 
00305   STRACE_ERROR(("Func is deprecated, use global datapool"));
00306   return -1;
00307 
00308   status = pthread_create(&(obj_datapool->worker_id), NULL, TSP_datapool_thread,  datapool);
00309   TSP_CHECK_THREAD(status, FALSE);
00310 
00311   return TRUE;
00312 
00313 }
00314 #endif
00315 
00321 static int TSP_global_datapool_init(void)
00322 {
00323          
00324   TSP_sample_symbol_info_list_t symbols;
00325         
00326   /* Here the datapool is global */
00327   X_global_datapool.h_glu = GLU_GLOBAL_HANDLE;   
00328 
00329   GLU_get_sample_symbol_info_list(X_global_datapool.h_glu, &symbols);
00330 
00331   X_global_datapool.size = symbols.TSP_sample_symbol_info_list_t_len;
00332 
00333   X_global_datapool.items = 
00334     (TSP_datapool_item_t*)calloc(X_global_datapool.size, sizeof(TSP_datapool_item_t));
00335   TSP_CHECK_ALLOC(X_global_datapool.items, FALSE);
00336 
00337   X_global_datapool.reverse_index = (int*)calloc(X_global_datapool.size, sizeof(int));
00338   TSP_CHECK_ALLOC(X_global_datapool.reverse_index, FALSE);
00339   X_global_datapool.nb_wanted_items = 0;
00340 
00341   STRACE_INFO(("No More datapool thread "));
00342   /*status = pthread_create(&(X_global_datapool.worker_id), NULL, TSP_datapool_thread,  &X_global_datapool);
00343   TSP_CHECK_THREAD(status, FALSE);*/
00344 
00345   X_global_datapool.initialized = TRUE;
00346   X_global_datapool.terminated = FALSE;
00347     
00348   return TRUE;
00349 
00350 }
00351 
00352 static void TSP_datapool_internal_free(TSP_datapool_table_t* obj_datapool)
00353 {
00354      free(obj_datapool->items);
00355      obj_datapool->items = 0;
00356      free(obj_datapool->reverse_index);
00357      obj_datapool->reverse_index = 0;
00358      obj_datapool->nb_wanted_items = 0;
00359 }
00360 
00361 void TSP_local_datapool_destroy(TSP_datapool_t datapool)
00362 {
00363    TSP_datapool_table_t* obj_datapool = (TSP_datapool_table_t*)datapool;
00364 
00365    TSP_datapool_internal_free(obj_datapool);
00366    free(obj_datapool);
00367 }
00368 
00369 
00370 TSP_datapool_t TSP_local_datapool_allocate(int symbols_number, GLU_handle_t h_glu )
00371 {
00372   TSP_datapool_table_t* datapool;
00373      
00374   datapool = (TSP_datapool_table_t*)calloc(1,sizeof(TSP_datapool_table_t));
00375   TSP_CHECK_ALLOC(datapool, 0);
00376         
00377   datapool->size = symbols_number;
00378 
00379   datapool->items = (TSP_datapool_item_t*)calloc(datapool->size,sizeof(TSP_datapool_item_t));
00380   TSP_CHECK_ALLOC(datapool->items, 0);
00381     
00382   datapool->h_glu = h_glu;
00383   datapool->initialized = TRUE;
00384   datapool->terminated = FALSE;
00385     
00386   return datapool;
00387 }
00388 
00389 
00390 void* TSP_datapool_get_symbol_value(TSP_datapool_t datapool, int provider_global_index, xdr_and_sync_type_t type)
00391 {
00392   void* p = 0;
00393   TSP_datapool_table_t* obj_datapool = (TSP_datapool_table_t*)datapool;
00394         
00395   TSP_CHECK_PROVIDER_GLOBAL_INDEX(*obj_datapool, provider_global_index, 0);
00396 
00397   /* Someone will ask for this symbols */
00398   if (obj_datapool->items[provider_global_index].is_wanted == FALSE)
00399     {
00400       obj_datapool->items[provider_global_index].is_wanted = TRUE; 
00401       obj_datapool->reverse_index[obj_datapool->nb_wanted_items++] = provider_global_index;
00402     }
00403 
00404   p = &(obj_datapool->items[provider_global_index].user_value);
00405 
00406   /* FIXME : manages different types RAW, DOUBLE, STRING...,
00407      see how to implement this when the data will be RAW in the datapool */
00408   /*switch(type & XDR_DATA_TYPE_MASK)
00409     {
00410     case XDR_DATA_TYPE_USER | TSP_DATA_TYPE_SYNC :
00411     p = &(X_global_datapool.items[provider_global_index].user_value);
00412     break;
00413     default :
00414     STRACE_ERROR(("Unknown XDR type : %X", type));
00415     }
00416   */
00417     
00418   return p;
00419 }
00420 
00421 
00422 TSP_datapool_t TSP_global_datapool_get_instance(void)
00423 {
00424   /* Act like a singleton. The first consumer that
00425  calls us, init us */
00426 
00427   /* Was the datapool terminated ? */
00428   if( TRUE == X_global_datapool.terminated )
00429     {
00430       /* Wait for thread to end */
00431       /* pthread_join(X_global_datapool.worker_id, NULL);*/
00432       /* Yes, clean up previous datapool */
00433       TSP_datapool_internal_free(&X_global_datapool);
00434       /* Now, the datapool is not initialized anymore */
00435       X_global_datapool.initialized = FALSE;
00436     }
00437 
00438   /* Was the datapool initialized  ? */
00439   if(FALSE == X_global_datapool.initialized)
00440     {
00441       /* Now initialize */
00442       TSP_global_datapool_init();
00443     }
00444 
00445   return &X_global_datapool;
00446 }
00447 
Framework Home Page.

Beware !! TSP wave is coming...