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 2790 : struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx, 35 : struct tevent_context *ev, 36 : struct server_id pid) 37 : { 38 63 : struct tevent_req *req, *subreq; 39 63 : struct server_id_watch_state *state; 40 : 41 2790 : req = tevent_req_create(mem_ctx, &state, struct server_id_watch_state); 42 2790 : if (req == NULL) { 43 0 : return NULL; 44 : } 45 2790 : state->ev = ev; 46 2790 : state->pid = pid; 47 : 48 2790 : if (!serverid_exists(&state->pid)) { 49 0 : tevent_req_done(req); 50 0 : return tevent_req_post(req, ev); 51 : } 52 : 53 2790 : subreq = tevent_wakeup_send( 54 : state, ev, tevent_timeval_current_ofs(0, 500000)); 55 2790 : if (tevent_req_nomem(subreq, req)) { 56 0 : return tevent_req_post(req, ev); 57 : } 58 2790 : tevent_req_set_callback(subreq, server_id_watch_waited, req); 59 : 60 2790 : return req; 61 : } 62 : 63 393 : static void server_id_watch_waited(struct tevent_req *subreq) 64 : { 65 393 : struct tevent_req *req = tevent_req_callback_data( 66 : subreq, struct tevent_req); 67 393 : struct server_id_watch_state *state = tevent_req_data( 68 : req, struct server_id_watch_state); 69 5 : bool ok; 70 : 71 393 : ok = tevent_wakeup_recv(subreq); 72 393 : TALLOC_FREE(subreq); 73 393 : if (!ok) { 74 0 : tevent_req_oom(req); 75 0 : return; 76 : } 77 : 78 393 : if (!serverid_exists(&state->pid)) { 79 2 : tevent_req_done(req); 80 2 : return; 81 : } 82 : 83 391 : subreq = tevent_wakeup_send( 84 : state, state->ev, tevent_timeval_current_ofs(0, 500000)); 85 391 : if (tevent_req_nomem(subreq, req)) { 86 0 : return; 87 : } 88 391 : tevent_req_set_callback(subreq, server_id_watch_waited, req); 89 : } 90 : 91 2 : int server_id_watch_recv(struct tevent_req *req, struct server_id *pid) 92 : { 93 2 : struct server_id_watch_state *state = tevent_req_data( 94 : req, struct server_id_watch_state); 95 2 : int err; 96 : 97 2 : if (tevent_req_is_unix_error(req, &err)) { 98 0 : return err; 99 : } 100 2 : if (pid) { 101 0 : *pid = state->pid; 102 : } 103 0 : return 0; 104 : }