static int event_unregister_poll (struct event_pool *event_pool, int fd, int idx_hint) { int idx = -1; GF_VALIDATE_OR_GOTO ("event", event_pool, out); pthread_mutex_lock (&event_pool->mutex); { idx = __event_getindex (event_pool, fd, idx_hint); if (idx == -1) { gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "index not found for fd=%d (idx_hint=%d)", fd, idx_hint); errno = ENOENT; goto unlock; } event_pool->reg[idx] = event_pool->reg[--event_pool->used]; event_pool->changed = 1; } unlock: pthread_mutex_unlock (&event_pool->mutex); out: return idx; }
static int event_select_on_poll (struct event_pool *event_pool, int fd, int idx_hint, int poll_in, int poll_out) { int idx = -1; GF_VALIDATE_OR_GOTO ("event", event_pool, out); pthread_mutex_lock (&event_pool->mutex); { idx = __event_getindex (event_pool, fd, idx_hint); if (idx == -1) { gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "index not found for fd=%d (idx_hint=%d)", fd, idx_hint); errno = ENOENT; goto unlock; } switch (poll_in) { case 1: event_pool->reg[idx].events |= POLLIN; break; case 0: event_pool->reg[idx].events &= ~POLLIN; break; case -1: /* do nothing */ break; default: /* TODO: log error */ break; } switch (poll_out) { case 1: event_pool->reg[idx].events |= POLLOUT; break; case 0: event_pool->reg[idx].events &= ~POLLOUT; break; case -1: /* do nothing */ break; default: /* TODO: log error */ break; } if (poll_in + poll_out > -2) event_pool->changed = 1; } unlock: pthread_mutex_unlock (&event_pool->mutex); out: return idx; }
static int event_dispatch_epoll_handler (struct event_pool *event_pool, struct epoll_event *events, int i) { struct event_data *event_data = NULL; event_handler_t handler = NULL; void *data = NULL; int idx = -1; int ret = -1; event_data = (void *)&events[i].data; handler = NULL; data = NULL; pthread_mutex_lock (&event_pool->mutex); { idx = __event_getindex (event_pool, event_data->fd, event_data->idx); if (idx == -1) { gf_log ("epoll", GF_LOG_ERROR, "index not found for fd(=%d) (idx_hint=%d)", event_data->fd, event_data->idx); goto unlock; } handler = event_pool->reg[idx].handler; data = event_pool->reg[idx].data; } unlock: pthread_mutex_unlock (&event_pool->mutex); if (handler) ret = handler (event_data->fd, event_data->idx, data, (events[i].events & (EPOLLIN|EPOLLPRI)), (events[i].events & (EPOLLOUT)), (events[i].events & (EPOLLERR|EPOLLHUP))); return ret; }
static int event_dispatch_poll_handler (struct event_pool *event_pool, struct pollfd *ufds, int i) { event_handler_t handler = NULL; void *data = NULL; int idx = -1; int ret = 0; handler = NULL; data = NULL; pthread_mutex_lock (&event_pool->mutex); { idx = __event_getindex (event_pool, ufds[i].fd, i); if (idx == -1) { gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "index not found for " "fd=%d (idx_hint=%d)", ufds[i].fd, i); goto unlock; } handler = event_pool->reg[idx].handler; data = event_pool->reg[idx].data; } unlock: pthread_mutex_unlock (&event_pool->mutex); if (handler) ret = handler (ufds[i].fd, idx, data, (ufds[i].revents & (POLLIN|POLLPRI)), (ufds[i].revents & (POLLOUT)), (ufds[i].revents & (POLLERR|POLLHUP|POLLNVAL))); return ret; }
static int event_select_on_epoll (struct event_pool *event_pool, int fd, int idx_hint, int poll_in, int poll_out) { int idx = -1; int ret = -1; struct epoll_event epoll_event = {0, }; struct event_data *ev_data = (void *)&epoll_event.data; GF_VALIDATE_OR_GOTO ("event", event_pool, out); pthread_mutex_lock (&event_pool->mutex); { idx = __event_getindex (event_pool, fd, idx_hint); if (idx == -1) { gf_log ("epoll", GF_LOG_ERROR, "index not found for fd=%d (idx_hint=%d)", fd, idx_hint); errno = ENOENT; goto unlock; } switch (poll_in) { case 1: event_pool->reg[idx].events |= EPOLLIN; break; case 0: event_pool->reg[idx].events &= ~EPOLLIN; break; case -1: /* do nothing */ break; default: gf_log ("epoll", GF_LOG_ERROR, "invalid poll_in value %d", poll_in); break; } switch (poll_out) { case 1: event_pool->reg[idx].events |= EPOLLOUT; break; case 0: event_pool->reg[idx].events &= ~EPOLLOUT; break; case -1: /* do nothing */ break; default: gf_log ("epoll", GF_LOG_ERROR, "invalid poll_out value %d", poll_out); break; } epoll_event.events = event_pool->reg[idx].events; ev_data->fd = fd; ev_data->idx = idx; ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD, fd, &epoll_event); if (ret == -1) { gf_log ("epoll", GF_LOG_ERROR, "failed to modify fd(=%d) events to %d", fd, epoll_event.events); } } unlock: pthread_mutex_unlock (&event_pool->mutex); out: return ret; }
static int event_unregister_epoll (struct event_pool *event_pool, int fd, int idx_hint) { int idx = -1; int ret = -1; struct epoll_event epoll_event = {0, }; struct event_data *ev_data = (void *)&epoll_event.data; int lastidx = -1; GF_VALIDATE_OR_GOTO ("event", event_pool, out); pthread_mutex_lock (&event_pool->mutex); { idx = __event_getindex (event_pool, fd, idx_hint); if (idx == -1) { gf_log ("epoll", GF_LOG_ERROR, "index not found for fd=%d (idx_hint=%d)", fd, idx_hint); errno = ENOENT; goto unlock; } ret = epoll_ctl (event_pool->fd, EPOLL_CTL_DEL, fd, NULL); /* if ret is -1, this array member should never be accessed */ /* if it is 0, the array member might be used by idx_cache * in which case the member should not be accessed till * it is reallocated */ event_pool->reg[idx].fd = -1; if (ret == -1) { gf_log ("epoll", GF_LOG_ERROR, "fail to del fd(=%d) from epoll fd(=%d) (%s)", fd, event_pool->fd, strerror (errno)); goto unlock; } lastidx = event_pool->used - 1; if (lastidx == idx) { event_pool->used--; goto unlock; } epoll_event.events = event_pool->reg[lastidx].events; ev_data->fd = event_pool->reg[lastidx].fd; ev_data->idx = idx; ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD, ev_data->fd, &epoll_event); if (ret == -1) { gf_log ("epoll", GF_LOG_ERROR, "fail to modify fd(=%d) index %d to %d (%s)", ev_data->fd, event_pool->used, idx, strerror (errno)); goto unlock; } /* just replace the unregistered idx by last one */ event_pool->reg[idx] = event_pool->reg[lastidx]; event_pool->used--; } unlock: pthread_mutex_unlock (&event_pool->mutex); out: return ret; }