commit 7dfa7e6ec01abe0d0ceddfb64be6e2d3c2ffcc38
parent fecbd058cb0ca1e3a7e5c6bdce5c935fc177bef1
Author: Joris Vink <joris@coders.se>
Date: Fri, 31 May 2013 00:06:54 +0200
be carefull when we reload the module to not reload it when workers are inside the module callbacks.
do this by implementing a pthread rwlock, and locking it for reading when going into a callback and locking it for writing when we need to reload the mod.
Diffstat:
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/example.conf b/example.conf
@@ -2,7 +2,7 @@
# Server configuration.
bind 10.211.55.3 443
-chroot /tmp
+chroot /home/joris/src/kore
runas joris
workers 10
diff --git a/src/kore.c b/src/kore.c
@@ -65,13 +65,14 @@ static TAILQ_HEAD(, connection) disconnected;
static TAILQ_HEAD(, kore_worker) kore_workers;
static TAILQ_HEAD(, reschedule) reschedule_list;
static struct kore_worker *last_worker = NULL;
+static pthread_mutex_t disconnect_lock;
+static pthread_rwlock_t module_lock;
int server_port = 0;
char *server_ip = NULL;
char *chroot_path = NULL;
char *runas_user = NULL;
u_int8_t worker_count = 0;
-pthread_mutex_t disconnect_lock;
static void kore_signal(int);
static void kore_worker_init(void);
@@ -132,6 +133,7 @@ main(int argc, char *argv[])
TAILQ_INIT(&disconnected);
TAILQ_INIT(&reschedule_list);
pthread_mutex_init(&disconnect_lock, NULL);
+ pthread_rwlock_init(&module_lock, NULL);
kore_worker_init();
@@ -142,8 +144,11 @@ main(int argc, char *argv[])
events = kore_calloc(EPOLL_EVENTS, sizeof(struct epoll_event));
for (;;) {
if (sig_recv == SIGHUP) {
- kore_module_reload();
- sig_recv = 0;
+ if (!pthread_rwlock_trywrlock(&module_lock)) {
+ kore_module_reload();
+ sig_recv = 0;
+ pthread_rwlock_unlock(&module_lock);
+ }
}
n = epoll_wait(efd, events, EPOLL_EVENTS, 1000);
@@ -574,11 +579,19 @@ kore_worker_entry(void *arg)
continue;
}
+ if (pthread_rwlock_tryrdlock(&module_lock)) {
+ pthread_mutex_unlock(&(req->owner->lock));
+ pthread_mutex_lock(&(kw->lock));
+ TAILQ_INSERT_TAIL(&(kw->requests), req, list);
+ continue;
+ }
+
hdlr = kore_module_handler_find(req->host, req->path);
if (hdlr == NULL)
r = http_generic_404(req);
else
r = hdlr(req);
+ pthread_rwlock_unlock(&module_lock);
if (r != KORE_RESULT_ERROR) {
r = net_send_flush(req->owner);