2 * @file frescan_requests_queue.c
4 * @brief FRESCAN requests queue
6 * This module contains an operation to create the queue, an operation to
7 * enqueue a message (with a request), and an operation to
14 * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
18 #include <misc/freelist.h>
19 #include <misc/linux_list.h>
21 #include "frescan_requests_queue.h"
22 #include "frescan_config.h"
23 #include "fosa_mutexes_and_condvars.h"
25 static bool is_initialized = false;
30 * We will use a freelist to allocate and free the requests.
35 frescan_req_type_t type;
36 frescan_robj_id_t reply;
37 frescan_contract_t *contract;
39 struct list_head request_list;
43 static fosa_mutex_t requests_mutex;
44 static fosa_cond_t requests_cond;
46 static struct request_t the_requests_pool[FRESCAN_MX_REQUESTS];
47 static freelist_t freelist;
48 static struct request_t the_requests_list;
51 * frescan_requests_init()
53 * Init the freelist, requests list, cond var and mutex.
57 int frescan_requests_init(int max_ceiling)
61 err = fosa_mutex_init(&requests_mutex, max_ceiling);
62 if (err != 0) return err;
64 err = fosa_cond_init(&requests_cond);
65 if (err != 0) return err;
67 err = freelist_init(&freelist, FRESCAN_MX_REQUESTS);
68 if (err != 0) return err;
70 INIT_LIST_HEAD(&the_requests_list.request_list);
72 is_initialized = true;
77 * frescan_request_alloc()
79 * Allocate a request with the mutex locked
83 int frescan_request_alloc(frescan_request_id_t *id)
87 if (is_initialized == false) return -1;
89 err = fosa_mutex_lock(&requests_mutex);
90 if (err != 0) return err;
92 pos = freelist_alloc(&freelist);
93 if (pos < 0) goto locked_error;
95 err = fosa_mutex_unlock(&requests_mutex);
96 if (err != 0) return err;
98 *id = (unsigned int)pos;
99 the_requests_pool[*id].pool_pos = pos;
104 fosa_mutex_unlock(&requests_mutex);
109 * frescan_request_free()
111 * free the request from the pool
115 int frescan_request_free(frescan_request_id_t id)
119 if (is_initialized == false) return -1;
121 err = fosa_mutex_lock(&requests_mutex);
122 if (err != 0) return err;
124 err = freelist_free(&freelist, id);
125 if (err != 0) goto locked_error;
127 err = fosa_mutex_unlock(&requests_mutex);
128 if (err != 0) return err;
133 fosa_mutex_unlock(&requests_mutex);
138 * frescan_request_set_type()
142 int frescan_request_set_type(frescan_request_id_t id, frescan_req_type_t type)
144 the_requests_pool[id].type = type;
149 * frescan_request_set_reply()
153 int frescan_request_set_reply(frescan_request_id_t id, frescan_robj_id_t reply)
155 the_requests_pool[id].reply = reply;
160 * frescan_request_set_contract()
164 int frescan_request_set_contract(frescan_request_id_t id,
165 frescan_contract_t *contract)
167 the_requests_pool[id].contract = contract;
172 * frescan_request_set_src()
176 int frescan_request_set_src(frescan_request_id_t id, frescan_node_t src)
178 the_requests_pool[id].src = src;
183 * frescan_request_get_type()
187 int frescan_request_get_type(frescan_request_id_t id, frescan_req_type_t *type)
189 *type = the_requests_pool[id].type;
194 * frescan_request_get_reply()
198 int frescan_request_get_reply(frescan_request_id_t id, frescan_robj_id_t *reply)
200 *reply = the_requests_pool[id].reply;
205 * frescan_request_get_contract()
209 int frescan_request_get_contract(frescan_request_id_t id,
210 frescan_contract_t **contract)
212 *contract = the_requests_pool[id].contract;
217 * frescan_request_get_src()
221 int frescan_request_get_src(frescan_request_id_t id, frescan_node_t *src)
223 *src = the_requests_pool[id].src;
228 * frescan_requestqueue_enqueue()
232 int frescan_requestqueue_enqueue(frescan_request_id_t id)
236 err = fosa_mutex_lock(&requests_mutex);
237 if (err != 0) return err;
239 list_add_tail(&the_requests_list.request_list,
240 &the_requests_pool[id].request_list);
242 err = fosa_cond_signal(&requests_cond);
243 if (err != 0) goto locked_error;
245 err = fosa_mutex_unlock(&requests_mutex);
246 if (err != 0) return err;
251 fosa_mutex_unlock(&requests_mutex);
256 * frescan_requestqueue_dequeue()
260 int frescan_requestqueue_dequeue(frescan_request_id_t *id)
263 struct list_head *pos;
264 struct request_t *request;
266 err = fosa_mutex_lock(&requests_mutex);
267 if (err != 0) return err;
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;
274 list_for_each(pos, &the_requests_pool[*id].request_list) {
275 request = list_entry(pos, struct request_t, request_list);
279 list_del(&request->request_list);
281 *id = request->pool_pos;
283 err = fosa_mutex_unlock(&requests_mutex);
284 if (err != 0) return err;
289 fosa_mutex_unlock(&requests_mutex);