Hi

This patch removes a third race, one between the worker init and the manager 
accept.

Currently the manager thread may cause a client to be added to an epoll fd
that has not been initialized yet. So wait until all workers are ready before 
accepting any clients.

- Lauri

PS: Note how this patch is a bit ugly due to the mutex. Atomic instructions 
would have been half the LoC for the same effect.
>From aaaefa535b07c6d7e415f22ce86da8be20cb38be Mon Sep 17 00:00:00 2001
From: Lauri Kasanen <[email protected]>
Date: Thu, 31 May 2012 20:17:42 +0300
Subject: [PATCH 3/3] monkey: wait until all workers are ready

Otherwise the manager thread may cause a client to be added to an epoll fd
that has not been initialized yet.

Signed-off-by: Lauri Kasanen <[email protected]>
---
 src/include/mk_scheduler.h |    3 +++
 src/mk_epoll.c             |    4 ++++
 src/mk_scheduler.c         |    1 +
 src/monkey.c               |   15 +++++++++++++++
 4 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/src/include/mk_scheduler.h b/src/include/mk_scheduler.h
index de0bab4..9179b65 100644
--- a/src/include/mk_scheduler.h
+++ b/src/include/mk_scheduler.h
@@ -56,6 +56,7 @@ struct sched_list_node
     pthread_t tid;
     pid_t pid;
     int epoll_fd;
+    unsigned char initialized;
 
     struct client_session *request_handler;
 };
@@ -73,6 +74,8 @@ typedef struct
 pthread_key_t epoll_fd;
 pthread_key_t worker_sched_node;
 
+extern pthread_mutex_t mutex_worker_init;
+
 void mk_sched_init();
 int mk_sched_register_thread(int epoll_fd);
 int mk_sched_launch_thread(int max_events);
diff --git a/src/mk_epoll.c b/src/mk_epoll.c
index 7cb208b..85e432c 100644
--- a/src/mk_epoll.c
+++ b/src/mk_epoll.c
@@ -86,6 +86,10 @@ void *mk_epoll_init(int efd, mk_epoll_handlers * handler, 
int max_events)
     fds_timeout = log_current_utime + config->timeout;
     events = mk_mem_malloc_z(max_events*sizeof(struct epoll_event));
 
+    pthread_mutex_lock(&mutex_worker_init);
+    sched->initialized = 1;
+    pthread_mutex_unlock(&mutex_worker_init);
+
     while (1) {
         ret = -1;
         num_fds = epoll_wait(efd, events, max_events, MK_EPOLL_WAIT_TIMEOUT);
diff --git a/src/mk_scheduler.c b/src/mk_scheduler.c
index 229fcc5..cd4342c 100644
--- a/src/mk_scheduler.c
+++ b/src/mk_scheduler.c
@@ -43,6 +43,7 @@
 #include "mk_macros.h"
 
 static pthread_mutex_t mutex_sched_init = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t mutex_worker_init = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Returns the worker id which should take a new incomming connection,
diff --git a/src/monkey.c b/src/monkey.c
index 4daeb22..3dbe392 100644
--- a/src/monkey.c
+++ b/src/monkey.c
@@ -192,6 +192,21 @@ int main(int argc, char **argv)
     /* Launch monkey http workers */
     mk_server_launch_workers();
 
+    /* Wait until all workers report as ready */
+    while (1) {
+        int i, ready = 0;
+
+        pthread_mutex_lock(&mutex_worker_init);
+        for (i = 0; i < config->workers; i++) {
+            if (sched_list[i].initialized)
+                ready++;
+        }
+        pthread_mutex_unlock(&mutex_worker_init);
+
+        if (ready == config->workers) break;
+        usleep(10000);
+    }
+
     /* Server loop, let's listen for incomming clients */
     mk_server_loop(config->server_fd);
 
-- 
1.7.2.1

_______________________________________________
Monkey mailing list
[email protected]
http://lists.monkey-project.com/listinfo/monkey

Reply via email to