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
};
/**
#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 */
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)
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;
/** 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 */
+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.
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);
+}
#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)
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;
}
}
+/** 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)
{
/* 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,
#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)
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() */
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);
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);
}
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;
+ }
+}
+
#ifndef WINRC_WIN_SVC_H
#define WINRC_WIN_SVC_H
+struct worker;
/** service name for unbound (internal to ServiceManager) */
#define SERVICE_NAME "unbound"
*/
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 */