2 Unix SMB/CIFS implementation.
4 Copyright (C) Volker Lendecke 2012
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "tevent_barrier.h"
22 #include "lib/util/tevent_unix.h"
24 struct tevent_barrier_waiter
{
25 struct tevent_immediate
*im
;
26 struct tevent_context
*ev
;
27 struct tevent_req
*req
;
30 struct tevent_barrier
{
32 struct tevent_barrier_waiter
*waiters
;
33 void (*trigger_cb
)(void *private_data
);
37 static int tevent_barrier_destructor(struct tevent_barrier
*b
);
38 static void tevent_barrier_release(struct tevent_barrier
*b
);
39 static void tevent_barrier_release_one(struct tevent_context
*ctx
,
40 struct tevent_immediate
*im
,
42 static void tevent_barrier_release_trigger(struct tevent_context
*ctx
,
43 struct tevent_immediate
*im
,
46 struct tevent_barrier
*tevent_barrier_init(
47 TALLOC_CTX
*mem_ctx
, unsigned count
,
48 void (*trigger_cb
)(void *private_data
), void *private_data
)
50 struct tevent_barrier
*b
;
57 b
= talloc(mem_ctx
, struct tevent_barrier
);
62 b
->trigger_cb
= trigger_cb
;
63 b
->private_data
= private_data
;
65 b
->waiters
= talloc_array(b
, struct tevent_barrier_waiter
, count
);
66 if (b
->waiters
== NULL
) {
69 for (i
=0; i
<count
; i
++) {
70 struct tevent_barrier_waiter
*w
= &b
->waiters
[i
];
72 w
->im
= tevent_create_immediate(b
->waiters
);
78 talloc_set_destructor(b
, tevent_barrier_destructor
);
85 static int tevent_barrier_destructor(struct tevent_barrier
*b
)
87 tevent_barrier_release(b
);
91 struct tevent_barrier_wait_state
{
92 struct tevent_barrier
*b
;
96 static void tevent_barrier_release(struct tevent_barrier
*b
)
100 for (i
=0; i
<b
->count
; i
++) {
101 struct tevent_barrier_waiter
*w
= &b
->waiters
[i
];
102 struct tevent_barrier_wait_state
*state
;
104 if (w
->req
== NULL
) {
107 tevent_schedule_immediate(
108 w
->im
, w
->ev
, tevent_barrier_release_one
, w
->req
);
110 state
= tevent_req_data(
111 w
->req
, struct tevent_barrier_wait_state
);
112 talloc_set_destructor(state
, NULL
);
118 if (b
->trigger_cb
!= NULL
) {
119 b
->trigger_cb(b
->private_data
);
123 static void tevent_barrier_release_one(struct tevent_context
*ctx
,
124 struct tevent_immediate
*im
,
127 struct tevent_req
*req
= talloc_get_type_abort(
128 private_data
, struct tevent_req
);
129 tevent_req_done(req
);
132 static int tevent_barrier_wait_state_destructor(
133 struct tevent_barrier_wait_state
*s
);
135 struct tevent_req
*tevent_barrier_wait_send(TALLOC_CTX
*mem_ctx
,
136 struct tevent_context
*ev
,
137 struct tevent_barrier
*b
)
139 struct tevent_req
*req
;
140 struct tevent_barrier_wait_state
*state
;
141 struct tevent_barrier_waiter
*w
;
142 struct tevent_immediate
*im
;
144 req
= tevent_req_create(mem_ctx
, &state
,
145 struct tevent_barrier_wait_state
);
150 state
->index
= b
->count
;
152 w
= &b
->waiters
[b
->count
];
157 talloc_set_destructor(state
, tevent_barrier_wait_state_destructor
);
159 if (b
->count
< talloc_array_length(b
->waiters
)) {
163 im
= tevent_create_immediate(req
);
164 if (tevent_req_nomem(im
, req
)) {
165 return tevent_req_post(req
, ev
);
167 tevent_schedule_immediate(im
, ev
, tevent_barrier_release_trigger
, b
);
171 static int tevent_barrier_wait_state_destructor(
172 struct tevent_barrier_wait_state
*s
)
174 struct tevent_barrier
*b
= s
->b
;
175 b
->waiters
[s
->index
].req
= b
->waiters
[b
->count
-1].req
;
180 static void tevent_barrier_release_trigger(struct tevent_context
*ctx
,
181 struct tevent_immediate
*im
,
184 struct tevent_barrier
*b
= talloc_get_type_abort(
185 private_data
, struct tevent_barrier
);
186 tevent_barrier_release(b
);
189 int tevent_barrier_wait_recv(struct tevent_req
*req
)
193 if (tevent_req_is_unix_error(req
, &err
)) {