diff options
author | Max Kellermann <max@musicpd.org> | 2019-05-16 21:01:26 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2019-05-16 21:11:03 +0200 |
commit | ca06d9d3bf448066c8bb1795ae9a780a18036659 (patch) | |
tree | b6d88797567f04460cb74c4cc758f159d067804e /src/input | |
parent | ed2db04f4350715a8535a1cb734015e7d9acdd48 (diff) |
input/buffered: fix deadlock bug
Diffstat (limited to 'src/input')
-rw-r--r-- | src/input/BufferedInputStream.cxx | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/input/BufferedInputStream.cxx b/src/input/BufferedInputStream.cxx index a5688de47..7ac4f0a2c 100644 --- a/src/input/BufferedInputStream.cxx +++ b/src/input/BufferedInputStream.cxx @@ -165,6 +165,30 @@ BufferedInputStream::RunThread() noexcept seek = false; client_cond.signal(); } else if (!idle && !read_error && + offset != input->GetOffset() && + !IsAvailable()) { + /* a past Seek() call was a no-op because data + was already available at that position, but + now we've reached a new position where + there is no more data in the buffer, and + our input is reading somewhere else (maybe + stuck at the end of the file); to find a + way out, we now seek our input to our + reading position to be able to fill our + buffer */ + + try { + input->Seek(offset); + } catch (...) { + /* this is really a seek error, but we + register it as a read_error, + because seek_error is only checked + by Seek(), and at our frontend (our + own InputStream interface) is in + "read" mode */ + read_error = std::current_exception(); + } + } else if (!idle && !read_error && input->IsAvailable() && !input->IsEOF()) { const auto read_offset = input->GetOffset(); auto w = buffer.Write(read_offset); |