• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/lib/tevent/
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
30struct 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	struct tevent_context *ev;
38
39	tevent_queue_trigger_fn_t trigger;
40	void *private_data;
41};
42
43struct tevent_queue {
44	const char *name;
45	const char *location;
46
47	bool running;
48	struct tevent_immediate *immediate;
49
50	size_t length;
51	struct tevent_queue_entry *list;
52};
53
54static void tevent_queue_immediate_trigger(struct tevent_context *ev,
55					   struct tevent_immediate *im,
56					   void *private_data);
57
58static int tevent_queue_entry_destructor(struct tevent_queue_entry *e)
59{
60	struct tevent_queue *q = e->queue;
61
62	if (!q) {
63		return 0;
64	}
65
66	DLIST_REMOVE(q->list, e);
67	q->length--;
68
69	if (!q->running) {
70		return 0;
71	}
72
73	if (!q->list) {
74		return 0;
75	}
76
77	if (q->list->triggered) {
78		return 0;
79	}
80
81	tevent_schedule_immediate(q->immediate,
82				  q->list->ev,
83				  tevent_queue_immediate_trigger,
84				  q);
85
86	return 0;
87}
88
89static int tevent_queue_destructor(struct tevent_queue *q)
90{
91	q->running = false;
92
93	while (q->list) {
94		struct tevent_queue_entry *e = q->list;
95		talloc_free(e);
96	}
97
98	return 0;
99}
100
101struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
102					  const char *name,
103					  const char *location)
104{
105	struct tevent_queue *queue;
106
107	queue = talloc_zero(mem_ctx, struct tevent_queue);
108	if (!queue) {
109		return NULL;
110	}
111
112	queue->name = talloc_strdup(queue, name);
113	if (!queue->name) {
114		talloc_free(queue);
115		return NULL;
116	}
117	queue->immediate = tevent_create_immediate(queue);
118	if (!queue->immediate) {
119		talloc_free(queue);
120		return NULL;
121	}
122
123	queue->location = location;
124
125	/* queue is running by default */
126	queue->running = true;
127
128	talloc_set_destructor(queue, tevent_queue_destructor);
129	return queue;
130}
131
132static void tevent_queue_immediate_trigger(struct tevent_context *ev,
133					   struct tevent_immediate *im,
134					   void *private_data)
135{
136	struct tevent_queue *q = talloc_get_type(private_data,
137				  struct tevent_queue);
138
139	if (!q->running) {
140		return;
141	}
142
143	q->list->triggered = true;
144	q->list->trigger(q->list->req, q->list->private_data);
145}
146
147bool tevent_queue_add(struct tevent_queue *queue,
148		      struct tevent_context *ev,
149		      struct tevent_req *req,
150		      tevent_queue_trigger_fn_t trigger,
151		      void *private_data)
152{
153	struct tevent_queue_entry *e;
154
155	e = talloc_zero(req, struct tevent_queue_entry);
156	if (e == NULL) {
157		return false;
158	}
159
160	e->queue = queue;
161	e->req = req;
162	e->ev = ev;
163	e->trigger = trigger;
164	e->private_data = private_data;
165
166	DLIST_ADD_END(queue->list, e, struct tevent_queue_entry *);
167	queue->length++;
168	talloc_set_destructor(e, tevent_queue_entry_destructor);
169
170	if (!queue->running) {
171		return true;
172	}
173
174	if (queue->list->triggered) {
175		return true;
176	}
177
178	tevent_schedule_immediate(queue->immediate,
179				  queue->list->ev,
180				  tevent_queue_immediate_trigger,
181				  queue);
182
183	return true;
184}
185
186void tevent_queue_start(struct tevent_queue *queue)
187{
188	if (queue->running) {
189		/* already started */
190		return;
191	}
192
193	queue->running = true;
194
195	if (!queue->list) {
196		return;
197	}
198
199	if (queue->list->triggered) {
200		return;
201	}
202
203	tevent_schedule_immediate(queue->immediate,
204				  queue->list->ev,
205				  tevent_queue_immediate_trigger,
206				  queue);
207}
208
209void tevent_queue_stop(struct tevent_queue *queue)
210{
211	queue->running = false;
212}
213
214size_t tevent_queue_length(struct tevent_queue *queue)
215{
216	return queue->length;
217}
218