lib/nfs/Connection: detect libnfs reconnect
When rpc_reconnect_requeue() gets called from inside nfs_service(), the NfsInputStream can stall completely because the old socket has been unregistered from epoll automatically, but the new one has never been registered. Therefore, nfs_service() will never be called again. This kludge attempts to detect this condition by checking nfs_which_events()==POLLOUT. https://bugs.musicpd.org/view.php?id=4081
This commit is contained in:
parent
38d263ac19
commit
05eac20ffe
2
NEWS
2
NEWS
@ -1,4 +1,6 @@
|
|||||||
ver 0.20.4 (not yet released)
|
ver 0.20.4 (not yet released)
|
||||||
|
* input
|
||||||
|
- nfs: fix freeze after reconnect
|
||||||
* output
|
* output
|
||||||
- sndio: work around a libroar C++ incompatibility
|
- sndio: work around a libroar C++ incompatibility
|
||||||
* workaround for GCC 4.9 "constexpr" bug
|
* workaround for GCC 4.9 "constexpr" bug
|
||||||
|
@ -396,6 +396,17 @@ NfsConnection::ScheduleSocket()
|
|||||||
assert(GetEventLoop().IsInside());
|
assert(GetEventLoop().IsInside());
|
||||||
assert(context != nullptr);
|
assert(context != nullptr);
|
||||||
|
|
||||||
|
const int which_events = nfs_which_events(context);
|
||||||
|
|
||||||
|
if (which_events == POLLOUT && SocketMonitor::IsDefined())
|
||||||
|
/* kludge: if libnfs asks only for POLLOUT, it means
|
||||||
|
that it is currently waiting for the connect() to
|
||||||
|
finish - rpc_reconnect_requeue() may have been
|
||||||
|
called from inside nfs_service(); we must now
|
||||||
|
unregister the old socket and register the new one
|
||||||
|
instead */
|
||||||
|
SocketMonitor::Steal();
|
||||||
|
|
||||||
if (!SocketMonitor::IsDefined()) {
|
if (!SocketMonitor::IsDefined()) {
|
||||||
int _fd = nfs_get_fd(context);
|
int _fd = nfs_get_fd(context);
|
||||||
if (_fd < 0)
|
if (_fd < 0)
|
||||||
@ -405,7 +416,7 @@ NfsConnection::ScheduleSocket()
|
|||||||
SocketMonitor::Open(_fd);
|
SocketMonitor::Open(_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketMonitor::Schedule(libnfs_to_events(nfs_which_events(context)));
|
SocketMonitor::Schedule(libnfs_to_events(which_events));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
|
Loading…
Reference in New Issue
Block a user