]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_requests_queue.c
starting to build the negotiations infrastructure
[frescor/fna.git] / src_frescan / frescan_requests_queue.c
1 /*!
2  * @file frescan_requests_queue.c
3  *
4  * @brief FRESCAN requests queue
5  *
6  * This module contains an operation to create the queue, an operation to
7  * enqueue a message (with a request), and an operation to
8  * dequeue a message.
9  *
10  * @version 0.01
11  *
12  * @date 1-Apr-2008
13  *
14  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
15  *
16  */
17
18 #include <misc/freelist.h>
19 #include <misc/linux_list.h>
20 #include "frescan.h"
21 #include "frescan_requests_queue.h"
22 #include "frescan_config.h"
23 #include "fosa_mutexes_and_condvars.h"
24
25 static bool is_initialized = false;
26
27 /**
28  * the_requests_pool
29  *
30  * We will use a freelist to allocate and free the requests.
31  *
32  **/
33
34 struct request_t {
35         frescan_req_type_t  type;
36         frescan_robj_id_t   reply;
37         frescan_contract_t  *contract;
38         frescan_node_t      src;
39         struct list_head    request_list;
40         int pool_pos;
41 };
42
43 static fosa_mutex_t requests_mutex;
44 static fosa_cond_t  requests_cond;
45
46 static struct request_t the_requests_pool[FRESCAN_MX_REQUESTS];
47 static freelist_t freelist;
48 static struct request_t the_requests_list;
49
50 /**
51  * frescan_requests_init()
52  *
53  * Init the freelist, requests list, cond var and mutex.
54  *
55  **/
56
57 int frescan_requests_init(int max_ceiling)
58 {
59         int err;
60
61         err = fosa_mutex_init(&requests_mutex, max_ceiling);
62         if (err != 0) return err;
63
64         err = fosa_cond_init(&requests_cond);
65         if (err != 0) return err;
66
67         err = freelist_init(&freelist, FRESCAN_MX_REQUESTS);
68         if (err != 0) return err;
69
70         INIT_LIST_HEAD(&the_requests_list.request_list);
71
72         is_initialized = true;
73         return 0;
74 }
75
76 /**
77  * frescan_request_alloc()
78  *
79  * Allocate a request with the mutex locked
80  *
81  **/
82
83 int frescan_request_alloc(frescan_request_id_t *id)
84 {
85         int err, pos;
86
87         if (is_initialized == false) return -1;
88
89         err = fosa_mutex_lock(&requests_mutex);
90         if (err != 0) return err;
91
92                 pos = freelist_alloc(&freelist);
93                 if (pos < 0) goto locked_error;
94
95         err = fosa_mutex_unlock(&requests_mutex);
96         if (err != 0) return err;
97
98         *id = (unsigned int)pos;
99         the_requests_pool[*id].pool_pos = pos;
100
101         return 0;
102
103 locked_error:
104         fosa_mutex_unlock(&requests_mutex);
105         return pos;
106 }
107
108 /**
109  * frescan_request_free()
110  *
111  * free the request from the pool
112  *
113  **/
114
115 int frescan_request_free(frescan_request_id_t id)
116 {
117         int err;
118
119         if (is_initialized == false) return -1;
120
121         err = fosa_mutex_lock(&requests_mutex);
122         if (err != 0) return err;
123
124                 err = freelist_free(&freelist, id);
125                 if (err != 0) goto locked_error;
126
127         err = fosa_mutex_unlock(&requests_mutex);
128         if (err != 0) return err;
129
130         return 0;
131
132 locked_error:
133         fosa_mutex_unlock(&requests_mutex);
134         return err;
135 }
136
137 /**
138  * frescan_request_set_type()
139  *
140  **/
141
142 int frescan_request_set_type(frescan_request_id_t id, frescan_req_type_t type)
143 {
144         the_requests_pool[id].type = type;
145         return 0;
146 }
147
148 /**
149  * frescan_request_set_reply()
150  *
151  **/
152
153 int frescan_request_set_reply(frescan_request_id_t id, frescan_robj_id_t reply)
154 {
155         the_requests_pool[id].reply = reply;
156         return 0;
157 }
158
159 /**
160  * frescan_request_set_contract()
161  *
162  **/
163
164 int frescan_request_set_contract(frescan_request_id_t id,
165                                  frescan_contract_t *contract)
166 {
167         the_requests_pool[id].contract = contract;
168         return 0;
169 }
170
171 /**
172  * frescan_request_set_src()
173  *
174  **/
175
176 int frescan_request_set_src(frescan_request_id_t id, frescan_node_t src)
177 {
178         the_requests_pool[id].src = src;
179         return 0;
180 }
181
182 /**
183  * frescan_request_get_type()
184  *
185  **/
186
187 int frescan_request_get_type(frescan_request_id_t id, frescan_req_type_t *type)
188 {
189         *type = the_requests_pool[id].type;
190         return 0;
191 }
192
193 /**
194  * frescan_request_get_reply()
195  *
196  **/
197
198 int frescan_request_get_reply(frescan_request_id_t id, frescan_robj_id_t *reply)
199 {
200         *reply = the_requests_pool[id].reply;
201         return 0;
202 }
203
204 /**
205  * frescan_request_get_contract()
206  *
207  **/
208
209 int frescan_request_get_contract(frescan_request_id_t id,
210                                  frescan_contract_t **contract)
211 {
212         *contract = the_requests_pool[id].contract;
213         return 0;
214 }
215
216 /**
217  * frescan_request_get_src()
218  *
219  **/
220
221 int frescan_request_get_src(frescan_request_id_t id, frescan_node_t *src)
222 {
223         *src = the_requests_pool[id].src;
224         return 0;
225 }
226
227 /**
228  * frescan_requestqueue_enqueue()
229  *
230  **/
231
232 int frescan_requestqueue_enqueue(frescan_request_id_t id)
233 {
234         int err;
235
236         err = fosa_mutex_lock(&requests_mutex);
237         if (err != 0) return err;
238
239         list_add_tail(&the_requests_list.request_list,
240                       &the_requests_pool[id].request_list);
241
242         err = fosa_cond_signal(&requests_cond);
243         if (err != 0) goto locked_error;
244
245         err = fosa_mutex_unlock(&requests_mutex);
246         if (err != 0) return err;
247
248         return 0;
249
250 locked_error:
251         fosa_mutex_unlock(&requests_mutex);
252         return err;
253 }
254
255 /**
256  * frescan_requestqueue_dequeue()
257  *
258  **/
259
260 int frescan_requestqueue_dequeue(frescan_request_id_t *id)
261 {
262         int err;
263         struct list_head *pos;
264         struct request_t *request;
265
266         err = fosa_mutex_lock(&requests_mutex);
267         if (err != 0) return err;
268
269         while (list_empty(&the_requests_pool[*id].request_list)) {
270                 err = fosa_cond_wait(&requests_cond, &requests_mutex);
271                 if (err != 0) goto locked_error;
272         }
273
274         list_for_each(pos, &the_requests_pool[*id].request_list) {
275                 request = list_entry(pos, struct request_t, request_list);
276                 break;
277         }
278
279         list_del(&request->request_list);
280
281         *id = request->pool_pos;
282
283         err = fosa_mutex_unlock(&requests_mutex);
284         if (err != 0) return err;
285
286         return 0;
287
288 locked_error:
289         fosa_mutex_unlock(&requests_mutex);
290         return err;
291 }