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.
This commit is contained in:
parent
05eac20ffe
commit
591afa0647
|
@ -416,7 +416,8 @@ NfsConnection::ScheduleSocket()
|
||||||
SocketMonitor::Open(_fd);
|
SocketMonitor::Open(_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketMonitor::Schedule(libnfs_to_events(which_events));
|
SocketMonitor::Schedule(libnfs_to_events(which_events)
|
||||||
|
| SocketMonitor::HANGUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
|
@ -453,10 +454,14 @@ NfsConnection::OnSocketReady(unsigned flags)
|
||||||
bool closed = false;
|
bool closed = false;
|
||||||
|
|
||||||
const bool was_mounted = mount_finished;
|
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
|
/* until the mount is finished, the NFS client may use
|
||||||
various sockets, therefore we unregister and
|
various sockets, therefore we unregister and
|
||||||
re-register it each time */
|
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();
|
SocketMonitor::Steal();
|
||||||
|
|
||||||
const int result = Service(flags);
|
const int result = Service(flags);
|
||||||
|
|
Loading…
Reference in New Issue