diff options
author | Max Kellermann <max@duempel.org> | 2014-09-02 20:13:38 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-09-02 21:27:07 +0200 |
commit | 60589fc1cbc6ecaed80f3b590d02c4fccc674d90 (patch) | |
tree | 11fe60325c0e45f753ed5e8499967a467ef21129 /src/input | |
parent | 5121316036ae5af381066474037fc28fbcd63696 (diff) |
input/nfs: auto-reconnect if failed while paused
Diffstat (limited to 'src/input')
-rw-r--r-- | src/input/plugins/NfsInputPlugin.cxx | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/input/plugins/NfsInputPlugin.cxx b/src/input/plugins/NfsInputPlugin.cxx index a34e6d344..c6c0970b9 100644 --- a/src/input/plugins/NfsInputPlugin.cxx +++ b/src/input/plugins/NfsInputPlugin.cxx @@ -51,13 +51,16 @@ static const size_t NFS_RESUME_AT = 384 * 1024; class NfsInputStream final : public AsyncInputStream, NfsFileReader { uint64_t next_offset; + bool reconnect_on_resume, reconnecting; + public: NfsInputStream(const char *_uri, Mutex &_mutex, Cond &_cond, void *_buffer) :AsyncInputStream(_uri, _mutex, _cond, _buffer, NFS_MAX_BUFFERED, - NFS_RESUME_AT) {} + NFS_RESUME_AT), + reconnect_on_resume(false), reconnecting(false) {} virtual ~NfsInputStream() { DeferClose(); @@ -118,6 +121,28 @@ NfsInputStream::DoRead() void NfsInputStream::DoResume() { + if (reconnect_on_resume) { + /* the NFS connection has died while this stream was + "paused" - attempt to reconnect */ + + reconnect_on_resume = false; + reconnecting = true; + + mutex.unlock(); + NfsFileReader::Close(); + + Error error; + bool success = NfsFileReader::Open(GetURI(), error); + mutex.lock(); + + if (!success) { + postponed_error = std::move(error); + cond.broadcast(); + } + + return; + } + assert(NfsFileReader::IsIdle()); DoRead(); @@ -140,6 +165,14 @@ NfsInputStream::OnNfsFileOpen(uint64_t _size) { const ScopeLock protect(mutex); + if (reconnecting) { + /* reconnect has succeeded */ + + reconnecting = false; + DoRead(); + return; + } + size = _size; seekable = true; next_offset = 0; @@ -164,6 +197,18 @@ void NfsInputStream::OnNfsFileError(Error &&error) { const ScopeLock protect(mutex); + + if (IsPaused()) { + /* while we're paused, don't report this error to the + client just yet (it might just be timeout, maybe + playback has been paused for quite some time) - + wait until the stream gets resumed and try to + reconnect, to give it another chance */ + + reconnect_on_resume = true; + return; + } + postponed_error = std::move(error); if (IsSeekPending()) |