00001
00002
00003
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <sys/msg.h>
00011
00012 #include "hmqueue.h"
00013 #include "hlog.h"
00014
00015
00016 struct hmqueue
00017 {
00018 struct hmqueue *next;
00019 struct hmqueue *prev;
00020 int key;
00021 int id;
00022 };
00023
00024
00026 int queue_cnt = 0;
00028 struct hmqueue* firstq = NULL;
00029 struct hmqueue* lastq = NULL;
00030
00031 static int set_prev_(struct hmqueue* element, struct hmqueue* element_prev);
00032 static int set_next_(struct hmqueue* element, struct hmqueue* element_next);
00033 static int create_mqueue_(int key, int msgflg);
00034 static int set_id_(struct hmqueue* element, int id);
00035 static int set_key_(struct hmqueue* element, int key);
00036
00037
00038 static int set_prev_(struct hmqueue* element, struct hmqueue* element_prev)
00039 {
00040 if (element == NULL)
00041 return -1;
00042
00043 element->prev = element_prev;
00044 return 0;
00045 }
00046
00047
00048 static int set_next_(struct hmqueue* element, struct hmqueue* element_next)
00049 {
00050 if (element == NULL)
00051 return -1;
00052
00053 element->next = element_next;
00054 return 0;
00055 }
00056
00057
00058 static int create_mqueue_(int key, int msgflg)
00059 {
00060 int msqid;
00061 msqid = msgget((key_t)key, msgflg);
00062
00063 if (msqid < 0) {
00064 hlog_write(HLOG_ERROR, "create_mqueue_: Can't create/connect to message queue.\n");
00065 return -1;
00066 } else {
00067 hlog_write(HLOG_DEBUG, "create_mqueue_: Message queue created. key=");
00068 hlog_write_integer(key);
00069 hlog_write_text(". msqid=");
00070 hlog_write_integer(msqid);
00071 hlog_write_text(". msgflg=");
00072 hlog_write_integer(msgflg);
00073 hlog_write_text(".\n");
00074 }
00075
00076 return msqid;
00077 }
00078
00079
00080 static int set_id_(struct hmqueue* element, int id)
00081 {
00082 if (element == NULL)
00083 return -1;
00084
00085 element->id = id;
00086
00087 return 0;
00088 }
00089
00090
00091 static int set_key_(struct hmqueue* element, int key)
00092 {
00093 if (element == NULL)
00094 return -1;
00095
00096 element->key = key;
00097
00098 return 0;
00099 }
00100
00101
00102 int hmqueue_size()
00103 {
00104 return queue_cnt;
00105 }
00106
00107
00108 struct hmqueue* hmqueue_get_prev(struct hmqueue* element)
00109 {
00110 if (element == NULL)
00111 return NULL;
00112
00113 return (struct hmqueue*)(element->prev);
00114 }
00115
00116
00117 struct hmqueue* hmqueue_get_next(struct hmqueue* element)
00118 {
00119 if (element == NULL)
00120 return NULL;
00121
00122 return element->next;
00123 }
00124
00125
00126 int hmqueue_get_key(struct hmqueue* element)
00127 {
00128 if (element == NULL)
00129 return -1;
00130
00131 return element->key;
00132 }
00133
00134
00135 int hmqueue_get_id(struct hmqueue* element)
00136 {
00137 if (element == NULL)
00138 return -1;
00139
00140 return element->id;
00141 }
00142
00143
00144 struct hmqueue* hmqueue_get(int key)
00145 {
00146 if (hmqueue_size() == 0)
00147 return NULL;
00148
00149 struct hmqueue* queue;
00150 queue = hmqueue_get_first();
00151 if (hmqueue_get_key(queue) == key)
00152 return queue;
00153
00154 while (hmqueue_get_next(queue) != NULL) {
00155 queue = hmqueue_get_next(queue);
00156 if (hmqueue_get_key(queue) == key)
00157 return queue;
00158 }
00159
00160 return NULL;
00161 }
00162
00163 int hmqueue_get_id_by_key (int key)
00164 {
00165 if(hmqueue_size() == 0)
00166 return -1;
00167
00168 struct hmqueue *it;
00169 it = hmqueue_get_first();
00170 if (hmqueue_get_key(it) == key)
00171 return hmqueue_get_id(it);
00172 while(1) {
00173
00174 if(hmqueue_get_next(it) == NULL)
00175 return -1;
00176
00177 it = hmqueue_get_next(it);
00178 if (hmqueue_get_key(it) == key)
00179 return hmqueue_get_id(it);
00180 }
00181 }
00182
00183
00184 struct hmqueue* hmqueue_add(int key, enum hmqueue_mode mode)
00185 {
00186
00187 int nr_removed = 0;
00188 while (hmqueue_remove_by_key(key) == 0) {
00189 nr_removed += 1;
00190 if (nr_removed > 10)
00191 return NULL;
00192 }
00193
00194 int msgflg = -1;
00195 if (mode == HMQ_CREATE)
00196 msgflg = IPC_CREAT | 0666;
00197 else if (mode == HMQ_CONNECT)
00198 msgflg = 0666;
00199 else
00200 return NULL;
00201
00202 struct hmqueue* queue = calloc(1, sizeof(*queue));
00203 int msqid = create_mqueue_(key, msgflg);
00204
00205 set_key_(queue, key);
00206 set_id_(queue, msqid);
00207 set_next_(queue, NULL);
00208 set_prev_(queue, NULL);
00209
00210 if(hmqueue_size() == 0) {
00211
00212 firstq = queue;
00213 lastq = queue;
00214 } else {
00215
00216 set_next_(hmqueue_get_last(), queue);
00217 set_prev_(queue, hmqueue_get_last());
00218 lastq = queue;
00219 }
00220
00221 queue_cnt++;
00222
00223 return queue;
00224 }
00225
00226
00227 int hmqueue_remove(struct hmqueue* element)
00228 {
00229 if (element == NULL)
00230 return -1;
00231
00232 hlog_write(HLOG_DEBUG, "hmqueue_remove: Removing queue with id=");
00233 hlog_write_integer(hmqueue_get_id(element));
00234 hlog_write_text("\n");
00235
00236 if (hmqueue_get_id(element) > 0)
00237 msgctl(hmqueue_get_id(element), IPC_RMID, NULL);
00238
00239 if (hmqueue_size() < 1) {
00241 hlog_write(HLOG_ERROR, "hmqueue_remove: Invalid list structure (-2).\n");
00242 return -2;
00243 } else if (hmqueue_size() == 1) {
00244
00245 free(element);
00246 firstq = NULL;
00247 lastq = NULL;
00248 queue_cnt = 0;
00249 } else {
00250
00251 struct hmqueue* element_prev = hmqueue_get_prev(element);
00252 struct hmqueue* element_next = hmqueue_get_next(element);
00253 if (element_prev == NULL && element_next != NULL) {
00254
00255 firstq = element_next;
00256 set_prev_( element_next, NULL );
00257 } else if (element_next == NULL && element_prev != NULL) {
00258
00259 lastq = element_prev;
00260 set_next_( element_prev, NULL);
00261 } else if (element_next != NULL && element_prev != NULL) {
00262
00263
00265 set_prev_( element_next, element_prev );
00266 set_next_( element_prev, element_next );
00267
00268 } else {
00269
00270 hlog_write(HLOG_ERROR, "hmqueue_remove: Invalid list structure (-3).\n");
00271 return -3;
00272 }
00273
00274 free(element);
00275 queue_cnt--;
00276 }
00277
00278 return 0;
00279 }
00280
00281
00282 int hmqueue_remove_by_key(int key)
00283 {
00284 struct hmqueue* element = hmqueue_get(key);
00285 return hmqueue_remove(element);
00286 }
00287
00288
00289 int hmqueue_remove_all()
00290 {
00291 struct hmqueue* it = hmqueue_get_first();
00292 struct hmqueue* it_prev = NULL;
00293
00294 int ret = 0;
00295 while (hmqueue_get_next(it) != NULL) {
00296 it = hmqueue_get_next(it);
00297 it_prev = hmqueue_get_prev(it);
00298 if (hmqueue_remove(it_prev) < 0)
00299 ret = -1;
00300 }
00301
00302 if (hmqueue_remove (it) < 0)
00303 ret = -1;
00304
00305 return ret;
00306 }
00307
00308
00309 struct hmqueue* hmqueue_get_first()
00310 {
00311 return firstq;
00312 }
00313
00314 struct hmqueue* hmqueue_get_last()
00315 {
00316 return lastq;
00317 }
00318
00319 int hmqueue_get_daemonkey()
00320 {
00321
00322 return 1234;
00323 }
00324
00325
00326
00327