static void * event_dispatch_epoll_worker (void *data) { struct epoll_event event; int ret = -1; struct event_thread_data *ev_data = data; struct event_pool *event_pool; int myindex = -1; int timetodie = 0; GF_VALIDATE_OR_GOTO ("event", ev_data, out); event_pool = ev_data->event_pool; myindex = ev_data->event_index; GF_VALIDATE_OR_GOTO ("event", event_pool, out); gf_log ("epoll", GF_LOG_INFO, "Started thread with index %d", myindex); pthread_mutex_lock (&event_pool->mutex); { event_pool->activethreadcount++; } pthread_mutex_unlock (&event_pool->mutex); for (;;) { if (event_pool->eventthreadcount < myindex) { /* ...time to die, thread count was decreased below * this threads index */ /* Start with extra safety at this point, reducing * lock conention in normal case when threads are not * reconfigured always */ pthread_mutex_lock (&event_pool->mutex); { if (event_pool->eventthreadcount < myindex) { /* if found true in critical section, * die */ event_pool->pollers[myindex - 1] = 0; event_pool->activethreadcount--; timetodie = 1; pthread_cond_broadcast (&event_pool->cond); } } pthread_mutex_unlock (&event_pool->mutex); if (timetodie) { gf_log ("epoll", GF_LOG_INFO, "Exited thread with index %d", myindex); goto out; } } ret = epoll_wait (event_pool->fd, &event, 1, -1); if (ret == 0) /* timeout */ continue; if (ret == -1 && errno == EINTR) /* sys call */ continue; ret = event_dispatch_epoll_handler (event_pool, &event); } out: if (ev_data) GF_FREE (ev_data); return NULL; }
static int event_dispatch_epoll (struct event_pool *event_pool) { struct epoll_event *events = NULL; int size = 0; int i = 0; int ret = -1; syslog(LOG_INFO | LOG_LOCAL1, "%s", "event_dispatch_epoll"); GF_VALIDATE_OR_GOTO ("event", event_pool, out); while (1) { pthread_mutex_lock (&event_pool->mutex); { while (event_pool->used == 0) pthread_cond_wait (&event_pool->cond, &event_pool->mutex); if (event_pool->used > event_pool->evcache_size) { GF_FREE (event_pool->evcache); event_pool->evcache = events = NULL; event_pool->evcache_size = event_pool->used + 256; events = GF_CALLOC (event_pool->evcache_size, sizeof (struct epoll_event), gf_common_mt_epoll_event); if (!events) break; event_pool->evcache = events; } } pthread_mutex_unlock (&event_pool->mutex); ret = epoll_wait (event_pool->fd, event_pool->evcache, event_pool->evcache_size, -1); if (ret == 0) /* timeout */ continue; if (ret == -1 && errno == EINTR) /* sys call */ continue; size = ret; for (i = 0; i < size; i++) { if (!events || !events[i].events) continue; ret = event_dispatch_epoll_handler (event_pool, events, i); } } out: return ret; }