2 * Unix SMB/CIFS implementation.
3 * Receive and count messages
4 * Copyright (C) Volker Lendecke 2014
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/>.
23 #include "lib/util/tevent_unix.h"
27 struct tevent_context
*ev
;
28 struct messaging_context
*msg_ctx
;
33 static void sink_done(struct tevent_req
*subreq
);
35 static struct tevent_req
*sink_send(TALLOC_CTX
*mem_ctx
,
36 struct tevent_context
*ev
,
37 struct messaging_context
*msg_ctx
,
38 int msg_type
, unsigned *counter
)
40 struct tevent_req
*req
, *subreq
;
41 struct sink_state
*state
;
43 req
= tevent_req_create(mem_ctx
, &state
, struct sink_state
);
48 state
->msg_ctx
= msg_ctx
;
49 state
->msg_type
= msg_type
;
50 state
->counter
= counter
;
52 subreq
= messaging_read_send(state
, state
->ev
, state
->msg_ctx
,
54 if (tevent_req_nomem(subreq
, req
)) {
55 return tevent_req_post(req
, ev
);
57 tevent_req_set_callback(subreq
, sink_done
, req
);
61 static void sink_done(struct tevent_req
*subreq
)
63 struct tevent_req
*req
= tevent_req_callback_data(
64 subreq
, struct tevent_req
);
65 struct sink_state
*state
= tevent_req_data(
66 req
, struct sink_state
);
69 ret
= messaging_read_recv(subreq
, NULL
, NULL
);
71 if (tevent_req_error(req
, ret
)) {
77 subreq
= messaging_read_send(state
, state
->ev
, state
->msg_ctx
,
79 if (tevent_req_nomem(subreq
, req
)) {
82 tevent_req_set_callback(subreq
, sink_done
, req
);
85 static int sink_recv(struct tevent_req
*req
)
89 if (tevent_req_is_unix_error(req
, &err
)) {
95 struct prcount_state
{
96 struct tevent_context
*ev
;
97 struct timeval interval
;
101 static void prcount_waited(struct tevent_req
*subreq
);
103 static struct tevent_req
*prcount_send(TALLOC_CTX
*mem_ctx
,
104 struct tevent_context
*ev
,
105 struct timeval interval
,
108 struct tevent_req
*req
, *subreq
;
109 struct prcount_state
*state
;
111 req
= tevent_req_create(mem_ctx
, &state
, struct prcount_state
);
116 state
->interval
= interval
;
117 state
->counter
= counter
;
119 subreq
= tevent_wakeup_send(
121 timeval_current_ofs(state
->interval
.tv_sec
,
122 state
->interval
.tv_usec
));
123 if (tevent_req_nomem(subreq
, req
)) {
124 return tevent_req_post(req
, ev
);
126 tevent_req_set_callback(subreq
, prcount_waited
, req
);
130 static void prcount_waited(struct tevent_req
*subreq
)
132 struct tevent_req
*req
= tevent_req_callback_data(
133 subreq
, struct tevent_req
);
134 struct prcount_state
*state
= tevent_req_data(
135 req
, struct prcount_state
);
138 ok
= tevent_wakeup_recv(subreq
);
141 tevent_req_error(req
, ENOMEM
);
145 printf("%u\n", *state
->counter
);
147 subreq
= tevent_wakeup_send(
149 timeval_current_ofs(state
->interval
.tv_sec
,
150 state
->interval
.tv_usec
));
151 if (tevent_req_nomem(subreq
, req
)) {
154 tevent_req_set_callback(subreq
, prcount_waited
, req
);
157 static int prcount_recv(struct tevent_req
*req
)
161 if (tevent_req_is_unix_error(req
, &err
)) {
167 struct msgcount_state
{
171 static void msgcount_sunk(struct tevent_req
*subreq
);
172 static void msgcount_printed(struct tevent_req
*subreq
);
174 static struct tevent_req
*msgcount_send(TALLOC_CTX
*mem_ctx
,
175 struct tevent_context
*ev
,
176 struct messaging_context
*msg_ctx
,
177 int msg_type
, struct timeval interval
)
179 struct tevent_req
*req
, *subreq
;
180 struct msgcount_state
*state
;
182 req
= tevent_req_create(mem_ctx
, &state
, struct msgcount_state
);
187 subreq
= sink_send(state
, ev
, msg_ctx
, msg_type
, &state
->count
);
188 if (tevent_req_nomem(subreq
, req
)) {
189 return tevent_req_post(req
, ev
);
191 tevent_req_set_callback(subreq
, msgcount_sunk
, req
);
193 subreq
= prcount_send(state
, ev
, interval
, &state
->count
);
194 if (tevent_req_nomem(subreq
, req
)) {
195 return tevent_req_post(req
, ev
);
197 tevent_req_set_callback(subreq
, msgcount_printed
, req
);
202 static void msgcount_sunk(struct tevent_req
*subreq
)
204 struct tevent_req
*req
= tevent_req_callback_data(
205 subreq
, struct tevent_req
);
208 ret
= sink_recv(subreq
);
210 if (tevent_req_error(req
, ret
)) {
213 tevent_req_done(req
);
216 static void msgcount_printed(struct tevent_req
*subreq
)
218 struct tevent_req
*req
= tevent_req_callback_data(
219 subreq
, struct tevent_req
);
222 ret
= prcount_recv(subreq
);
224 if (tevent_req_error(req
, ret
)) {
227 tevent_req_done(req
);
230 static int msgcount_recv(struct tevent_req
*req
)
234 if (tevent_req_is_unix_error(req
, &err
)) {
242 TALLOC_CTX
*frame
= talloc_stackframe();
243 struct tevent_context
*ev
;
244 struct messaging_context
*msg_ctx
;
245 struct tevent_req
*req
;
248 struct server_id_buf tmp
;
250 lp_load_global(get_dyn_CONFIGFILE());
252 ev
= tevent_context_init(frame
);
254 perror("tevent_context_init failed");
258 msg_ctx
= messaging_init(ev
, ev
);
259 if (msg_ctx
== NULL
) {
260 perror("messaging_init failed");
264 id
= messaging_server_id(msg_ctx
);
266 printf("server_id: %s\n", server_id_str_buf(id
, &tmp
));
268 req
= msgcount_send(ev
, ev
, msg_ctx
, MSG_SMB_NOTIFY
,
271 perror("msgcount_send failed");
275 if (!tevent_req_poll(req
, ev
)) {
276 perror("tevent_req_poll failed");
280 ret
= msgcount_recv(req
);
281 printf("msgcount_recv returned %d\n", ret
);