00001 #include <stdio.h>
00002 #include <stdlib.h>
00003
00004 #include "hsqueue.h"
00005 #include "hsqlist.h"
00006 #include "hlog.h"
00007 #include "hprocess.h"
00008 #include "hsignal.h"
00009
00010
00016 struct hsqueue {
00018 int processes_num;
00020 int parent_list;
00022 struct hprocess* first_process;
00024 struct hprocess* last_process;
00026 struct hsqueue* next;
00028 struct hsqueue* prev;
00029 };
00030
00031 static int set_first_process_(struct hsqueue* queue, struct hprocess* process);
00032 static int set_last_process_(struct hsqueue* queue, struct hprocess* process);
00033 static int increment_size_(struct hsqueue* queue);
00034 static int decrement_size_(struct hsqueue* queue);
00035 static int set_size_(struct hsqueue* queue, int number);
00036 static int set_prev_(struct hsqueue* element, struct hsqueue* element_prev);
00037 static int set_next_(struct hsqueue* element, struct hsqueue* element_next);
00038
00053 static int add_queue_callback_(struct hsqueue* queue, struct hsqueue* queue_prev, struct hsqueue* queue_next, int list);
00054
00055 static int remove_queue_callback_(struct hsqueue* queue);
00056
00057 static int set_parent_list_(struct hsqueue* queue, int list);
00058
00065 static int (*signal_enqueue_process_)();
00066
00067 static int (*signal_remove_process_)();
00068
00069
00070 static int add_queue_callback_(struct hsqueue* queue, struct hsqueue* queue_prev, struct hsqueue* queue_next, int list)
00071 {
00072 set_parent_list_(queue, list);
00073 set_prev_(queue, queue_prev);
00074 set_next_(queue, queue_next);
00075 set_prev_(queue_next, queue);
00076 set_next_(queue_prev, queue);
00077
00078 return 0;
00079 }
00080
00081
00082 static int remove_queue_callback_(struct hsqueue* queue)
00083 {
00084 if (queue == NULL)
00085 return -1;
00086
00087
00088
00089 struct hsqueue* prev = hsqueue_get_prev(queue);
00090 struct hsqueue* next = hsqueue_get_next(queue);
00091 set_prev_(next, prev);
00092 set_next_(prev, next);
00093
00094 free(queue);
00095
00096 return 0;
00097 }
00098
00099
00100 static int set_prev_(struct hsqueue* element, struct hsqueue* element_prev)
00101 {
00102 if (element == NULL)
00103 return -1;
00104
00105 element->prev = element_prev;
00106 return 0;
00107 }
00108
00109
00110 static int set_next_(struct hsqueue* element, struct hsqueue* element_next)
00111 {
00112 if (element == NULL)
00113 return -1;
00114
00115 element->next = element_next;
00116 return 0;
00117 }
00118
00119
00120 static int set_first_process_(struct hsqueue* queue, struct hprocess* process)
00121 {
00122 if (queue == NULL)
00123 return -1;
00124
00125 queue->first_process = process;
00126 return 0;
00127 }
00128
00129
00130 static int set_last_process_(struct hsqueue* queue, struct hprocess* process)
00131 {
00132 if (queue == NULL)
00133 return -1;
00134
00135 queue->last_process = process;
00136 return 0;
00137 }
00138
00139
00140 static int increment_size_(struct hsqueue* queue)
00141 {
00142 if (queue == NULL)
00143 return -1;
00144
00145 queue->processes_num += 1;
00146
00147 return queue->processes_num;
00148 }
00149
00150
00151 static int decrement_size_(struct hsqueue* queue)
00152 {
00153 if (queue == NULL)
00154 return -1;
00155
00156 if (queue->processes_num < 1) {
00157 queue->processes_num = 0;
00158 return 0;
00159 }
00160
00161 queue->processes_num = queue->processes_num - 1;
00162
00163 return queue->processes_num;
00164 }
00165
00166
00167 static int set_size_(struct hsqueue* queue, int number)
00168 {
00169 if (queue == NULL)
00170 return -1;
00171
00172 queue->processes_num = number;
00173
00174 return queue->processes_num;
00175 }
00176
00177
00178 static int set_parent_list_(struct hsqueue* queue, int list)
00179 {
00180 if (queue == NULL)
00181 return -1;
00182
00183 queue->parent_list = list;
00184
00185 return 0;
00186 }
00187
00188
00189 int hsqueue_register_signal(int signal, int (*function)())
00190 {
00191 switch (signal) {
00192 case HSIGNAL_ADD_PROCESS:
00193 signal_enqueue_process_ = function;
00194 return 0;
00195 case HSIGNAL_REMOVE_PROCESS:
00196 signal_remove_process_ = function;
00197 return 0;
00198 default:
00199 return -1;
00200 }
00201
00202 return -1;
00203 }
00204
00205
00206 int hsqueue_get_parent_list(struct hsqueue* queue)
00207 {
00208 if (queue == NULL)
00209 return -1;
00210 else if (queue->parent_list < 0)
00211 return -1;
00212
00213 return queue->parent_list;
00214 }
00215
00216
00217 int hsqueue_size(struct hsqueue* element)
00218 {
00219 if (element == NULL)
00220 return -1;
00221
00222 return element->processes_num;
00223 }
00224
00225
00226 int hsqueue_get_state(struct hsqueue* queue)
00227 {
00228 return hprocess_get_state( hsqueue_get_first_process(queue) );
00229 }
00230
00231
00232 struct hsqueue* hsqueue_get_prev(struct hsqueue* element)
00233 {
00234 if (element == NULL)
00235 return NULL;
00236
00237 return (struct hsqueue*)(element->prev);
00238 }
00239
00240
00241 struct hsqueue* hsqueue_get_next(struct hsqueue* element)
00242 {
00243 if (element == NULL)
00244 return NULL;
00245
00246 return element->next;
00247 }
00248
00249
00250 struct hsqueue* hsqueue_create()
00251 {
00252 struct hsqueue* queue = calloc(1, sizeof(*queue));
00253 set_next_(queue, NULL);
00254 set_prev_(queue, NULL);
00255 set_first_process_(queue, NULL);
00256 set_last_process_(queue, NULL);
00257 set_size_(queue, 0);
00258 set_parent_list_(queue, -1);
00259
00260 hsqlist_register_signal(HSIGNAL_ADD_QUEUE, add_queue_callback_);
00261 hsqlist_register_signal(HSIGNAL_REMOVE_QUEUE, remove_queue_callback_);
00262
00263 return queue;
00264 }
00265
00266
00267 int hsqueue_enqueue_process(struct hsqueue* queue, struct hprocess* process)
00268 {
00269 if (process == NULL)
00270 return -1;
00271
00272 struct hprocess* last_process = hsqueue_get_last_process(queue);
00273
00274
00275 signal_enqueue_process_(process, last_process);
00276
00277 if (last_process == NULL) {
00278 set_first_process_(queue, process);
00279 }
00280
00281 set_last_process_(queue, process);
00282
00283 return increment_size_(queue);
00284 }
00285
00286
00287 int hsqueue_remove_process(struct hsqueue* queue, struct hprocess* process)
00288 {
00292
00293 if (process == NULL)
00294 return -1;
00295
00296 if (process == hsqueue_get_first_process(queue))
00297 set_first_process_(queue, hprocess_get_next(process));
00298
00299 if (process == hsqueue_get_last_process(queue))
00300 set_last_process_(queue, hprocess_get_prev(process));
00301
00302 decrement_size_(queue);
00303
00304
00305 signal_remove_process_(process);
00306
00307 return 0;
00308 }
00309
00310 struct hprocess* hsqueue_dequeue_process(struct hsqueue* queue)
00311 {
00312 if (queue == NULL)
00313 return NULL;
00314
00316 struct hprocess* process = hsqueue_get_first_process(queue);
00317 if (hsqueue_remove_process(queue, process) == 0)
00318 return process;
00319 else
00320 return NULL;
00321 }
00322
00323 int hsqueue_remove(struct hsqueue* queue)
00324 {
00325 if (queue == NULL)
00326 return -1;
00327
00328
00329 return hsqlist_remove_queue(hsqueue_get_parent_list(queue), queue);
00330 }
00331
00332
00333 struct hprocess* hsqueue_get_first_process(struct hsqueue* queue)
00334 {
00335 if (queue == NULL)
00336 return NULL;
00337
00338 return queue->first_process;
00339 }
00340
00341
00342 struct hprocess* hsqueue_get_last_process(struct hsqueue* queue)
00343 {
00344 if (queue == NULL)
00345 return NULL;
00346
00347 return queue->last_process;
00348 }
00349