Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * Wait for process death
4 : * Copyright (C) Volker Lendecke 2016
5 : *
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.
10 : *
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.
15 : *
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/>.
18 : */
19 :
20 : #include "replace.h"
21 : #include <tevent.h>
22 : #include <talloc.h>
23 : #include "serverid.h"
24 : #include "server_id_watch.h"
25 : #include "lib/util/tevent_unix.h"
26 :
27 : struct server_id_watch_state {
28 : struct tevent_context *ev;
29 : struct server_id pid;
30 : };
31 :
32 : static void server_id_watch_waited(struct tevent_req *subreq);
33 :
34 514 : struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx,
35 : struct tevent_context *ev,
36 : struct server_id pid)
37 : {
38 : struct tevent_req *req, *subreq;
39 : struct server_id_watch_state *state;
40 :
41 514 : req = tevent_req_create(mem_ctx, &state, struct server_id_watch_state);
42 514 : if (req == NULL) {
43 0 : return NULL;
44 : }
45 514 : state->ev = ev;
46 514 : state->pid = pid;
47 :
48 514 : if (!serverid_exists(&state->pid)) {
49 0 : tevent_req_done(req);
50 0 : return tevent_req_post(req, ev);
51 : }
52 :
53 514 : subreq = tevent_wakeup_send(
54 : state, ev, tevent_timeval_current_ofs(0, 500000));
55 514 : if (tevent_req_nomem(subreq, req)) {
56 0 : return tevent_req_post(req, ev);
57 : }
58 514 : tevent_req_set_callback(subreq, server_id_watch_waited, req);
59 :
60 514 : return req;
61 : }
62 :
63 0 : static void server_id_watch_waited(struct tevent_req *subreq)
64 : {
65 0 : struct tevent_req *req = tevent_req_callback_data(
66 : subreq, struct tevent_req);
67 0 : struct server_id_watch_state *state = tevent_req_data(
68 : req, struct server_id_watch_state);
69 : bool ok;
70 :
71 0 : ok = tevent_wakeup_recv(subreq);
72 0 : TALLOC_FREE(subreq);
73 0 : if (!ok) {
74 0 : tevent_req_oom(req);
75 0 : return;
76 : }
77 :
78 0 : if (!serverid_exists(&state->pid)) {
79 0 : tevent_req_done(req);
80 0 : return;
81 : }
82 :
83 0 : subreq = tevent_wakeup_send(
84 : state, state->ev, tevent_timeval_current_ofs(0, 500000));
85 0 : if (tevent_req_nomem(subreq, req)) {
86 0 : return;
87 : }
88 0 : tevent_req_set_callback(subreq, server_id_watch_waited, req);
89 : }
90 :
91 0 : int server_id_watch_recv(struct tevent_req *req, struct server_id *pid)
92 : {
93 0 : struct server_id_watch_state *state = tevent_req_data(
94 : req, struct server_id_watch_state);
95 : int err;
96 :
97 0 : if (tevent_req_is_unix_error(req, &err)) {
98 0 : return err;
99 : }
100 0 : if (pid) {
101 0 : *pid = state->pid;
102 : }
103 0 : return 0;
104 : }
|