Changeset 3690
- Timestamp:
- 10/23/10 14:57:51 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/module-obj-llist.h
r3689 r3690 1 1 /* 2 * module-obj-llist. c2 * module-obj-llist.h 3 3 * 4 4 * Created on: 23.04.2010 … … 6 6 */ 7 7 8 #include <string.h> 9 #include <stdlib.h> 10 #include "module-obj-llist.h" 11 #include "globals.h" 8 #ifndef OSCAMLLIST_D__H_ 9 #define OSCAMLLIST_D__H_ 12 10 13 LLIST_D_ *llist_create(void) 14 { 15 LLIST_D_ *l = malloc(sizeof(LLIST_D_)); 16 if (!l) 17 return NULL; 18 memset(l, 0, sizeof(LLIST_D_)); 11 /******************************** */ 12 /* LINKED LIST CODE - IF IT'S USEFUL ELSEWHERE, IT SHOULD BE SPLIT OFF INTO linkedlist.h/.c */ 13 /******************************** */ 19 14 20 pthread_mutex_init(&l->lock, NULL); 15 // Simple, doubly linked 16 // This is thread-safe, so requires pthread. Also expect locking if iterators are not destroyed. 21 17 22 l->items = 0; 18 #include <pthread.h> 23 19 24 return l; 25 } 20 struct llist_node { 21 void *obj; 22 struct llist_node *prv; 23 struct llist_node *nxt; 24 }; 26 25 27 void llist_destroy(LLIST_D_ *l) 28 { 29 LLIST_D__ITR itr; 30 if (!l) 31 return; 32 void *o = llist_itr_init(l, &itr); 33 while (o) { 34 free(o); 35 o = llist_itr_remove(&itr); 36 } 37 pthread_mutex_destroy(&l->lock); 38 free(l); 39 } 26 typedef struct llist_d { 27 struct llist_node *first; 28 struct llist_node *last; 29 int items; 30 pthread_mutex_t lock; 31 } LLIST_D_; 40 32 41 void llist_clear(LLIST_D_ *l) 42 { 43 LLIST_D__ITR itr; 44 if (!l) 45 return; 46 void *o = llist_itr_init(l, &itr); 47 while (o) { 48 free(o); 49 o = llist_itr_remove(&itr); 50 } 51 pthread_mutex_destroy(&l->lock); 52 } 33 typedef struct llist_itr { 34 LLIST_D_ *l; 35 struct llist_node *cur; 36 } LLIST_D__ITR; 53 37 54 void *llist_append(LLIST_D_ *l, void *o) 55 { 56 if (!l) 57 return NULL; 58 pthread_mutex_lock(&l->lock); 59 if (o) { 60 struct llist_node *ln = malloc(sizeof(struct llist_node)); 61 if (!ln) { 62 pthread_mutex_unlock(&l->lock); 63 return NULL; 64 } 38 LLIST_D_ *llist_create(void); // init linked list 39 void llist_destroy(LLIST_D_ *l); // de-init linked list - frees all objects on the list 40 void llist_clear(LLIST_D_ *l); // frees all objects on the list 65 41 66 memset(ln, 0, sizeof(struct llist_node)); 67 ln->obj = o; 42 void *llist_append(LLIST_D_ *l, void *o); // append object onto bottom of list, returns ptr to obj 43 void *llist_insert_first(LLIST_D_ *l, void *o); // append object onto bottom of list, returns ptr to obj 68 44 69 if (l->last) { 70 ln->prv = l->last; 71 ln->prv->nxt = ln; 72 } else { 73 l->first = ln; 74 } 75 l->last = ln; 45 void *llist_itr_init(LLIST_D_ *l, LLIST_D__ITR *itr); // linked list iterator, returns ptr to first obj 46 //void llist_itr_release(LLIST_D__ITR *itr); // release iterator 47 void *llist_itr_next(LLIST_D__ITR *itr); // iterates, returns ptr to next obj 76 48 77 l->items++; 78 } 79 pthread_mutex_unlock(&l->lock); 49 void *llist_itr_insert(LLIST_D__ITR *itr, void *o); // insert object at itr point, iterates to and returns ptr to new obj 50 void *llist_itr_remove(LLIST_D__ITR *itr); // remove obj at itr, iterates to and returns ptr to next obj 80 51 81 return o; 82 } 52 int llist_count(LLIST_D_ *l); // returns number of obj in list 83 53 84 void *llist_insert_first(LLIST_D_ *l, void *o) 85 { 86 if (!l) 87 return NULL; 88 pthread_mutex_lock(&l->lock); 89 if (o) { 90 struct llist_node *ln = malloc(sizeof(struct llist_node)); 91 if (!ln) { 92 pthread_mutex_unlock(&l->lock); 93 return NULL; 94 } 95 96 memset(ln, 0, sizeof(struct llist_node)); 97 ln->obj = o; 98 99 if (l->first) { 100 ln->nxt = l->first; 101 ln->nxt->prv = ln; 102 } else { 103 l->last = ln; 104 } 105 l->first = ln; 106 107 l->items++; 108 } 109 pthread_mutex_unlock(&l->lock); 110 111 return o; 112 } 113 114 void *llist_itr_init(LLIST_D_ *l, LLIST_D__ITR *itr) 115 { 116 if (!l || !itr) 117 return NULL; 118 // pthread_mutex_lock(&l->lock); 119 if (l->first) { 120 121 memset(itr, 0, sizeof(LLIST_D__ITR)); 122 itr->cur = l->first; 123 itr->l = l; 124 125 return itr->cur->obj; 126 } 127 128 return NULL; 129 } 130 /* 131 void llist_itr_release(LLIST_D__ITR *itr) 132 { 133 // pthread_mutex_unlock(&itr->l->lock); 134 } 135 */ 136 void *llist_itr_next(LLIST_D__ITR *itr) 137 { 138 if (itr->cur->nxt) { 139 itr->cur = itr->cur->nxt; 140 return itr->cur->obj; 141 } 142 143 return NULL; 144 } 145 146 void *llist_itr_remove(LLIST_D__ITR *itr) // this needs cleaning - I was lazy 147 { 148 if (!itr || !itr->l || itr->l->items == 0) 149 return NULL; 150 itr->l->items--; 151 if ((itr->cur == itr->l->first) && (itr->cur == itr->l->last)) { 152 NULLFREE(itr->cur); 153 itr->l->first = NULL; 154 itr->l->last = NULL; 155 return NULL; 156 } else if (itr->cur == itr->l->first) { 157 struct llist_node *nxt = itr->cur->nxt; 158 NULLFREE(itr->cur); 159 nxt->prv = NULL; 160 itr->l->first = nxt; 161 itr->cur = nxt; 162 } else if (itr->cur == itr->l->last) { 163 itr->l->last = itr->cur->prv; 164 itr->l->last->nxt = NULL; 165 NULLFREE(itr->cur); 166 return NULL; 167 } else { 168 struct llist_node *nxt = itr->cur->nxt; 169 itr->cur->prv->nxt = itr->cur->nxt; 170 itr->cur->nxt->prv = itr->cur->prv; 171 NULLFREE(itr->cur); 172 itr->cur = nxt; 173 } 174 175 return itr->cur->obj; 176 } 177 178 int llist_count(LLIST_D_ *l) 179 { 180 return l->items; 181 } 182 54 #endif /* OSCAMLLIST_D__H_ */
Note:
See TracChangeset
for help on using the changeset viewer.