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/>.
22 #include "lib/util/server_id.h"
24 #include "lib/util/tevent_unix.h"
28 struct tevent_context
*ev
;
29 struct messaging_context
*msg_ctx
;
34 static void sink_done(struct tevent_req
*subreq
);
36 static struct tevent_req
*sink_send(TALLOC_CTX
*mem_ctx
,
37 struct tevent_context
*ev
,
38 struct messaging_context
*msg_ctx
,
39 int msg_type
, unsigned *counter
)
41 struct tevent_req
*req
, *subreq
;
42 struct sink_state
*state
;
44 req
= tevent_req_create(mem_ctx
, &state
, struct sink_state
);
49 state
->msg_ctx
= msg_ctx
;
50 state
->msg_type
= msg_type
;
51 state
->counter
= counter
;
53 subreq
= messaging_read_send(state
, state
->ev
, state
->msg_ctx
,
55 if (tevent_req_nomem(subreq
, req
)) {
56 return tevent_req_post(req
, ev
);
58 tevent_req_set_callback(subreq
, sink_done
, req
);
62 static void sink_done(struct tevent_req
*subreq
)
64 struct tevent_req
*req
= tevent_req_callback_data(
65 subreq
, struct tevent_req
);
66 struct sink_state
*state
= tevent_req_data(
67 req
, struct sink_state
);
70 ret
= messaging_read_recv(subreq
, NULL
, NULL
);
72 if (tevent_req_error(req
, ret
)) {
78 subreq
= messaging_read_send(state
, state
->ev
, state
->msg_ctx
,
80 if (tevent_req_nomem(subreq
, req
)) {
83 tevent_req_set_callback(subreq
, sink_done
, req
);
86 static int sink_recv(struct tevent_req
*req
)
90 if (tevent_req_is_unix_error(req
, &err
)) {
96 struct prcount_state
{
97 struct tevent_context
*ev
;
98 struct timeval interval
;
102 static void prcount_waited(struct tevent_req
*subreq
);
104 static struct tevent_req
*prcount_send(TALLOC_CTX
*mem_ctx
,
105 struct tevent_context
*ev
,
106 struct timeval interval
,
109 struct tevent_req
*req
, *subreq
;
110 struct prcount_state
*state
;
112 req
= tevent_req_create(mem_ctx
, &state
, struct prcount_state
);
117 state
->interval
= interval
;
118 state
->counter
= counter
;
120 subreq
= tevent_wakeup_send(
122 timeval_current_ofs(state
->interval
.tv_sec
,
123 state
->interval
.tv_usec
));
124 if (tevent_req_nomem(subreq
, req
)) {
125 return tevent_req_post(req
, ev
);
127 tevent_req_set_callback(subreq
, prcount_waited
, req
);
131 static void prcount_waited(struct tevent_req
*subreq
)
133 struct tevent_req
*req
= tevent_req_callback_data(
134 subreq
, struct tevent_req
);
135 struct prcount_state
*state
= tevent_req_data(
136 req
, struct prcount_state
);
139 ok
= tevent_wakeup_recv(subreq
);
142 tevent_req_error(req
, ENOMEM
);
146 printf("%u\n", *state
->counter
);
148 subreq
= tevent_wakeup_send(
150 timeval_current_ofs(state
->interval
.tv_sec
,
151 state
->interval
.tv_usec
));
152 if (tevent_req_nomem(subreq
, req
)) {
155 tevent_req_set_callback(subreq
, prcount_waited
, req
);
158 static int prcount_recv(struct tevent_req
*req
)
162 if (tevent_req_is_unix_error(req
, &err
)) {
168 struct msgcount_state
{
172 static void msgcount_sunk(struct tevent_req
*subreq
);
173 static void msgcount_printed(struct tevent_req
*subreq
);
175 static struct tevent_req
*msgcount_send(TALLOC_CTX
*mem_ctx
,
176 struct tevent_context
*ev
,
177 struct messaging_context
*msg_ctx
,
178 int msg_type
, struct timeval interval
)
180 struct tevent_req
*req
, *subreq
;
181 struct msgcount_state
*state
;
183 req
= tevent_req_create(mem_ctx
, &state
, struct msgcount_state
);
188 subreq
= sink_send(state
, ev
, msg_ctx
, msg_type
, &state
->count
);
189 if (tevent_req_nomem(subreq
, req
)) {
190 return tevent_req_post(req
, ev
);
192 tevent_req_set_callback(subreq
, msgcount_sunk
, req
);
194 subreq
= prcount_send(state
, ev
, interval
, &state
->count
);
195 if (tevent_req_nomem(subreq
, req
)) {
196 return tevent_req_post(req
, ev
);
198 tevent_req_set_callback(subreq
, msgcount_printed
, req
);
203 static void msgcount_sunk(struct tevent_req
*subreq
)
205 struct tevent_req
*req
= tevent_req_callback_data(
206 subreq
, struct tevent_req
);
209 ret
= sink_recv(subreq
);
211 if (tevent_req_error(req
, ret
)) {
214 tevent_req_done(req
);
217 static void msgcount_printed(struct tevent_req
*subreq
)
219 struct tevent_req
*req
= tevent_req_callback_data(
220 subreq
, struct tevent_req
);
223 ret
= prcount_recv(subreq
);
225 if (tevent_req_error(req
, ret
)) {
228 tevent_req_done(req
);
231 static int msgcount_recv(struct tevent_req
*req
)
235 if (tevent_req_is_unix_error(req
, &err
)) {
243 TALLOC_CTX
*frame
= talloc_stackframe();
244 struct tevent_context
*ev
;
245 struct messaging_context
*msg_ctx
;
246 struct tevent_req
*req
;
249 struct server_id_buf tmp
;
251 lp_load_global(get_dyn_CONFIGFILE());
253 ev
= tevent_context_init(frame
);
255 perror("tevent_context_init failed");
259 msg_ctx
= messaging_init(ev
, ev
);
260 if (msg_ctx
== NULL
) {
261 perror("messaging_init failed");
265 id
= messaging_server_id(msg_ctx
);
267 printf("server_id: %s\n", server_id_str_buf(id
, &tmp
));
269 req
= msgcount_send(ev
, ev
, msg_ctx
, MSG_SMB_NOTIFY
,
272 perror("msgcount_send failed");
276 if (!tevent_req_poll(req
, ev
)) {
277 perror("tevent_req_poll failed");
281 ret
= msgcount_recv(req
);
282 printf("msgcount_recv returned %d\n", ret
);