Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / libosip2 / src / osip2 / port_fifo.c
1 /*
2   The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3   Copyright (C) 2001,2002,2003  Aymeric MOIZARD jack@atosc.org
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14   
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22
23 #include <osip2/internal.h>
24 #include <osip2/osip_fifo.h>
25
26
27 /* always use this method to initiate osip_fifo_t.
28 */
29 void
30 osip_fifo_init (osip_fifo_t * ff)
31 {
32 #ifdef OSIP_MT
33   ff->qislocked = osip_mutex_init ();
34   /*INIT SEMA TO BLOCK ON GET() WHEN QUEUE IS EMPTY */
35   ff->qisempty = osip_sem_init (0);
36 #endif
37   ff->queue = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
38   osip_list_init (ff->queue);
39   /* ff->nb_elt = 0; */
40   ff->etat = vide;
41 }
42
43 int
44 osip_fifo_add (osip_fifo_t * ff, void *el)
45 {
46 #ifdef OSIP_MT
47   osip_mutex_lock (ff->qislocked);
48 #endif
49
50   if (ff->etat != plein)
51     {
52       /* ff->nb_elt++; */
53       osip_list_add (ff->queue, el, -1);        /* insert at end of queue */
54     }
55   else
56     {
57       OSIP_TRACE (osip_trace
58                   (__FILE__, __LINE__, OSIP_WARNING, NULL,
59                    "too much traffic in fifo.\n"));
60 #ifdef OSIP_MT
61       osip_mutex_unlock (ff->qislocked);
62 #endif
63       return -1;                /* stack is full */
64     }
65   /* if (ff->nb_elt >= MAX_LEN) */
66   if (osip_list_size (ff->queue) >= MAX_LEN)
67     ff->etat = plein;
68   else
69     ff->etat = ok;
70
71 #ifdef OSIP_MT
72   osip_sem_post (ff->qisempty);
73   osip_mutex_unlock (ff->qislocked);
74 #endif
75   return 0;
76 }
77
78
79 int
80 osip_fifo_insert (osip_fifo_t * ff, void *el)
81 {
82 #ifdef OSIP_MT
83   osip_mutex_lock (ff->qislocked);
84 #endif
85
86   if (ff->etat != plein)
87     {
88       /* ff->nb_elt++; */
89       osip_list_add (ff->queue, el, 0); /* insert at end of queue */
90     }
91   else
92     {
93       OSIP_TRACE (osip_trace
94                   (__FILE__, __LINE__, OSIP_WARNING, NULL,
95                    "too much traffic in fifo.\n"));
96 #ifdef OSIP_MT
97       osip_mutex_unlock (ff->qislocked);
98 #endif
99       return -1;                /* stack is full */
100     }
101   /* if (ff->nb_elt >= MAX_LEN) */
102   if (osip_list_size (ff->queue) >= MAX_LEN)
103     ff->etat = plein;
104   else
105     ff->etat = ok;
106
107 #ifdef OSIP_MT
108   osip_sem_post (ff->qisempty);
109   osip_mutex_unlock (ff->qislocked);
110 #endif
111   return 0;
112 }
113
114
115 int
116 osip_fifo_size (osip_fifo_t * ff)
117 {
118   int i;
119
120 #ifdef OSIP_MT
121   osip_mutex_lock (ff->qislocked);
122 #endif
123
124   i = osip_list_size (ff->queue);
125 #ifdef OSIP_MT
126   osip_mutex_unlock (ff->qislocked);
127 #endif
128   return i;
129 }
130
131 #ifdef OSIP_MT
132
133 void *
134 osip_fifo_get (osip_fifo_t * ff)
135 {
136   void *el;
137   int i = osip_sem_wait (ff->qisempty);
138
139   if (i != 0)
140     return NULL;
141   osip_mutex_lock (ff->qislocked);
142
143   if (ff->etat != vide)
144     {
145       el = osip_list_get (ff->queue, 0);
146       osip_list_remove (ff->queue, 0);
147       /* ff->nb_elt--; */
148     }
149   else
150     {
151       OSIP_TRACE (osip_trace
152                   (__FILE__, __LINE__, OSIP_ERROR, NULL,
153                    "no element in fifo.\n"));
154       osip_mutex_unlock (ff->qislocked);
155       return 0;                 /* pile vide */
156     }
157   /* if (ff->nb_elt <= 0) */
158   if (osip_list_size (ff->queue) <= 0)
159     ff->etat = vide;
160   else
161     ff->etat = ok;
162
163   osip_mutex_unlock (ff->qislocked);
164   return el;
165 }
166
167 #endif
168
169 void *
170 osip_fifo_tryget (osip_fifo_t * ff)
171 {
172   void *el;
173
174 #ifdef OSIP_MT
175   if (0 != osip_sem_trywait (ff->qisempty))
176     {                           /* no elements... */
177       return NULL;
178     }
179   osip_mutex_lock (ff->qislocked);
180 #else
181   if (ff->etat == vide)
182     return NULL;
183 #endif
184
185   if (ff->etat != vide)
186     {
187       el = osip_list_get (ff->queue, 0);
188       osip_list_remove (ff->queue, 0);
189       /* ff->nb_elt--; */
190     }
191 #ifdef OSIP_MT
192   else
193     {                           /* this case MUST never happen... */
194       OSIP_TRACE (osip_trace
195                   (__FILE__, __LINE__, OSIP_INFO4, NULL,
196                    "no element in fifo.\n"));
197       osip_mutex_unlock (ff->qislocked);
198       return 0;
199     }
200 #endif
201
202   /* if (ff->nb_elt <= 0) */
203   if (osip_list_size (ff->queue) <= 0)
204     ff->etat = vide;
205   else
206     ff->etat = ok;
207
208 #ifdef OSIP_MT
209   osip_mutex_unlock (ff->qislocked);
210 #endif
211   return el;
212 }
213
214 void
215 osip_fifo_free (osip_fifo_t * ff)
216 {
217   if (ff == NULL)
218     return;
219 #ifdef OSIP_MT
220   osip_mutex_destroy (ff->qislocked);
221   /* seems that pthread_mutex_destroy does not free space by itself */
222   osip_sem_destroy (ff->qisempty);
223 #endif
224   osip_free (ff->queue);
225   osip_free (ff);
226 }