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
