mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-24 00:29:58 -05:00
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
This commit is contained in:
parent
254e6ec34f
commit
e4c5af61c6
10 changed files with 96 additions and 33 deletions
|
|
@ -99,12 +99,6 @@ struct daemon {
|
||||||
struct timeval time_last_stat;
|
struct timeval time_last_stat;
|
||||||
/** time when daemon started */
|
/** time when daemon started */
|
||||||
struct timeval time_boot;
|
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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,9 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#ifdef UB_ON_WINDOWS
|
||||||
|
#include "winrc/win_svc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Size of an UDP datagram */
|
/** Size of an UDP datagram */
|
||||||
#define NORMAL_UDP_SIZE 512 /* bytes */
|
#define NORMAL_UDP_SIZE 512 /* bytes */
|
||||||
|
|
@ -997,17 +1000,6 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||||
return worker;
|
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
|
int
|
||||||
worker_init(struct worker* worker, struct config_file *cfg,
|
worker_init(struct worker* worker, struct config_file *cfg,
|
||||||
struct listen_port* ports, int do_sigs)
|
struct listen_port* ports, int do_sigs)
|
||||||
|
|
@ -1056,13 +1048,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef UB_ON_WINDOWS
|
#ifdef UB_ON_WINDOWS
|
||||||
if(!winsock_register_wsaevent(comm_base_internal(worker->base),
|
wsvc_setup_worker(worker);
|
||||||
&worker->daemon->stop_ev, worker->daemon->stop_event,
|
|
||||||
&worker_win_stop_cb, worker)) {
|
|
||||||
log_err("could not register wsaevent");
|
|
||||||
worker_delete(worker);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* UB_ON_WINDOWS */
|
#endif /* UB_ON_WINDOWS */
|
||||||
} else { /* !do_sigs */
|
} else { /* !do_sigs */
|
||||||
worker->comsig = NULL;
|
worker->comsig = NULL;
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,4 @@ void worker_stats_clear(struct worker* worker);
|
||||||
/** statistics timer callback handler */
|
/** statistics timer callback handler */
|
||||||
void worker_stat_timer_cb(void* arg);
|
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 */
|
#endif /* DAEMON_WORKER_H */
|
||||||
|
|
|
||||||
|
|
@ -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
|
10 March 2009: Wouter
|
||||||
- makedist -w strips out old rc.. and snapshot info from version.
|
- makedist -w strips out old rc.. and snapshot info from version.
|
||||||
- setup.exe starts and stops unbound after install, before uninstall.
|
- setup.exe starts and stops unbound after install, before uninstall.
|
||||||
|
|
|
||||||
|
|
@ -325,3 +325,13 @@ void wsvc_command_option(const char* ATTR_UNUSED(wopt),
|
||||||
log_assert(0);
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,9 @@
|
||||||
#include "libunbound/libworker.h"
|
#include "libunbound/libworker.h"
|
||||||
#include "libunbound/context.h"
|
#include "libunbound/context.h"
|
||||||
#include "util/tube.h"
|
#include "util/tube.h"
|
||||||
|
#ifdef UB_ON_WINDOWS
|
||||||
|
#include "winrc/win_svc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
fptr_whitelist_comm_point(comm_point_callback_t *fptr)
|
fptr_whitelist_comm_point(comm_point_callback_t *fptr)
|
||||||
|
|
|
||||||
|
|
@ -482,6 +482,9 @@ struct tube* tube_create(void)
|
||||||
free(tube);
|
free(tube);
|
||||||
log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError()));
|
log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError()));
|
||||||
}
|
}
|
||||||
|
if(!WSAResetEvent(tube->event)) {
|
||||||
|
log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError()));
|
||||||
|
}
|
||||||
lock_basic_init(&tube->res_lock);
|
lock_basic_init(&tube->res_lock);
|
||||||
verbose(VERB_ALGO, "tube created");
|
verbose(VERB_ALGO, "tube created");
|
||||||
return tube;
|
return tube;
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
/** call select and callbacks for that */
|
||||||
static int handle_select(struct event_base* base, struct timeval* wait)
|
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 */
|
/* eventlist[i] fired */
|
||||||
if(eventlist[i]->is_signal) {
|
if(eventlist[i]->is_signal) {
|
||||||
/* not a network event at all */
|
/* not a network event at all */
|
||||||
fptr_ok(fptr_whitelist_event(
|
handle_signal(eventlist[i]);
|
||||||
eventlist[i]->ev_callback));
|
|
||||||
(*eventlist[i]->ev_callback)(eventlist[i]->ev_fd,
|
|
||||||
eventlist[i]->ev_events,
|
|
||||||
eventlist[i]->ev_arg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(WSAEnumNetworkEvents(eventlist[i]->ev_fd,
|
if(WSAEnumNetworkEvents(eventlist[i]->ev_fd,
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,10 @@
|
||||||
#include "winrc/win_svc.h"
|
#include "winrc/win_svc.h"
|
||||||
#include "winrc/w_inst.h"
|
#include "winrc/w_inst.h"
|
||||||
#include "daemon/daemon.h"
|
#include "daemon/daemon.h"
|
||||||
|
#include "daemon/worker.h"
|
||||||
#include "util/config_file.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 */
|
/** from gen_msg.h - success message record for windows message log */
|
||||||
#define MSG_GENERIC_SUCCESS ((DWORD)0x20010001L)
|
#define MSG_GENERIC_SUCCESS ((DWORD)0x20010001L)
|
||||||
|
|
@ -64,6 +67,8 @@ SERVICE_STATUS service_status;
|
||||||
SERVICE_STATUS_HANDLE service_status_handle;
|
SERVICE_STATUS_HANDLE service_status_handle;
|
||||||
/** global service stop event */
|
/** global service stop event */
|
||||||
WSAEVENT service_stop_event = NULL;
|
WSAEVENT service_stop_event = NULL;
|
||||||
|
/** event struct for stop callbacks */
|
||||||
|
struct event service_stop_ev;
|
||||||
/** config file to open. global communication to service_main() */
|
/** config file to open. global communication to service_main() */
|
||||||
const char* service_cfgfile = CONFIGFILE;
|
const char* service_cfgfile = CONFIGFILE;
|
||||||
/** commandline verbosity. global communication to service_main() */
|
/** 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);
|
report_status(SERVICE_STOPPED, NO_ERROR, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
daemon->stop_event = service_stop_event;
|
if(!WSAResetEvent(service_stop_event)) {
|
||||||
|
log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
/* SetServiceStatus SERVICE_RUNNING;*/
|
/* SetServiceStatus SERVICE_RUNNING;*/
|
||||||
report_status(SERVICE_RUNNING, NO_ERROR, 0);
|
report_status(SERVICE_RUNNING, NO_ERROR, 0);
|
||||||
|
|
@ -261,6 +268,7 @@ service_main(DWORD ATTR_UNUSED(argc), LPTSTR* ATTR_UNUSED(argv))
|
||||||
daemon_cleanup(daemon);
|
daemon_cleanup(daemon);
|
||||||
config_delete(cfg);
|
config_delete(cfg);
|
||||||
daemon_delete(daemon);
|
daemon_delete(daemon);
|
||||||
|
(void)WSACloseEvent(service_stop_event);
|
||||||
verbose(VERB_QUERY, "winservice - full stop");
|
verbose(VERB_QUERY, "winservice - full stop");
|
||||||
report_status(SERVICE_STOPPED, NO_ERROR, 0);
|
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);
|
else fatal_exit("unknown option: %s", wopt);
|
||||||
exit(0);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
#ifndef WINRC_WIN_SVC_H
|
#ifndef WINRC_WIN_SVC_H
|
||||||
#define WINRC_WIN_SVC_H
|
#define WINRC_WIN_SVC_H
|
||||||
|
struct worker;
|
||||||
|
|
||||||
/** service name for unbound (internal to ServiceManager) */
|
/** service name for unbound (internal to ServiceManager) */
|
||||||
#define SERVICE_NAME "unbound"
|
#define SERVICE_NAME "unbound"
|
||||||
|
|
@ -58,4 +59,13 @@
|
||||||
*/
|
*/
|
||||||
void wsvc_command_option(const char* wopt, const char* cfgfile, int v);
|
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 */
|
#endif /* WINRC_WIN_SVC_H */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue