event/MultiSocketMonitor: eliminate virtual method CheckSockets()

Handle timeout internally.
This commit is contained in:
Max Kellermann 2013-08-10 11:21:38 +02:00
parent be0c8495cd
commit 84ac79bb08
3 changed files with 16 additions and 36 deletions

View File

@ -42,7 +42,8 @@ static GSourceFuncs multi_socket_monitor_source_funcs = {
MultiSocketMonitor::MultiSocketMonitor(EventLoop &_loop) MultiSocketMonitor::MultiSocketMonitor(EventLoop &_loop)
:loop(_loop), :loop(_loop),
source((Source *)g_source_new(&multi_socket_monitor_source_funcs, source((Source *)g_source_new(&multi_socket_monitor_source_funcs,
sizeof(*source))) { sizeof(*source))),
absolute_timeout_us(G_MAXINT64) {
source->monitor = this; source->monitor = this;
g_source_attach(&source->base, loop.GetContext()); g_source_attach(&source->base, loop.GetContext());
@ -55,10 +56,21 @@ MultiSocketMonitor::~MultiSocketMonitor()
source = nullptr; source = nullptr;
} }
bool
MultiSocketMonitor::Prepare(gint *timeout_r)
{
int timeout_ms = *timeout_r = PrepareSockets();
absolute_timeout_us = timeout_ms < 0
? G_MAXINT64
: GetTime() + gint64(timeout_ms) * 1000;
return false;
}
bool bool
MultiSocketMonitor::Check() const MultiSocketMonitor::Check() const
{ {
if (CheckSockets()) if (GetTime() >= absolute_timeout_us)
return true; return true;
for (const auto &i : fds) for (const auto &i : fds)

View File

@ -52,6 +52,7 @@ class MultiSocketMonitor {
EventLoop &loop; EventLoop &loop;
Source *source; Source *source;
gint64 absolute_timeout_us;
std::forward_list<GPollFD> fds; std::forward_list<GPollFD> fds;
public: public:
@ -105,7 +106,6 @@ protected:
* @return timeout [ms] or -1 for no timeout * @return timeout [ms] or -1 for no timeout
*/ */
virtual int PrepareSockets() = 0; virtual int PrepareSockets() = 0;
virtual bool CheckSockets() const { return false; }
virtual void DispatchSockets() = 0; virtual void DispatchSockets() = 0;
public: public:
@ -116,11 +116,7 @@ public:
gpointer user_data); gpointer user_data);
private: private:
bool Prepare(gint *timeout_r) { bool Prepare(gint *timeout_r);
*timeout_r = PrepareSockets();
return false;
}
bool Check() const; bool Check() const;
void Dispatch() { void Dispatch() {

View File

@ -183,18 +183,6 @@ struct input_curl {
* This class monitors all CURL file descriptors. * This class monitors all CURL file descriptors.
*/ */
class CurlSockets final : private MultiSocketMonitor { class CurlSockets final : private MultiSocketMonitor {
/**
* Did CURL give us a timeout? If yes, then we need to call
* curl_multi_perform(), even if there was no event on any
* file descriptor.
*/
bool have_timeout;
/**
* The absolute time stamp when the timeout expires.
*/
gint64 absolute_timeout;
public: public:
CurlSockets(EventLoop &_loop) CurlSockets(EventLoop &_loop)
:MultiSocketMonitor(_loop) {} :MultiSocketMonitor(_loop) {}
@ -205,7 +193,6 @@ private:
void UpdateSockets(); void UpdateSockets();
virtual int PrepareSockets() override; virtual int PrepareSockets() override;
virtual bool CheckSockets() const override;
virtual void DispatchSockets() override; virtual void DispatchSockets() override;
}; };
@ -541,14 +528,9 @@ CurlSockets::PrepareSockets()
{ {
UpdateSockets(); UpdateSockets();
have_timeout = false;
long timeout2; long timeout2;
CURLMcode mcode = curl_multi_timeout(curl.multi, &timeout2); CURLMcode mcode = curl_multi_timeout(curl.multi, &timeout2);
if (mcode == CURLM_OK) { if (mcode == CURLM_OK) {
if (timeout2 >= 0)
absolute_timeout = GetTime() + timeout2 * 1000;
if (timeout2 >= 0 && timeout2 < 10) if (timeout2 >= 0 && timeout2 < 10)
/* CURL 7.21.1 likes to report "timeout=0", /* CURL 7.21.1 likes to report "timeout=0",
which means we're running in a busy loop. which means we're running in a busy loop.
@ -556,7 +538,6 @@ CurlSockets::PrepareSockets()
Let's use a lower limit of 10ms. */ Let's use a lower limit of 10ms. */
timeout2 = 10; timeout2 = 10;
have_timeout = timeout2 >= 0;
return timeout2; return timeout2;
} else { } else {
g_warning("curl_multi_timeout() failed: %s\n", g_warning("curl_multi_timeout() failed: %s\n",
@ -565,15 +546,6 @@ CurlSockets::PrepareSockets()
} }
} }
bool
CurlSockets::CheckSockets() const
{
/* when a timeout has expired, we need to call
curl_multi_perform(), even if there was no file descriptor
event */
return have_timeout && GetTime() >= absolute_timeout;
}
void void
CurlSockets::DispatchSockets() CurlSockets::DispatchSockets()
{ {