diff options
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/event-epoll.c | 81 | ||||
-rw-r--r-- | libglusterfs/src/event-poll.c | 4 | ||||
-rw-r--r-- | libglusterfs/src/event.c | 59 | ||||
-rw-r--r-- | libglusterfs/src/event.h | 11 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs.h | 2 |
5 files changed, 109 insertions, 48 deletions
diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c index e2b40602e7a..4b76cc96fd3 100644 --- a/libglusterfs/src/event-epoll.c +++ b/libglusterfs/src/event-epoll.c @@ -569,38 +569,11 @@ pre_unlock: if (!handler) goto out; - ret = handler (fd, idx, data, + ret = handler (fd, idx, gen, data, (event->events & (EPOLLIN|EPOLLPRI)), (event->events & (EPOLLOUT)), (event->events & (EPOLLERR|EPOLLHUP))); - LOCK (&slot->lock); - { - slot->in_handler--; - - if (gen != slot->gen) { - /* event_unregister() happened while we were - in handler() - */ - gf_msg_debug ("epoll", 0, "generation bumped on idx=%d" - " from gen=%d to slot->gen=%d, fd=%d, " - "slot->fd=%d", idx, gen, slot->gen, fd, - slot->fd); - goto post_unlock; - } - - /* This call also picks up the changes made by another - thread calling event_select_on_epoll() while this - thread was busy in handler() - */ - if (slot->in_handler == 0) { - event->events = slot->events; - ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD, - fd, event); - } - } -post_unlock: - UNLOCK (&slot->lock); out: event_slot_unref (event_pool, slot, idx); @@ -891,6 +864,55 @@ event_pool_destroy_epoll (struct event_pool *event_pool) return ret; } +static int +event_handled_epoll (struct event_pool *event_pool, int fd, int idx, int gen) +{ + struct event_slot_epoll *slot = NULL; + struct epoll_event epoll_event = {0, }; + struct event_data *ev_data = (void *)&epoll_event.data; + int ret = 0; + + slot = event_slot_get (event_pool, idx); + + assert (slot->fd == fd); + + LOCK (&slot->lock); + { + slot->in_handler--; + + if (gen != slot->gen) { + /* event_unregister() happened while we were + in handler() + */ + gf_msg_debug ("epoll", 0, "generation bumped on idx=%d" + " from gen=%d to slot->gen=%d, fd=%d, " + "slot->fd=%d", idx, gen, slot->gen, fd, + slot->fd); + goto post_unlock; + } + + /* This call also picks up the changes made by another + thread calling event_select_on_epoll() while this + thread was busy in handler() + */ + if (slot->in_handler == 0) { + epoll_event.events = slot->events; + ev_data->idx = idx; + ev_data->gen = gen; + + ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD, + fd, &epoll_event); + } + } +post_unlock: + UNLOCK (&slot->lock); + + event_slot_unref (event_pool, slot, idx); + + return ret; +} + + struct event_ops event_ops_epoll = { .new = event_pool_new_epoll, .event_register = event_register_epoll, @@ -899,7 +921,8 @@ struct event_ops event_ops_epoll = { .event_unregister_close = event_unregister_close_epoll, .event_dispatch = event_dispatch_epoll, .event_reconfigure_threads = event_reconfigure_threads_epoll, - .event_pool_destroy = event_pool_destroy_epoll + .event_pool_destroy = event_pool_destroy_epoll, + .event_handled = event_handled_epoll, }; #endif diff --git a/libglusterfs/src/event-poll.c b/libglusterfs/src/event-poll.c index 2006e33d33b..3bffc4784d7 100644 --- a/libglusterfs/src/event-poll.c +++ b/libglusterfs/src/event-poll.c @@ -40,7 +40,7 @@ event_register_poll (struct event_pool *event_pool, int fd, static int -__flush_fd (int fd, int idx, void *data, +__flush_fd (int fd, int idx, int gen, void *data, int poll_in, int poll_out, int poll_err) { char buf[64]; @@ -386,7 +386,7 @@ unlock: pthread_mutex_unlock (&event_pool->mutex); if (handler) - ret = handler (ufds[i].fd, idx, data, + ret = handler (ufds[i].fd, idx, 0, data, (ufds[i].revents & (POLLIN|POLLPRI)), (ufds[i].revents & (POLLOUT)), (ufds[i].revents & (POLLERR|POLLHUP|POLLNVAL))); diff --git a/libglusterfs/src/event.c b/libglusterfs/src/event.c index 6aaa53499df..bba6f8429a1 100644 --- a/libglusterfs/src/event.c +++ b/libglusterfs/src/event.c @@ -159,8 +159,9 @@ event_pool_destroy (struct event_pool *event_pool) } pthread_mutex_unlock (&event_pool->mutex); - if (!destroy || (activethreadcount > 0)) + if (!destroy || (activethreadcount > 0)) { goto out; + } ret = event_pool->ops->event_pool_destroy (event_pool); out: @@ -168,19 +169,27 @@ out: } int -poller_destroy_handler (int fd, int idx, void *data, +poller_destroy_handler (int fd, int idx, int gen, void *data, int poll_out, int poll_in, int poll_err) { - int readfd = -1; - char buf = '\0'; + struct event_destroy_data *destroy = NULL; + int readfd = -1, ret = -1; + char buf = '\0'; - readfd = *(int *)data; - if (readfd < 0) - return -1; + destroy = data; + readfd = destroy->readfd; + if (readfd < 0) { + goto out; + } while (sys_read (readfd, &buf, 1) > 0) { } - return 0; + + ret = 0; +out: + event_handled (destroy->pool, fd, idx, gen); + + return ret; } /* This function destroys all the poller threads. @@ -197,11 +206,12 @@ poller_destroy_handler (int fd, int idx, void *data, int event_dispatch_destroy (struct event_pool *event_pool) { - int ret = -1; - int fd[2] = {-1}; - int idx = -1; - int flags = 0; - struct timespec sleep_till = {0, }; + int ret = -1, threadcount = 0; + int fd[2] = {-1}; + int idx = -1; + int flags = 0; + struct timespec sleep_till = {0, }; + struct event_destroy_data data = {0, }; GF_VALIDATE_OR_GOTO ("event", event_pool, out); @@ -223,10 +233,13 @@ event_dispatch_destroy (struct event_pool *event_pool) if (ret < 0) goto out; + data.pool = event_pool; + data.readfd = fd[1]; + /* From the main thread register an event on the pipe fd[0], */ idx = event_register (event_pool, fd[0], poller_destroy_handler, - &fd[1], 1, 0); + &data, 1, 0); if (idx < 0) goto out; @@ -235,6 +248,7 @@ event_dispatch_destroy (struct event_pool *event_pool) */ pthread_mutex_lock (&event_pool->mutex); { + threadcount = event_pool->eventthreadcount; event_pool->destroy = 1; } pthread_mutex_unlock (&event_pool->mutex); @@ -254,9 +268,11 @@ event_dispatch_destroy (struct event_pool *event_pool) */ int retry = 0; - while (event_pool->activethreadcount > 0 && retry++ < 10) { - if (sys_write (fd[1], "dummy", 6) == -1) + while (event_pool->activethreadcount > 0 + && (retry++ < (threadcount + 10))) { + if (sys_write (fd[1], "dummy", 6) == -1) { break; + } sleep_till.tv_sec = time (NULL) + 1; ret = pthread_cond_timedwait (&event_pool->cond, &event_pool->mutex, @@ -275,3 +291,14 @@ event_dispatch_destroy (struct event_pool *event_pool) return ret; } + +int +event_handled (struct event_pool *event_pool, int fd, int idx, int gen) +{ + int ret = 0; + + if (event_pool->ops->event_handled) + ret = event_pool->ops->event_handled (event_pool, fd, idx, gen); + + return ret; +} diff --git a/libglusterfs/src/event.h b/libglusterfs/src/event.h index 1348f5d05c0..c60b14ad04b 100644 --- a/libglusterfs/src/event.h +++ b/libglusterfs/src/event.h @@ -23,7 +23,7 @@ struct event_data { } __attribute__ ((__packed__, __may_alias__)); -typedef int (*event_handler_t) (int fd, int idx, void *data, +typedef int (*event_handler_t) (int fd, int idx, int gen, void *data, int poll_in, int poll_out, int poll_err); #define EVENT_EPOLL_TABLES 1024 @@ -73,6 +73,11 @@ struct event_pool { }; +struct event_destroy_data { + int readfd; + struct event_pool *pool; +}; + struct event_ops { struct event_pool * (*new) (int count, int eventthreadcount); @@ -93,6 +98,8 @@ struct event_ops { int (*event_reconfigure_threads) (struct event_pool *event_pool, int newcount); int (*event_pool_destroy) (struct event_pool *event_pool); + int (*event_handled) (struct event_pool *event_pool, int fd, int idx, + int gen); }; struct event_pool *event_pool_new (int count, int eventthreadcount); @@ -107,4 +114,6 @@ int event_dispatch (struct event_pool *event_pool); int event_reconfigure_threads (struct event_pool *event_pool, int value); int event_pool_destroy (struct event_pool *event_pool); int event_dispatch_destroy (struct event_pool *event_pool); +int event_handled (struct event_pool *event_pool, int fd, int idx, int gen); + #endif /* _EVENT_H_ */ diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 839a1d47d2a..2e709b9d703 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -520,6 +520,8 @@ struct _glusterfs_ctx { int notifying; struct gf_ctx_tw *tw; /* refcounted timer_wheel */ + + gf_lock_t volfile_lock; }; typedef struct _glusterfs_ctx glusterfs_ctx_t; |