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 #ifndef _XLV_LIST_H
00026 #define _XLV_LIST_H
00027
00028 #include <glib.h>
00029 #include <pthread.h>
00030
00031
00032
00033
00034
00035
00036 typedef struct _XLV_List XLV_List;
00037 typedef struct _XLV_ListIterator XLV_ListIterator;
00038 typedef XLV_List XLV_ListPool;
00039
00040
00041
00042
00043
00044 struct _XLV_List {
00045 XLV_ListIterator *m_first_element;
00046 XLV_ListIterator *m_last_element;
00047 XLV_ListPool *m_pool;
00048 guint32 m_n_elements;
00049 pthread_mutex_t m_mutex;
00050 };
00051
00052 struct _XLV_ListIterator {
00053 gpointer data;
00054 XLV_ListIterator *m_next;
00055 XLV_ListIterator *m_prev;
00056 };
00057
00058
00059
00060
00061
00062
00063
00064 static inline XLV_ListIterator *xlv_list_pool_get_node (XLV_ListPool * pool);
00065 static inline void xlv_list_pool_release_node (XLV_ListPool * pool,
00066 XLV_ListIterator * node);
00067
00068 static inline XLV_ListIterator *
00069 xlv_list_next (XLV_ListIterator * list)
00070 {
00071 return list->m_next;
00072 }
00073
00074 static inline XLV_ListIterator *
00075 xlv_list_prev (XLV_ListIterator * list)
00076 {
00077 return list->m_prev;
00078 }
00079
00080 static inline XLV_ListIterator *
00081 xlv_list_first (XLV_List * list)
00082 {
00083 return list->m_first_element;
00084 }
00085
00086 static inline XLV_ListIterator *
00087 xlv_list_last (XLV_List * list)
00088 {
00089 return list->m_last_element;
00090 }
00091
00092 static inline guint32
00093 xlv_list_length (XLV_List * list)
00094 {
00095 return list->m_n_elements;
00096 }
00097
00098 static inline XLV_List *
00099 xlv_list_new (XLV_ListPool * pool)
00100 {
00101 XLV_List *list;
00102
00103 list = g_new (XLV_List, 1);
00104 list->m_first_element = NULL;
00105 list->m_last_element = NULL;
00106 list->m_n_elements = 0;
00107 list->m_pool = pool;
00108 pthread_mutex_init (&list->m_mutex, NULL);
00109
00110 return list;
00111 }
00112
00113 static inline void
00114 xlv_list_free (XLV_List * list)
00115 {
00116 XLV_ListIterator *iter;
00117
00118 g_assert (list != NULL);
00119
00120 iter = xlv_list_first (list);
00121 while (iter != NULL) {
00122 XLV_ListIterator *next;
00123
00124 next = xlv_list_next (iter);
00125 xlv_list_pool_release_node (list->m_pool, iter);
00126 iter = next;
00127 }
00128
00129 pthread_mutex_destroy (&list->m_mutex);
00130 g_free (list);
00131 }
00132
00133 static inline void
00134 xlv_list_append (XLV_List * list, gpointer data)
00135 {
00136 XLV_ListIterator *iter;
00137
00138 g_assert (list != NULL);
00139
00140 pthread_mutex_lock (&list->m_mutex);
00141 iter = xlv_list_pool_get_node (list->m_pool);
00142 iter->data = data;
00143 iter->m_next = NULL;
00144 iter->m_prev = list->m_last_element;
00145
00146 if (list->m_last_element != NULL)
00147 list->m_last_element->m_next = iter;
00148
00149 list->m_last_element = iter;
00150
00151 if (list->m_first_element == NULL)
00152 list->m_first_element = iter;
00153
00154 list->m_n_elements++;
00155 pthread_mutex_unlock (&list->m_mutex);
00156 }
00157
00158 static inline XLV_ListIterator *
00159 xlv_list_find (XLV_List * list, gpointer data)
00160 {
00161 XLV_ListIterator *iter;
00162
00163 g_assert (list != NULL);
00164
00165 iter = xlv_list_first (list);
00166 while (iter != NULL) {
00167 if (iter->data == data)
00168 return iter;
00169 iter = xlv_list_next (iter);
00170 }
00171
00172 return NULL;
00173 }
00174
00175 static inline void
00176 xlv_list_remove_link (XLV_List * list, XLV_ListIterator * link)
00177 {
00178 g_assert (list != NULL);
00179 g_assert (link != NULL);
00180
00181 pthread_mutex_lock (&list->m_mutex);
00182
00183 list->m_n_elements--;
00184
00185 if (link->m_prev)
00186 link->m_prev->m_next = link->m_next;
00187 if (link->m_next)
00188 link->m_next->m_prev = link->m_prev;
00189
00190 if (link == list->m_first_element)
00191 list->m_first_element = link->m_next;
00192 if (link == list->m_last_element)
00193 list->m_last_element = link->m_prev;
00194
00195 xlv_list_pool_release_node (list->m_pool, link);
00196 pthread_mutex_unlock (&list->m_mutex);
00197 }
00198
00199 static inline void
00200 xlv_list_remove_all_links (XLV_List * list)
00201 {
00202 XLV_ListIterator *iter, *node;
00203
00204 iter = xlv_list_first (list);
00205 while (iter != NULL) {
00206 node = iter->m_next;
00207 xlv_list_pool_release_node (list->m_pool, iter);
00208 iter = node;
00209 }
00210
00211 list->m_first_element = NULL;
00212 list->m_last_element = NULL;
00213 list->m_n_elements = 0;
00214 }
00215
00216
00217
00218
00219
00220
00221 static inline XLV_ListPool *
00222 xlv_list_pool_new (guint32 elems)
00223 {
00224 XLV_ListPool *pool;
00225
00226 pool = xlv_list_new (NULL);
00227 for (; elems != 0; elems--)
00228 xlv_list_append (pool, NULL);
00229
00230 return pool;
00231 }
00232
00233 static inline void
00234 xlv_list_pool_free (XLV_ListPool * pool)
00235 {
00236 xlv_list_free (pool);
00237 }
00238
00239 static inline XLV_ListIterator *
00240 xlv_list_pool_get_node (XLV_ListPool * pool)
00241 {
00242 XLV_ListIterator *node;
00243
00244 if (pool && pool->m_first_element) {
00245 pthread_mutex_lock (&pool->m_mutex);
00246 pool->m_n_elements--;
00247
00248 node = pool->m_first_element;
00249 pool->m_first_element = node->m_next;
00250 if (pool->m_first_element)
00251 pool->m_first_element->m_prev = NULL;
00252 if (pool->m_last_element == node)
00253 pool->m_last_element = NULL;
00254 pthread_mutex_unlock (&pool->m_mutex);
00255
00256 return node;
00257 }
00258 node = g_new (XLV_ListIterator, 1);
00259
00260 return node;
00261 }
00262
00263 static inline void
00264 xlv_list_pool_release_node (XLV_ListPool * pool, XLV_ListIterator * node)
00265 {
00266 if (!pool) {
00267 g_free (node);
00268 return;
00269 }
00270
00271 pthread_mutex_lock (&pool->m_mutex);
00272 if (pool->m_first_element)
00273 pool->m_first_element->m_prev = node;
00274
00275 node->m_next = pool->m_first_element;
00276 node->m_prev = NULL;
00277 pool->m_first_element = node;
00278
00279 pool->m_n_elements++;
00280 pthread_mutex_unlock (&pool->m_mutex);
00281 }
00282
00283 #endif