From: Wouter Wijngaards Date: Wed, 11 Mar 2009 11:02:34 +0000 (+0000) Subject: XP tested. winsock event handler fixed for signal events. Neater code integration. X-Git-Tag: release-1.3.0~106 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e4c5af61c6f233737dfa88d1727e0fdeca5a16a0;p=thirdparty%2Funbound.git XP tested. winsock event handler fixed for signal events. Neater code integration. git-svn-id: file:///svn/unbound/trunk@1517 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/daemon.h b/daemon/daemon.h index 21cdbd45f..dd12454a4 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -99,12 +99,6 @@ struct daemon { struct timeval time_last_stat; /** time when daemon started */ struct timeval time_boot; -#ifdef UB_ON_WINDOWS - /** stop signaling event - not owned by this structure */ - WSAEVENT stop_event; - /** event structure for callback */ - struct event stop_ev; -#endif }; /** diff --git a/daemon/worker.c b/daemon/worker.c index ec5bd7aa7..cd5490ff0 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -74,6 +74,9 @@ #include #endif #include +#ifdef UB_ON_WINDOWS +#include "winrc/win_svc.h" +#endif /** Size of an UDP datagram */ #define NORMAL_UDP_SIZE 512 /* bytes */ @@ -997,17 +1000,6 @@ worker_create(struct daemon* daemon, int id, int* ports, int n) return worker; } -#ifdef UB_ON_WINDOWS -void -worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* arg) -{ - struct worker* worker = (struct worker*)arg; - verbose(VERB_QUERY, "caught stop signal (wsaevent)"); - worker->need_to_exit = 1; - comm_base_exit(worker->base); -} -#endif /* UB_ON_WINDOWS */ - int worker_init(struct worker* worker, struct config_file *cfg, struct listen_port* ports, int do_sigs) @@ -1056,13 +1048,7 @@ worker_init(struct worker* worker, struct config_file *cfg, return 0; } #ifdef UB_ON_WINDOWS - if(!winsock_register_wsaevent(comm_base_internal(worker->base), - &worker->daemon->stop_ev, worker->daemon->stop_event, - &worker_win_stop_cb, worker)) { - log_err("could not register wsaevent"); - worker_delete(worker); - return 0; - } + wsvc_setup_worker(worker); #endif /* UB_ON_WINDOWS */ } else { /* !do_sigs */ worker->comsig = NULL; diff --git a/daemon/worker.h b/daemon/worker.h index e9bf38a4a..47e349ed9 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -239,7 +239,4 @@ void worker_stats_clear(struct worker* worker); /** statistics timer callback handler */ void worker_stat_timer_cb(void* arg); -/** windows worker stop event callback handler */ -void worker_win_stop_cb(int fd, short ev, void* arg); - #endif /* DAEMON_WORKER_H */ diff --git a/doc/Changelog b/doc/Changelog index 836febb16..fa897e839 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,9 @@ +11 March 2009: Wouter + - winsock event handler resets WSAevents after signalled. + - winsock event handler tests if signals are really signalled. + - install and service with log to file works on XP and Vista on + default install location. + 10 March 2009: Wouter - makedist -w strips out old rc.. and snapshot info from version. - setup.exe starts and stops unbound after install, before uninstall. diff --git a/testcode/testbound.c b/testcode/testbound.c index f893d6bd6..6a7866040 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -325,3 +325,13 @@ void wsvc_command_option(const char* ATTR_UNUSED(wopt), log_assert(0); } +void wsvc_setup_worker(struct worker* ATTR_UNUSED(worker)) +{ + log_assert(0); +} + +void worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index 4f6404ad2..0e3742cac 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -69,6 +69,9 @@ #include "libunbound/libworker.h" #include "libunbound/context.h" #include "util/tube.h" +#ifdef UB_ON_WINDOWS +#include "winrc/win_svc.h" +#endif int fptr_whitelist_comm_point(comm_point_callback_t *fptr) diff --git a/util/tube.c b/util/tube.c index 74fe936f1..1bf557365 100644 --- a/util/tube.c +++ b/util/tube.c @@ -482,6 +482,9 @@ struct tube* tube_create(void) free(tube); log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError())); } + if(!WSAResetEvent(tube->event)) { + log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError())); + } lock_basic_init(&tube->res_lock); verbose(VERB_ALGO, "tube created"); return tube; diff --git a/util/winsock_event.c b/util/winsock_event.c index 56bf2d6f0..40a238361 100644 --- a/util/winsock_event.c +++ b/util/winsock_event.c @@ -177,6 +177,33 @@ static void handle_timeouts(struct event_base* base, struct timeval* now, } } +/** handle is_signal events and see if signalled */ +static void handle_signal(struct event* ev) +{ + DWORD ret; + log_assert(ev->is_signal && ev->hEvent); + /* see if the event is signalled */ + ret = WSAWaitForMultipleEvents(1, &ev->hEvent, 0 /* any object */, + 0 /* return immediately */, 0 /* not alertable for IOcomple*/); + if(ret == WSA_WAIT_IO_COMPLETION || ret == WSA_WAIT_FAILED) { + log_err("WSAWaitForMultipleEvents(signal) failed: %s", + wsa_strerror(WSAGetLastError())); + return; + } + if(ret == WSA_WAIT_TIMEOUT) { + /* not signalled */ + return; + } + + /* reset the signal */ + if(!WSAResetEvent(ev->hEvent)) + log_err("WSAResetEvent failed: %s", + wsa_strerror(WSAGetLastError())); + /* do the callback (which may set the signal again) */ + fptr_ok(fptr_whitelist_event(ev->ev_callback)); + (*ev->ev_callback)(ev->ev_fd, ev->ev_events, ev->ev_arg); +} + /** call select and callbacks for that */ static int handle_select(struct event_base* base, struct timeval* wait) { @@ -249,11 +276,7 @@ static int handle_select(struct event_base* base, struct timeval* wait) /* eventlist[i] fired */ if(eventlist[i]->is_signal) { /* not a network event at all */ - fptr_ok(fptr_whitelist_event( - eventlist[i]->ev_callback)); - (*eventlist[i]->ev_callback)(eventlist[i]->ev_fd, - eventlist[i]->ev_events, - eventlist[i]->ev_arg); + handle_signal(eventlist[i]); continue; } if(WSAEnumNetworkEvents(eventlist[i]->ev_fd, diff --git a/winrc/win_svc.c b/winrc/win_svc.c index 20014de33..5a18f5478 100644 --- a/winrc/win_svc.c +++ b/winrc/win_svc.c @@ -47,7 +47,10 @@ #include "winrc/win_svc.h" #include "winrc/w_inst.h" #include "daemon/daemon.h" +#include "daemon/worker.h" #include "util/config_file.h" +#include "util/netevent.h" +#include "util/winsock_event.h" /** from gen_msg.h - success message record for windows message log */ #define MSG_GENERIC_SUCCESS ((DWORD)0x20010001L) @@ -64,6 +67,8 @@ SERVICE_STATUS service_status; SERVICE_STATUS_HANDLE service_status_handle; /** global service stop event */ WSAEVENT service_stop_event = NULL; +/** event struct for stop callbacks */ +struct event service_stop_ev; /** config file to open. global communication to service_main() */ const char* service_cfgfile = CONFIGFILE; /** commandline verbosity. global communication to service_main() */ @@ -246,7 +251,9 @@ service_main(DWORD ATTR_UNUSED(argc), LPTSTR* ATTR_UNUSED(argv)) report_status(SERVICE_STOPPED, NO_ERROR, 0); return; } - daemon->stop_event = service_stop_event; + if(!WSAResetEvent(service_stop_event)) { + log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError())); + } /* SetServiceStatus SERVICE_RUNNING;*/ report_status(SERVICE_RUNNING, NO_ERROR, 0); @@ -261,6 +268,7 @@ service_main(DWORD ATTR_UNUSED(argc), LPTSTR* ATTR_UNUSED(argv)) daemon_cleanup(daemon); config_delete(cfg); daemon_delete(daemon); + (void)WSACloseEvent(service_stop_event); verbose(VERB_QUERY, "winservice - full stop"); report_status(SERVICE_STOPPED, NO_ERROR, 0); } @@ -299,3 +307,26 @@ wsvc_command_option(const char* wopt, const char* cfgfile, int v) else fatal_exit("unknown option: %s", wopt); exit(0); } + +void +worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* arg) +{ + struct worker* worker = (struct worker*)arg; + verbose(VERB_QUERY, "caught stop signal (wsaevent)"); + worker->need_to_exit = 1; + comm_base_exit(worker->base); +} + +void wsvc_setup_worker(struct worker* worker) +{ + /* if not started with -w service, do nothing */ + if(!service_stop_event) + return; + if(!winsock_register_wsaevent(comm_base_internal(worker->base), + &service_stop_ev, service_stop_event, + &worker_win_stop_cb, worker)) { + fatal_exit("could not register wsaevent"); + return; + } +} + diff --git a/winrc/win_svc.h b/winrc/win_svc.h index 0c030e720..0b4ecfa60 100644 --- a/winrc/win_svc.h +++ b/winrc/win_svc.h @@ -46,6 +46,7 @@ #ifndef WINRC_WIN_SVC_H #define WINRC_WIN_SVC_H +struct worker; /** service name for unbound (internal to ServiceManager) */ #define SERVICE_NAME "unbound" @@ -58,4 +59,13 @@ */ void wsvc_command_option(const char* wopt, const char* cfgfile, int v); +/** + * Setup lead worker events. + * @param worker: the worker + */ +void wsvc_setup_worker(struct worker* worker); + +/** windows worker stop event callback handler */ +void worker_win_stop_cb(int fd, short ev, void* arg); + #endif /* WINRC_WIN_SVC_H */