diff options
author | Zhang Huan <zhanghuan@open-fs.com> | 2019-01-08 16:17:06 +0800 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2019-01-28 04:52:37 +0000 |
commit | f747d55a7fd364e2b9a74fe40360ab3cb7b11537 (patch) | |
tree | 70ccd73edaa2b2e00ba2f3c8006d8624c9875e8d | |
parent | 72922c1fd69191b220f79905a23395c3a87f86ce (diff) |
socket: fix issue on concurrent handle of a socket
Found an issue on concurrent invoke of event handler to the same socket
fd, causing memory corruption. This issue arises after applying commit
"socket: Remove redundant in_lock in incoming message handling" that
removes priv->in_lock to serialize socket read.
The following call sequence describes how concurrent socket event handle
happens.
thread 1 thread 2 thread 3
epoll_wait() return
(slot->in_handler is 0) call select_on_epoll()
and epoll_ctl() on fd
epoll_wait() return
slot->in_handler++
(slot->in_handler is 1)
slot->in_handler++
(slot->in_handler is 2)
call handler() call handler()
Fix this issue by skip invoke of handler if there is already a handler
inprogress.
Change-Id: I437126ac772debcadb00993a948919c931cd607b
updates: bz#1467614
Signed-off-by: Zhang Huan <zhanghuan@open-fs.com>
-rw-r--r-- | libglusterfs/src/event-epoll.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c index 38acdadbe00..dcaf9804529 100644 --- a/libglusterfs/src/event-epoll.c +++ b/libglusterfs/src/event-epoll.c @@ -623,6 +623,12 @@ event_dispatch_epoll_handler(struct event_pool *event_pool, handler = slot->handler; data = slot->data; + if (slot->in_handler > 0) { + /* Another handler is inprogress, skip this one. */ + handler = NULL; + goto pre_unlock; + } + if (slot->handled_error) { handled_error_previously = _gf_true; } else { |