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:
Wouter Wijngaards 2009-03-11 11:02:34 +00:00
parent 254e6ec34f
commit e4c5af61c6
10 changed files with 96 additions and 33 deletions

View file

@ -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
};
/**

View file

@ -74,6 +74,9 @@
#include <netdb.h>
#endif
#include <signal.h>
#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;

View file

@ -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 */

View file

@ -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.

View file

@ -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);
}

View file

@ -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)

View file

@ -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;

View file

@ -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,

View file

@ -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;
}
}

View file

@ -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 */