From 635b9c0de15a4bb43ddda25f1f9c19d0945075e2 Mon Sep 17 00:00:00 2001 From: Kaike Wan Date: Thu, 15 May 2014 13:41:47 -0700 Subject: [PATCH] ibacm/prov: Make the retry handler thread cancellable. Signed-off-by: Kaike Wan Signed-off-by: Sean Hefty --- src/acm.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/acm.c b/src/acm.c index dc9690c..318637d 100644 --- a/src/acm.c +++ b/src/acm.c @@ -310,6 +310,8 @@ static atomic_t tid; static DLIST_ENTRY timeout_list; static event_t timeout_event; static atomic_t wait_cnt; +static pthread_t retry_thread_id; +static int retry_thread_started = 0; static SOCKET listen_socket; static SOCKET ip_mon_socket; @@ -1931,7 +1933,7 @@ static void acmp_process_wait_queue(struct acmp_ep *ep, uint64_t *next_expire) * their addition while walking the link lists. Therefore, we need to acquire * the appropriate locks. */ -static void CDECL_FUNC acmp_retry_handler(void *context) +static void *acmp_retry_handler(void *context) { struct acmp_device *dev; struct acmp_port *port; @@ -1941,9 +1943,21 @@ static void CDECL_FUNC acmp_retry_handler(void *context) int i, wait; acm_log(0, "started\n"); + if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { + acm_log(0, "Error: failed to set cancel type \n"); + pthread_exit(NULL); + } + if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) { + acm_log(0, "Error: failed to set cancel state\n"); + pthread_exit(NULL); + } + retry_thread_started = 1; + while (1) { - while (!atomic_get(&wait_cnt)) + while (!atomic_get(&wait_cnt)) { + pthread_testcancel(); event_wait(&timeout_event, -1); + } next_expire = -1; lock_acquire(&acmp_dev_lock); @@ -1977,9 +1991,14 @@ static void CDECL_FUNC acmp_retry_handler(void *context) acmp_process_timeouts(); wait = (int) (next_expire - time_stamp_ms()); - if (wait > 0 && atomic_get(&wait_cnt)) + if (wait > 0 && atomic_get(&wait_cnt)) { + pthread_testcancel(); event_wait(&timeout_event, wait); + } } + + retry_thread_started = 0; + return NULL; } static void acm_init_server(void) @@ -4816,11 +4835,23 @@ int CDECL_FUNC main(int argc, char **argv) acm_activate_devices(); acm_log(1, "starting timeout/retry thread\n"); - beginthread(acmp_retry_handler, NULL); + if (pthread_create(&retry_thread_id, NULL, acmp_retry_handler, NULL)) { + acm_log(0, "Error: failed to create the retry thread"); + retry_thread_started = 0; + return -1; + } acm_log(1, "starting server\n"); acm_server(); acm_log(0, "shutting down\n"); + if (retry_thread_started) { + if (pthread_cancel(retry_thread_id)) + acm_log(0, "Error: failed to cancel the retry thread \n"); + + if (pthread_join(retry_thread_id, NULL)) + acm_log(0, "Error: failed to join the retry thread\n"); + retry_thread_started = 0; + } fclose(flog); return 0; } -- 2.41.0