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 #ifndef _AP_QUEUE_TEMPLATE_H_
00036 #define _AP_QUEUE_TEMPLATE_H_
00037 #include "macros.h"
00038 #include "mc_error.h"
00039 
00040 #define AP_QUEUE_DECL_TEMPLATE( name, node_type) \
00041 typedef struct name##_s \
00042 { \
00043   int size; \
00044   list_p list; \
00045   MUTEX_T* lock; \
00046   COND_T* cond; \
00047 } name##_t; \
00048   \
00049 typedef name##_t* name##_p; \
00050   \
00051 name##_p name##_New( void ); \
00052 int name##_Destroy( name##_p name ); \
00053 int name##_Add( name##_p name, struct node_type##_s* node ); \
00054 name##_p name##_Copy(name##_p name); \
00055 struct node_type##_s* name##_Pop( name##_p name ); \
00056 struct node_type##_s* name##_SearchIndex( name##_p name, int index ); \
00057 int name##_RemoveIndex(name##_p name, int index); 
00058 
00059 #define AP_QUEUE_GENERIC_DECL_TEMPLATE(name, func_name, return_type, search_type) \
00060 return_type name##_##func_name(name##_p name, const search_type key);
00061 
00062 #define AP_QUEUE_STD_DEFN_TEMPLATE( name, node_type) \
00063 name##_p name##_New( void ) \
00064 { \
00065   name##_p temp; \
00066   temp = (name##_p)malloc(sizeof(name##_t)); \
00067   temp->size = 0; \
00068   temp->list = ListInitialize(); \
00069   \
00070   temp->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); \
00071   temp->cond = (COND_T*)malloc(sizeof(COND_T)); \
00072   MUTEX_INIT(temp->lock); \
00073   COND_INIT(temp->cond); \
00074   return temp; \
00075 } \
00076   \
00077 int name##_Destroy( name##_p name ) \
00078 { \
00079   struct node_type##_s* node; \
00080   while ((node = name##_Pop(name)) != NULL) { \
00081     node_type##_Destroy(node); \
00082   } \
00083   ListTerminate(name->list); \
00084   MUTEX_DESTROY(name->lock); \
00085   COND_DESTROY(name->cond); \
00086   free(name->lock); \
00087   free(name->cond); \
00088   free(name); \
00089   return 0; \
00090 } \
00091   \
00092 name##_p name##_Copy(name##_p name) \
00093 { \
00094   int i;\
00095   name##_p temp; \
00096   struct node_type##_s* temp_node; \
00097   temp = (name##_p)malloc(sizeof(name##_t)); \
00098   if (temp == NULL) { \
00099     fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00100     exit(0); \
00101   } \
00102   temp->size = 0; \
00103   temp->list = ListInitialize(); \
00104   temp->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); \
00105   if (temp->lock == NULL) { \
00106     fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00107     exit(0); \
00108   } \
00109   temp->cond = (COND_T*)malloc(sizeof(COND_T)); \
00110   if(temp->cond == NULL) { \
00111     fprintf(stderr, "Memory Error at %s:%d\n", __FILE__, __LINE__); \
00112     exit(0); \
00113   } \
00114   MUTEX_INIT(temp->lock); \
00115   COND_INIT(temp->cond); \
00116   for( \
00117       i = 0; \
00118       (temp_node = name##_SearchIndex(name, i)) != NULL; \
00119       i++ \
00120      ) \
00121   { \
00122     name##_Add(temp, node_type##_Copy(temp_node)); \
00123   } \
00124   return temp; \
00125 } \
00126   \
00127 int name##_Add( name##_p name, node_type##_t* node ) \
00128 { \
00129   MUTEX_LOCK(name->lock); \
00130   ListAdd(name->list, node); \
00131   name->size++; \
00132   COND_SIGNAL(name->cond); \
00133   MUTEX_UNLOCK(name->lock); \
00134   return 0; \
00135 } \
00136   \
00137 node_type##_t* name##_Pop( name##_p name ) \
00138 { \
00139   struct node_type##_s* ret; \
00140   MUTEX_LOCK(name->lock); \
00141   if (name->size <= 0) { \
00142     MUTEX_UNLOCK(name->lock); \
00143     return NULL; \
00144   } \
00145   ret = ListPop(name->list); \
00146   name->size--; \
00147   COND_SIGNAL(name->cond); \
00148   MUTEX_UNLOCK(name->lock); \
00149   return ret; \
00150 } \
00151   \
00152 struct node_type##_s* name##_SearchIndex( name##_p name, int index ) \
00153 { \
00154   struct node_type##_s* node; \
00155   MUTEX_LOCK(name->lock); \
00156   node = (node_type##_t*)ListSearch(name->list, index); \
00157   MUTEX_UNLOCK(name->lock); \
00158   return node; \
00159 } \
00160   \
00161 int name##_RemoveIndex( name##_p name, int index ) \
00162 { \
00163   struct node_type##_s* node; \
00164   MUTEX_LOCK(name->lock); \
00165   node = ListDelete(name->list, index); \
00166   node_type##_Destroy(node); \
00167   name->size--; \
00168   MUTEX_UNLOCK(name->lock); \
00169   return 0; \
00170 } 
00171 
00172 #define AP_QUEUE_SEARCH_TEMPLATE( name, func_name, node_type, \
00173     search_type, search_expression ) \
00174 struct node_type##_s* name##_##func_name( name##_p name, const search_type key ) \
00175 { \
00176   listNode_t* parsenode; \
00177   struct node_type##_s* node; \
00178   struct node_type##_s* ret = NULL; \
00179   node = NULL; \
00180   \
00181   MUTEX_LOCK(name->lock); \
00182   if (name->list->listhead == NULL) { \
00183     MUTEX_UNLOCK(name->lock); \
00184     return NULL; \
00185   } \
00186   for( \
00187       parsenode = (listNode_t*)name->list->listhead; \
00188       parsenode != NULL; \
00189       parsenode = (listNode_t*)parsenode->next \
00190      ) \
00191   { \
00192     node = (node_type##_t*)parsenode->node_data; \
00193     if (search_expression){ \
00194       ret = node; \
00195       break; \
00196     } \
00197   } \
00198   MUTEX_UNLOCK(name->lock); \
00199   return ret; \
00200 } 
00201 
00202 #define AP_QUEUE_REMOVE_TEMPLATE( name, func_name, node_type, \
00203     search_type, search_expression) \
00204 int name##_##func_name( name##_p name, const search_type key ) \
00205 { \
00206   int err_code = MC_ERR_NOT_FOUND; \
00207   struct listNode_s* parsenode; \
00208   struct node_type##_s* node; \
00209   node = NULL; \
00210   \
00211   MUTEX_LOCK(name->lock); \
00212   if (name->list->listhead == NULL) { \
00213     MUTEX_UNLOCK(name->lock); \
00214     return MC_ERR_NOT_FOUND; \
00215   } \
00216   for( \
00217       parsenode = (listNode_t*)name->list->listhead; \
00218       parsenode->next != NULL; \
00219       parsenode = (listNode_t*)parsenode->next \
00220      ) \
00221   { \
00222     node = (node_type##_t*)parsenode->node_data; \
00223     if (search_expression) { \
00224       break; \
00225       err_code = MC_SUCCESS; \
00226     } \
00227   } \
00228   MUTEX_UNLOCK(name->lock); \
00229   return err_code; \
00230 }
00231 #endif