Move update-external.sh to third_party/
[Samba.git] / source3 / torture / msg_sink.c
blob158fe3c82fb0eb16d8ef5f7f30ad9daf743ba937
1 /*
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/>.
20 #include "replace.h"
21 #include "includes.h"
22 #include "messages.h"
23 #include "lib/util/tevent_unix.h"
24 #include <stdio.h>
26 struct sink_state {
27 struct tevent_context *ev;
28 struct messaging_context *msg_ctx;
29 int msg_type;
30 unsigned *counter;
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);
44 if (req == NULL) {
45 return NULL;
47 state->ev = ev;
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,
53 state->msg_type);
54 if (tevent_req_nomem(subreq, req)) {
55 return tevent_req_post(req, ev);
57 tevent_req_set_callback(subreq, sink_done, req);
58 return 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);
67 int ret;
69 ret = messaging_read_recv(subreq, NULL, NULL);
70 TALLOC_FREE(subreq);
71 if (tevent_req_error(req, ret)) {
72 return;
75 *state->counter += 1;
77 subreq = messaging_read_send(state, state->ev, state->msg_ctx,
78 state->msg_type);
79 if (tevent_req_nomem(subreq, req)) {
80 return;
82 tevent_req_set_callback(subreq, sink_done, req);
85 static int sink_recv(struct tevent_req *req)
87 int err;
89 if (tevent_req_is_unix_error(req, &err)) {
90 return err;
92 return 0;
95 struct prcount_state {
96 struct tevent_context *ev;
97 struct timeval interval;
98 unsigned *counter;
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,
106 unsigned *counter)
108 struct tevent_req *req, *subreq;
109 struct prcount_state *state;
111 req = tevent_req_create(mem_ctx, &state, struct prcount_state);
112 if (req == NULL) {
113 return NULL;
115 state->ev = ev;
116 state->interval = interval;
117 state->counter = counter;
119 subreq = tevent_wakeup_send(
120 state, state->ev,
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);
127 return 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);
136 bool ok;
138 ok = tevent_wakeup_recv(subreq);
139 TALLOC_FREE(subreq);
140 if (!ok) {
141 tevent_req_error(req, ENOMEM);
142 return;
145 printf("%u\n", *state->counter);
147 subreq = tevent_wakeup_send(
148 state, state->ev,
149 timeval_current_ofs(state->interval.tv_sec,
150 state->interval.tv_usec));
151 if (tevent_req_nomem(subreq, req)) {
152 return;
154 tevent_req_set_callback(subreq, prcount_waited, req);
157 static int prcount_recv(struct tevent_req *req)
159 int err;
161 if (tevent_req_is_unix_error(req, &err)) {
162 return err;
164 return 0;
167 struct msgcount_state {
168 unsigned count;
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);
183 if (req == NULL) {
184 return NULL;
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);
199 return req;
202 static void msgcount_sunk(struct tevent_req *subreq)
204 struct tevent_req *req = tevent_req_callback_data(
205 subreq, struct tevent_req);
206 int ret;
208 ret = sink_recv(subreq);
209 TALLOC_FREE(subreq);
210 if (tevent_req_error(req, ret)) {
211 return;
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);
220 int ret;
222 ret = prcount_recv(subreq);
223 TALLOC_FREE(subreq);
224 if (tevent_req_error(req, ret)) {
225 return;
227 tevent_req_done(req);
230 static int msgcount_recv(struct tevent_req *req)
232 int err;
234 if (tevent_req_is_unix_error(req, &err)) {
235 return err;
237 return 0;
240 int main(void)
242 TALLOC_CTX *frame = talloc_stackframe();
243 struct tevent_context *ev;
244 struct messaging_context *msg_ctx;
245 struct tevent_req *req;
246 int ret;
247 struct server_id id;
248 struct server_id_buf tmp;
250 lp_load_global(get_dyn_CONFIGFILE());
252 ev = tevent_context_init(frame);
253 if (ev == NULL) {
254 perror("tevent_context_init failed");
255 return -1;
258 msg_ctx = messaging_init(ev, ev);
259 if (msg_ctx == NULL) {
260 perror("messaging_init failed");
261 return -1;
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,
269 timeval_set(1, 0));
270 if (req == NULL) {
271 perror("msgcount_send failed");
272 return -1;
275 if (!tevent_req_poll(req, ev)) {
276 perror("tevent_req_poll failed");
277 return -1;
280 ret = msgcount_recv(req);
281 printf("msgcount_recv returned %d\n", ret);
283 return 0;