Hi Max,
I am so sorry that it's first time at here, so I don't know how to do that
correctly.
My patch was creating from mad-git, the reversion is
34db35c36d8bb32b2c41640432474f52889cce08.
If you need any information more, please let me know, sorry again.
And attached my patch again.
below is the patch
==
diff --git a/src/input/AsyncInputStream.cxx b/src/input/AsyncInputStream.cxx
index 68cb8ff..df37104 100644
--- a/src/input/AsyncInputStream.cxx
+++ b/src/input/AsyncInputStream.cxx
@@ -155,6 +155,20 @@ AsyncInputStream::Seek(offset_type new_offset, Error
&error)
}
void
+AsyncInputStream::SeekStart()
+{
+ assert(io_thread_inside());
+ assert(IsSeekPending());
+
+ /* we may have reached end-of-file previously, and the
+ connection may have been closed already; however after
+ seeking successfully, the connection must be alive again */
+ open = true;
+
+ seek_state = SeekState::PENDING;
+}
+
+void
AsyncInputStream::SeekDone()
{
assert(io_thread_inside());
diff --git a/src/input/AsyncInputStream.hxx b/src/input/AsyncInputStream.hxx
index 64f566a..1ce1716 100644
--- a/src/input/AsyncInputStream.hxx
+++ b/src/input/AsyncInputStream.hxx
@@ -154,6 +154,7 @@ protected:
* Call this after seeking has finished. It will notify the
* client thread.
*/
+ void SeekStart();
void SeekDone();
private:
diff --git a/src/input/plugins/CurlInputPlugin.cxx
b/src/input/plugins/CurlInputPlugin.cxx
index 814fe7a..2745e9d 100644
--- a/src/input/plugins/CurlInputPlugin.cxx
+++ b/src/input/plugins/CurlInputPlugin.cxx
@@ -81,7 +81,7 @@ struct CurlInputStream final : public AsyncInputStream {
_buffer, CURL_MAX_BUFFERED,
CURL_RESUME_AT),
request_headers(nullptr),
-icy(new IcyInputStream(this)) {}
+icy(new IcyInputStream(this)), try_count(0), read_bytes(0) {}
~CurlInputStream();
@@ -130,6 +130,13 @@ struct CurlInputStream final : public AsyncInputStream {
/* virtual methods from AsyncInputStream */
virtual void DoResume() override;
virtual void DoSeek(offset_type new_offset) override;
+
+private:
+ void DoSeekInternal(offset_type new_offset);
+
+ /** connection try count */
+ int try_count;
+ offset_type read_bytes;
};
class CurlMulti;
@@ -297,7 +304,9 @@ CurlInputStream::DoResume()
mutex.unlock();
- curl_easy_pause(easy, CURLPAUSE_CONT);
+ if (easy != nullptr) {
+ curl_easy_pause(easy, CURLPAUSE_CONT);
+ }
if (curl_version_num < 0x072000)
/* libcurl older than 7.32.0 does not update
@@ -441,8 +450,16 @@ CurlInputStream::RequestDone(CURLcode result, long status)
const ScopeLock protect(mutex);
if (result != CURLE_OK) {
- postponed_error.Format(curl_domain, result,
+ /* when network is bad, we need to try one more times */
+ if (try_count++ < 3) {
+ SeekStart();
+ DoSeekInternal(read_bytes);
+ cond.broadcast();
+ return;
+ } else {
+ postponed_error.Format(curl_domain, result,
"curl failed: %s", error_buffer);
+ }
} else if (status < 200 || status >= 300) {
postponed_error.Format(http_domain, status,
"got HTTP status %ld",
@@ -711,8 +728,10 @@ CurlInputStream::DataReceived(const void *ptr, size_t
received_size)
const ScopeLock protect(mutex);
- if (IsSeekPending())
+ if (IsSeekPending()) {
+ try_count = 0;
SeekDone();
+ }
if (received_size > GetBufferSpace()) {
AsyncInputStream::Pause();
@@ -720,6 +739,7 @@ CurlInputStream::DataReceived(const void *ptr, size_t
received_size)
}
AppendToBuffer(ptr, received_size);
+ read_bytes += received_size;
return received_size;
}
@@ -800,6 +820,15 @@ CurlInputStream::InitEasy(Error &error)
void
CurlInputStream::DoSeek(offset_type new_offset)
{
+ try_count = 0;
+ read_bytes = new_offset;
+
+ DoSeekInternal(new_offset);
+}
+
+void
+CurlInputStream::DoSeekInternal(offset_type new_offset)
+{
assert(IsReady());
/* close the old connection and open a new one */
= end patch
=
-- Original --
From: "Max Kellermann";;
Date: Fri, Aug 7, 2015 04:07 AM
To: "矛与盾";
Cc: "mpd-devel";
Subject: Re: [mpd-devel] CurlInputPlugin : broken connection sometimes
--Solved patch
On 2015/08/06 11:31, ?? wrote:
> Hi All,
>
> Attached is