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";<[email protected]>;
Date:  Fri, Aug 7, 2015 04:07 AM
To:  "矛与盾"<[email protected]>;
Cc:  "mpd-devel"<[email protected]>;
Subject:  Re: [mpd-devel] CurlInputPlugin : broken connection sometimes 
--Solved patch

On 2015/08/06 11:31, ?????? <[email protected]> wrote:
> Hi All,
> 
> Attached is for solving this issue which I was discussing at my last email:
> http://mailman.blarg.de/pipermail/mpd-devel/2015-July/000375.html
> 
> 
> It seems work fine after I test, and anyone helps me to double check? Thanks.
> 
> 
> And any feedbacks? Thanks again.

Commit message is missing completely.  I can't do review without
exaplantion in commit message.
_______________________________________________
mpd-devel mailing list
[email protected]
http://mailman.blarg.de/listinfo/mpd-devel

Reply via email to