]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
XP tested. winsock event handler fixed for signal events. Neater code integration.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 11 Mar 2009 11:02:34 +0000 (11:02 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 11 Mar 2009 11:02:34 +0000 (11:02 +0000)
git-svn-id: file:///svn/unbound/trunk@1517 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/daemon.h
daemon/worker.c
daemon/worker.h
doc/Changelog
testcode/testbound.c
util/fptr_wlist.c
util/tube.c
util/winsock_event.c
winrc/win_svc.c
winrc/win_svc.h

index 21cdbd45fca558c16ad6e68841b927261bedf112..dd12454a4dc4b20c95c26eea430da51507d4e657 100644 (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
 };
 
 /**
index ec5bd7aa7529afc8d754c47e31deeb29c2f18b75..cd5490ff09a68b826ef9d8eff11f3bc477f8ac06 100644 (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;
index e9bf38a4a9edf120906c13a96ea3b0b98e61e72d..47e349ed9487a3d926ed1676964da039c2c8676b 100644 (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 */
index 836febb16cf3e95f37d06e89b517ac1f865a8063..fa897e839a3bf97b2dc7e9e7cee464891ca39086 100644 (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.
index f893d6bd63b0df52b78cba4cea8dcdc79ff6a2e7..6a7866040b366ea274f96be0b21c0c1b5feeddd4 100644 (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);
+}
index 4f6404ad2bd3acecb3af24ef7ab0b0970fb8824f..0e3742cacdfdf39a4771081ff51af4705eeba512 100644 (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)
index 74fe936f1585ef0ee42ff0c8f905d545ca2d3243..1bf5573654993e0e9e7b90f2c2293301c26ab343 100644 (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;
index 56bf2d6f0434c63e531e466ee2ffc9d6bc86305a..40a238361936fdb56c89493c2b59b5289cd3a3a6 100644 (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, 
index 20014de3370c131de624125fc172eb9fd71ed237..5a18f5478db919c3b6c4fc3ea54477c41d478a52 100644 (file)
 #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;
+       }
+}
+
index 0c030e7209e90d23e9096cfed4719a28eb42fa71..0b4ecfa60ed0bad9f48a65db6884b1b46d2c844c 100644 (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"
  */
 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 */