Strip /usr/include from include flags, so we don't end up including
[kai/samba.git] / lib / tevent / tevent_queue.c
1 /*
2    Unix SMB/CIFS implementation.
3    Infrastructure for async requests
4    Copyright (C) Volker Lendecke 2008
5    Copyright (C) Stefan Metzmacher 2009
6
7      ** NOTE! The following LGPL license applies to the tevent
8      ** library. This does NOT imply that all of Samba is released
9      ** under the LGPL
10
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Lesser General Public
13    License as published by the Free Software Foundation; either
14    version 3 of the License, or (at your option) any later version.
15
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Lesser General Public License for more details.
20
21    You should have received a copy of the GNU Lesser General Public
22    License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "replace.h"
26 #include "tevent.h"
27 #include "tevent_internal.h"
28 #include "tevent_util.h"
29
30 struct tevent_queue_entry {
31         struct tevent_queue_entry *prev, *next;
32         struct tevent_queue *queue;
33
34         bool triggered;
35
36         struct tevent_req *req;
37
38         tevent_queue_trigger_fn_t trigger;
39         void *private_data;
40 };
41
42 struct tevent_queue {
43         const char *name;
44         const char *location;
45
46         bool running;
47         struct tevent_timer *timer;
48
49         size_t length;
50         struct tevent_queue_entry *list;
51 };
52
53 static int tevent_queue_entry_destructor(struct tevent_queue_entry *e)
54 {
55         struct tevent_queue *q = e->queue;
56
57         if (!q) {
58                 return 0;
59         }
60
61         DLIST_REMOVE(q->list, e);
62         q->length--;
63
64         if (e->triggered &&
65             q->running &&
66             q->list) {
67                 q->list->triggered = true;
68                 q->list->trigger(q->list->req,
69                                  q->list->private_data);
70         }
71
72         return 0;
73 }
74
75 static int tevent_queue_destructor(struct tevent_queue *q)
76 {
77         q->running = false;
78
79         while (q->list) {
80                 struct tevent_queue_entry *e = q->list;
81                 talloc_free(e);
82         }
83
84         return 0;
85 }
86
87 struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
88                                           const char *name,
89                                           const char *location)
90 {
91         struct tevent_queue *queue;
92
93         queue = talloc_zero(mem_ctx, struct tevent_queue);
94         if (!queue) {
95                 return NULL;
96         }
97
98         queue->name = talloc_strdup(queue, name);
99         if (!queue->name) {
100                 talloc_free(queue);
101                 return NULL;
102         }
103
104         queue->location = location;
105
106         /* queue is running by default */
107         queue->running = true;
108
109         talloc_set_destructor(queue, tevent_queue_destructor);
110         return queue;
111 }
112
113 static void tevent_queue_timer_start(struct tevent_context *ev,
114                                      struct tevent_timer *te,
115                                      struct timeval now,
116                                      void *private_data)
117 {
118         struct tevent_queue *q = talloc_get_type(private_data,
119                                   struct tevent_queue);
120
121         talloc_free(te);
122         q->timer = NULL;
123
124         q->list->triggered = true;
125         q->list->trigger(q->list->req, q->list->private_data);
126 }
127
128 bool tevent_queue_add(struct tevent_queue *queue,
129                       struct tevent_context *ev,
130                       struct tevent_req *req,
131                       tevent_queue_trigger_fn_t trigger,
132                       void *private_data)
133 {
134         struct tevent_queue_entry *e;
135
136         e = talloc_zero(req, struct tevent_queue_entry);
137         if (e == NULL) {
138                 return false;
139         }
140
141         e->queue = queue;
142         e->req = req;
143         e->trigger = trigger;
144         e->private_data = private_data;
145
146         if (queue->running &&
147             !queue->timer &&
148             !queue->list) {
149                 queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(),
150                                                 tevent_queue_timer_start,
151                                                 queue);
152                 if (!queue->timer) {
153                         talloc_free(e);
154                         return false;
155                 }
156         }
157
158         DLIST_ADD_END(queue->list, e, struct tevent_queue_entry *);
159         queue->length++;
160         talloc_set_destructor(e, tevent_queue_entry_destructor);
161
162         return true;
163 }
164
165 bool tevent_queue_start(struct tevent_queue *queue,
166                         struct tevent_context *ev)
167 {
168         if (queue->running) {
169                 /* already started */
170                 return true;
171         }
172
173         if (!queue->timer &&
174             queue->list) {
175                 queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(),
176                                                 tevent_queue_timer_start,
177                                                 queue);
178                 if (!queue->timer) {
179                         return false;
180                 }
181         }
182
183         queue->running = true;
184
185         return true;
186 }
187
188 void tevent_queue_stop(struct tevent_queue *queue)
189 {
190         queue->running = false;
191         talloc_free(queue->timer);
192         queue->timer = NULL;
193 }
194
195 size_t tevent_queue_length(struct tevent_queue *queue)
196 {
197         return queue->length;
198 }