diff options
author | Lennart Poettering <lennart@poettering.net> | 2008-07-27 19:07:16 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2008-07-27 19:07:16 +0200 |
commit | c4365abb7cf39d9ec019c58ecec666bf1a09d9a1 (patch) | |
tree | 8574f84a2cf81ff5b2e59d658ca55e6f10ba2fe2 /libasyncns/asyncns.c | |
parent | 92c9e510532a22e3ef774d7721db37e06c2d775d (diff) |
rework thread shutdown logic
Diffstat (limited to 'libasyncns/asyncns.c')
-rw-r--r-- | libasyncns/asyncns.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/libasyncns/asyncns.c b/libasyncns/asyncns.c index e66d6f6..257cb63 100644 --- a/libasyncns/asyncns.c +++ b/libasyncns/asyncns.c @@ -663,7 +663,9 @@ fail: static void* thread_worker(void *p) { sigset_t fullset; int *fds = p; + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); /* No signals in this thread please */ sigfillset(&fullset); @@ -676,9 +678,17 @@ static void* thread_worker(void *p) { if ((length = recv(fds[REQUEST_RECV_FD], buf, sizeof(buf), 0)) <= 0) break; + /* We cannot cancel the thread while it is in on of the name + * resolver functions, because the cleanup might not happen + * properly. To work around this we temporarily disable + * cancellation. The request handling code will eventually + * terminate, and hence we should be safe. */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + if (handle_request(fds[RESPONSE_SEND_FD], buf, (size_t) length) < 0) break; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } return NULL; @@ -765,14 +775,20 @@ void asyncns_free(asyncns_t *asyncns) { for (p = 0; p < asyncns->valid_workers; p++) send(asyncns->fds[REQUEST_SEND_FD], &req, req.length, 0); - /* No terminate them forcibly*/ + /* Now terminate them forcibly */ for (p = 0; p < asyncns->valid_workers; p++) { #ifndef HAVE_PTHREAD kill(asyncns->workers[p], SIGTERM); waitpid(asyncns->workers[p], NULL, 0); #else pthread_cancel(asyncns->workers[p]); - pthread_join(asyncns->workers[p], NULL); + pthread_detach(asyncns->workers[p]); + + /* We don't join the thread here because there is no clean way + to cancel a running lookup if one should be active. So it + might take a while until the lookup thread actually + terminates. But we don't really care, because it won't leak + resources. */ #endif } |