summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2017-02-01 21:36:32 +0100
committerMax Kellermann <max@musicpd.org>2017-02-01 21:44:20 +0100
commit591afa06474b7d71ddb1bf0b95e99387b3378c4c (patch)
tree6eb5f572ab3639e8be242011204908506e98798b
parent05eac20ffe5af325ac7d4019e72d3ac0b69d494a (diff)
lib/nfs/Connection: detect socket hangup and unregister from epoll
Fixes race condition when epoll_ctl() gets called after the socket has been closed, which may affect a different socket created by another thread meanwhile.
-rw-r--r--src/lib/nfs/Connection.cxx9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/lib/nfs/Connection.cxx b/src/lib/nfs/Connection.cxx
index e41c4acd8..b417f2fab 100644
--- a/src/lib/nfs/Connection.cxx
+++ b/src/lib/nfs/Connection.cxx
@@ -416,7 +416,8 @@ NfsConnection::ScheduleSocket()
SocketMonitor::Open(_fd);
}
- SocketMonitor::Schedule(libnfs_to_events(which_events));
+ SocketMonitor::Schedule(libnfs_to_events(which_events)
+ | SocketMonitor::HANGUP);
}
inline int
@@ -453,10 +454,14 @@ NfsConnection::OnSocketReady(unsigned flags)
bool closed = false;
const bool was_mounted = mount_finished;
- if (!mount_finished)
+ if (!mount_finished || (flags & SocketMonitor::HANGUP) != 0)
/* until the mount is finished, the NFS client may use
various sockets, therefore we unregister and
re-register it each time */
+ /* also re-register the socket if we got a HANGUP,
+ which is a sure sign that libnfs will close the
+ socket, which can lead to a race condition if
+ epoll_ctl() is called later */
SocketMonitor::Steal();
const int result = Service(flags);