]>
Commit | Line | Data |
---|---|---|
adca27eb JH |
1 | /** |
2 | * @file job_queue.c | |
79538669 | 3 | * |
adca27eb | 4 | * @brief Job-Queue based on linked_list_t |
79538669 | 5 | * |
adca27eb JH |
6 | */ |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
10 | * Hochschule fuer Technik Rapperswil | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify it | |
13 | * under the terms of the GNU General Public License as published by the | |
14 | * Free Software Foundation; either version 2 of the License, or (at your | |
15 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, but | |
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
19 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
20 | * for more details. | |
21 | */ | |
22 | ||
954d34e3 | 23 | #include <stdlib.h> |
adca27eb JH |
24 | #include <pthread.h> |
25 | #include <freeswan.h> | |
26 | #include <pluto/constants.h> | |
27 | #include <pluto/defs.h> | |
79538669 | 28 | |
6c4b815f | 29 | #include "allocator.h" |
adca27eb | 30 | #include "job_queue.h" |
b32ea284 | 31 | #include "linked_list.h" |
adca27eb | 32 | |
adca27eb JH |
33 | /** |
34 | * @brief Private Variables and Functions of job_queue class | |
79538669 | 35 | * |
adca27eb JH |
36 | */ |
37 | typedef struct private_job_queue_s private_job_queue_t; | |
79538669 | 38 | |
adca27eb JH |
39 | |
40 | struct private_job_queue_s { | |
41 | job_queue_t public; | |
79538669 | 42 | |
adca27eb JH |
43 | /** |
44 | * The jobs are stored in a linked list | |
45 | */ | |
46 | linked_list_t *list; | |
47 | /** | |
48 | * access to linked_list is locked through this mutex | |
49 | */ | |
50 | pthread_mutex_t mutex; | |
79538669 | 51 | |
adca27eb JH |
52 | /** |
53 | * If the queue is empty a thread has to wait | |
54 | * This condvar is used to wake up such a thread | |
55 | */ | |
79538669 | 56 | pthread_cond_t condvar; |
adca27eb JH |
57 | }; |
58 | ||
59 | ||
60 | /** | |
61 | * @brief implements function get_count of job_queue_t | |
62 | */ | |
ddd639f6 | 63 | static status_t get_count(private_job_queue_t *this, int *count) |
adca27eb | 64 | { |
adca27eb | 65 | pthread_mutex_lock(&(this->mutex)); |
7c2228f1 | 66 | this->list->get_count(this->list,count); |
adca27eb JH |
67 | pthread_mutex_unlock(&(this->mutex)); |
68 | return SUCCESS; | |
69 | } | |
70 | ||
71 | /** | |
72 | * @brief implements function get of job_queue_t | |
73 | */ | |
ddd639f6 | 74 | static status_t get(private_job_queue_t *this, job_t **job) |
adca27eb | 75 | { |
7c2228f1 | 76 | int count; |
db5dc986 | 77 | int oldstate; |
adca27eb | 78 | pthread_mutex_lock(&(this->mutex)); |
db5dc986 | 79 | /* go to wait while no jobs available */ |
7c2228f1 JH |
80 | this->list->get_count(this->list,&count); |
81 | while(count == 0) | |
adca27eb | 82 | { |
db5dc986 MW |
83 | /* add mutex unlock handler for cancellation, enable cancellation */ |
84 | pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex)); | |
85 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); | |
79538669 | 86 | |
adca27eb | 87 | pthread_cond_wait( &(this->condvar), &(this->mutex)); |
79538669 | 88 | |
db5dc986 MW |
89 | /* reset cancellation, remove mutex-unlock handler (without executing) */ |
90 | pthread_setcancelstate(oldstate, NULL); | |
91 | pthread_cleanup_pop(0); | |
7c2228f1 | 92 | this->list->get_count(this->list,&count); |
adca27eb JH |
93 | } |
94 | this->list->remove_first(this->list,(void **) job); | |
95 | pthread_mutex_unlock(&(this->mutex)); | |
96 | return SUCCESS; | |
97 | } | |
98 | ||
99 | /** | |
100 | * @brief implements function add of job_queue_t | |
101 | */ | |
ddd639f6 | 102 | static status_t add(private_job_queue_t *this, job_t *job) |
adca27eb | 103 | { |
adca27eb JH |
104 | pthread_mutex_lock(&(this->mutex)); |
105 | this->list->insert_last(this->list,job); | |
106 | pthread_cond_signal( &(this->condvar)); | |
107 | pthread_mutex_unlock(&(this->mutex)); | |
108 | return SUCCESS; | |
109 | } | |
110 | ||
111 | /** | |
112 | * @brief implements function destroy of job_queue_t | |
79538669 | 113 | * |
adca27eb | 114 | */ |
ddd639f6 | 115 | static status_t job_queue_destroy (private_job_queue_t *this) |
79538669 | 116 | { |
7c2228f1 JH |
117 | int count; |
118 | this->list->get_count(this->list,&count); | |
79538669 JH |
119 | |
120 | while (count > 0) | |
adca27eb JH |
121 | { |
122 | job_t *job; | |
123 | if (this->list->remove_first(this->list,(void *) &job) != SUCCESS) | |
124 | { | |
125 | this->list->destroy(this->list); | |
126 | break; | |
127 | } | |
128 | job->destroy(job); | |
7c2228f1 | 129 | this->list->get_count(this->list,&count); |
adca27eb JH |
130 | } |
131 | this->list->destroy(this->list); | |
79538669 | 132 | |
adca27eb | 133 | pthread_mutex_destroy(&(this->mutex)); |
79538669 | 134 | |
adca27eb | 135 | pthread_cond_destroy(&(this->condvar)); |
79538669 JH |
136 | |
137 | allocator_free(this); | |
adca27eb JH |
138 | return SUCCESS; |
139 | } | |
140 | ||
141 | /* | |
79538669 | 142 | * |
adca27eb JH |
143 | * Documented in header |
144 | */ | |
145 | job_queue_t *job_queue_create() | |
146 | { | |
147 | linked_list_t *linked_list = linked_list_create(); | |
148 | if (linked_list == NULL) | |
149 | { | |
150 | return NULL; | |
151 | } | |
79538669 | 152 | |
6c4b815f | 153 | private_job_queue_t *this = allocator_alloc_thing(private_job_queue_t); |
adca27eb JH |
154 | if (this == NULL) |
155 | { | |
156 | linked_list->destroy(linked_list); | |
157 | return NULL; | |
158 | } | |
79538669 | 159 | |
16b46908 MW |
160 | this->public.get_count = (status_t(*)(job_queue_t*, int*))get_count; |
161 | this->public.get = (status_t(*)(job_queue_t*, job_t**))get; | |
162 | this->public.add = (status_t(*)(job_queue_t*, job_t*))add; | |
163 | this->public.destroy = (status_t(*)(job_queue_t*))job_queue_destroy; | |
79538669 | 164 | |
adca27eb JH |
165 | this->list = linked_list; |
166 | pthread_mutex_init(&(this->mutex), NULL); | |
167 | pthread_cond_init(&(this->condvar), NULL); | |
79538669 | 168 | |
adca27eb JH |
169 | return (&this->public); |
170 | } |