diff options
author | Max Kellermann <max@musicpd.org> | 2017-02-01 21:36:32 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2017-02-01 21:44:20 +0100 |
commit | 591afa06474b7d71ddb1bf0b95e99387b3378c4c (patch) | |
tree | 6eb5f572ab3639e8be242011204908506e98798b | |
parent | 05eac20ffe5af325ac7d4019e72d3ac0b69d494a (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.cxx | 9 |
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); |