]> rtime.felk.cvut.cz Git - frescor/fwp.git/blob - fwp/lib/fwp/fwp_msgq.c
Implemented synchronous and asynchronous sending
[frescor/fwp.git] / fwp / lib / fwp / fwp_msgq.c
1 /**************************************************************************/
2 /* ---------------------------------------------------------------------- */
3 /* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                 */
4 /*                                                                        */
5 /*   Universidad de Cantabria,              SPAIN                         */
6 /*   University of York,                    UK                            */
7 /*   Scuola Superiore Sant'Anna,            ITALY                         */
8 /*   Kaiserslautern University,             GERMANY                       */
9 /*   Univ. Politécnica  Valencia,           SPAIN                        */
10 /*   Czech Technical University in Prague,  CZECH REPUBLIC                */
11 /*   ENEA                                   SWEDEN                        */
12 /*   Thales Communication S.A.              FRANCE                        */
13 /*   Visual Tools S.A.                      SPAIN                         */
14 /*   Rapita Systems Ltd                     UK                            */
15 /*   Evidence                               ITALY                         */
16 /*                                                                        */
17 /*   See http://www.frescor.org for a link to partners' websites          */
18 /*                                                                        */
19 /*          FRESCOR project (FP6/2005/IST/5-034026) is funded             */
20 /*       in part by the European Union Sixth Framework Programme          */
21 /*       The European Union is not liable of any use that may be          */
22 /*       made of this code.                                               */
23 /*                                                                        */
24 /*                                                                        */
25 /*  This file is part of FWP (Frescor WLAN Protocol)                      */
26 /*                                                                        */
27 /* FWP is free software; you can redistribute it and/or modify it         */
28 /* under terms of the GNU General Public License as published by the      */
29 /* Free Software Foundation; either version 2, or (at your option) any    */
30 /* later version.  FWP is distributed in the hope that it will be         */
31 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty    */
32 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU    */
33 /* General Public License for more details. You should have received a    */
34 /* copy of the GNU General Public License along with FWP; see file        */
35 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
36 /* Cambridge, MA 02139, USA.                                              */
37 /*                                                                        */
38 /* As a special exception, including FWP header files in a file,          */
39 /* instantiating FWP generics or templates, or linking other files        */
40 /* with FWP objects to produce an executable application, does not        */
41 /* by itself cause the resulting executable application to be covered     */
42 /* by the GNU General Public License. This exception does not             */
43 /* however invalidate any other reasons why the executable file might be  */
44 /* covered by the GNU Public License.                                     */
45 /**************************************************************************/
46 #include "fwp_msgq.h"
47 #include <errno.h>
48
49 /**
50  *Initialize message queue 
51  *@param[in] msgq Message queue
52  **/
53 void fwp_msgq_init(struct fwp_msgq *msgq)
54 {
55         msgq->nr_pending = 0;
56         msgq->in = 0;
57         msgq->out = 0;
58         pthread_mutex_init(&msgq->lock, NULL); /* fast mutex */
59         sem_init(&msgq->msg_sem, 0, 0);
60 }
61
62 /**
63  * Enqueue message in message queue
64  *
65  * @param[in] msgq Message queue
66  *`@param[in] msgb Message buffer which stores a message
67  * @return
68  *   Zero on success, -1 or error.
69  **/
70 int fwp_msgq_enqueue(struct fwp_msgq *msgq, struct fwp_msgb *msgb)
71 {
72         /* acquire queue mutex */
73         pthread_mutex_lock(&msgq->lock);
74         
75         if (!(msgq->nr_pending < FWP_MSGQ_SIZE)){
76                 /*if (msgq->qr_policy == NEWCOMER) {*/  
77                 
78                 /*release queue mutex*/
79                 pthread_mutex_unlock(&msgq->lock);
80                 errno = ENOBUFS;
81                 return -1;
82                 /* }
83                  * if (msgq->qr_policy == OLDEST)
84                         msgq->first = (msgq->first++) % FWP_MSGQ_SIZE;
85                         msgq->nr_pending--;
86                 */
87         }
88
89         /* depends on queuing policy specifies in endpoint */
90         msgq->queue[msgq->in] = msgb;
91         msgq->nr_pending++;
92         msgq->in = (++msgq->in) & (FWP_MSGQ_SIZE - 1);
93
94         sem_post(&msgq->msg_sem);
95         /* release queue mutex */
96         pthread_mutex_unlock(&msgq->lock);
97
98         return 0;
99 }
100
101 /**
102  * Dequeue message from message queue
103  *
104  * @param[in] msgq Message queue
105  * @return
106  *   NULL if message queue in empty 
107  *   else returns pointer to message buffer(msgb) 
108  **/
109 struct fwp_msgb* fwp_msgq_dequeue(struct fwp_msgq *msgq)
110 {
111         struct fwp_msgb* msgb;
112         
113         sem_wait(&msgq->msg_sem);
114         /* acquire queue mutex */
115         pthread_mutex_lock(&msgq->lock);
116         
117         msgb = msgq->queue[msgq->out];
118         msgq->nr_pending--;
119         msgq->out = (++msgq->out) & (FWP_MSGQ_SIZE - 1);
120         
121         /* release queue mutex */
122         pthread_mutex_unlock(&msgq->lock);
123
124         return msgb;
125
126
127 struct fwp_msgb* fwp_msgq_peek(struct fwp_msgq *msgq)
128 {
129         struct fwp_msgb* msgb;
130         
131         pthread_mutex_lock(&msgq->lock);
132
133         if (msgq->nr_pending > 0)
134                 msgb = msgq->queue[msgq->out];
135         else
136                 msgb = NULL;
137         pthread_mutex_unlock(&msgq->lock);
138
139         return msgb;
140
141
142 /*
143  * Dequeue all messages from message queue
144  *
145  * @param[in] msgq Message queue
146  * @return
147  *   NULL if message queue is empty
148  *   else returns pointer to message buffer(msgb) 
149  **/
150 void fwp_msgq_dequeue_all(struct fwp_msgq *msgq)
151 {
152         struct fwp_msgb *msgb;
153
154         /* acquire queue mutex */
155         pthread_mutex_lock(&msgq->lock);
156         
157         while (msgq->in != msgq->out){
158                 msgb = msgq->queue[msgq->out];
159                 msgq->nr_pending--;
160                 msgq->out = (++msgq->out) & (FWP_MSGQ_SIZE - 1);
161                 fwp_msgb_free(msgb);
162         }
163         
164         sem_init(&msgq->msg_sem, 0, 0);
165         /* release queue mutex */
166         pthread_mutex_unlock(&msgq->lock);
167 }