summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/curl/Global.cxx61
-rw-r--r--src/lib/curl/Global.hxx2
-rw-r--r--src/lib/curl/Multi.hxx41
-rw-r--r--src/lib/dbus/AppendIter.hxx8
-rw-r--r--src/lib/dbus/ReadIter.hxx9
-rw-r--r--src/lib/dbus/Types.hxx38
-rw-r--r--src/lib/dbus/UDisks2.cxx17
-rw-r--r--src/lib/dbus/Values.hxx4
-rw-r--r--src/lib/dbus/Watch.cxx24
-rw-r--r--src/lib/dbus/Watch.hxx9
-rw-r--r--src/lib/nfs/Connection.cxx38
-rw-r--r--src/lib/nfs/Connection.hxx16
-rw-r--r--src/lib/nfs/Manager.hxx16
13 files changed, 159 insertions, 124 deletions
diff --git a/src/lib/curl/Global.cxx b/src/lib/curl/Global.cxx
index 8b32eae97..a43699f57 100644
--- a/src/lib/curl/Global.cxx
+++ b/src/lib/curl/Global.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2019 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright 2008-2020 Max Kellermann <max.kellermann@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,25 +29,23 @@
#include "Global.hxx"
#include "Request.hxx"
-#include "Log.hxx"
#include "event/Loop.hxx"
-#include "event/SocketMonitor.hxx"
-#include "util/RuntimeError.hxx"
-#include "util/Domain.hxx"
+#include "event/SocketEvent.hxx"
#include <cassert>
-static constexpr Domain curlm_domain("curlm");
-
/**
* Monitor for one socket created by CURL.
*/
-class CurlSocket final : SocketMonitor {
+class CurlSocket final {
CurlGlobal &global;
+ SocketEvent socket_event;
+
public:
CurlSocket(CurlGlobal &_global, EventLoop &_loop, SocketDescriptor _fd)
- :SocketMonitor(_fd, _loop), global(_global) {}
+ :global(_global),
+ socket_event(_loop, BIND_THIS_METHOD(OnSocketReady), _fd) {}
~CurlSocket() noexcept {
/* TODO: sometimes, CURL uses CURL_POLL_REMOVE after
@@ -59,6 +57,10 @@ public:
better solution? */
}
+ auto &GetEventLoop() const noexcept {
+ return socket_event.GetEventLoop();
+ }
+
/**
* Callback function for CURLMOPT_SOCKETFUNCTION.
*/
@@ -66,13 +68,17 @@ public:
curl_socket_t s, int action,
void *userp, void *socketp) noexcept;
- bool OnSocketReady(unsigned flags) noexcept override;
-
private:
+ SocketDescriptor GetSocket() const noexcept {
+ return socket_event.GetSocket();
+ }
+
+ void OnSocketReady(unsigned events) noexcept;
+
static constexpr int FlagsToCurlCSelect(unsigned flags) noexcept {
- return (flags & (READ | HANGUP) ? CURL_CSELECT_IN : 0) |
- (flags & WRITE ? CURL_CSELECT_OUT : 0) |
- (flags & ERROR ? CURL_CSELECT_ERR : 0);
+ return (flags & (SocketEvent::READ | SocketEvent::HANGUP) ? CURL_CSELECT_IN : 0) |
+ (flags & SocketEvent::WRITE ? CURL_CSELECT_OUT : 0) |
+ (flags & SocketEvent::ERROR ? CURL_CSELECT_ERR : 0);
}
gcc_const
@@ -82,13 +88,13 @@ private:
return 0;
case CURL_POLL_IN:
- return READ;
+ return SocketEvent::READ;
case CURL_POLL_OUT:
- return WRITE;
+ return SocketEvent::WRITE;
case CURL_POLL_INOUT:
- return READ|WRITE;
+ return SocketEvent::READ|SocketEvent::WRITE;
}
assert(false);
@@ -130,17 +136,16 @@ CurlSocket::SocketFunction([[maybe_unused]] CURL *easy,
unsigned flags = CurlPollToFlags(action);
if (flags != 0)
- cs->Schedule(flags);
+ cs->socket_event.Schedule(flags);
return 0;
}
-bool
+void
CurlSocket::OnSocketReady(unsigned flags) noexcept
{
assert(GetEventLoop().IsInside());
global.SocketAction(GetSocket().Get(), FlagsToCurlCSelect(flags));
- return true;
}
void
@@ -148,10 +153,7 @@ CurlGlobal::Add(CurlRequest &r)
{
assert(GetEventLoop().IsInside());
- CURLMcode mcode = curl_multi_add_handle(multi.Get(), r.Get());
- if (mcode != CURLM_OK)
- throw FormatRuntimeError("curl_multi_add_handle() failed: %s",
- curl_multi_strerror(mcode));
+ multi.Add(r.Get());
InvalidateSockets();
}
@@ -161,7 +163,7 @@ CurlGlobal::Remove(CurlRequest &r) noexcept
{
assert(GetEventLoop().IsInside());
- curl_multi_remove_handle(multi.Get(), r.Get());
+ multi.Remove(r.Get());
}
/**
@@ -185,10 +187,8 @@ CurlGlobal::ReadInfo() noexcept
assert(GetEventLoop().IsInside());
CURLMsg *msg;
- int msgs_in_queue;
- while ((msg = curl_multi_info_read(multi.Get(),
- &msgs_in_queue)) != nullptr) {
+ while ((msg = multi.InfoRead()) != nullptr) {
if (msg->msg == CURLMSG_DONE) {
auto *request = ToRequest(msg->easy_handle);
if (request != nullptr)
@@ -203,10 +203,7 @@ CurlGlobal::SocketAction(curl_socket_t fd, int ev_bitmask) noexcept
int running_handles;
CURLMcode mcode = curl_multi_socket_action(multi.Get(), fd, ev_bitmask,
&running_handles);
- if (mcode != CURLM_OK)
- FormatError(curlm_domain,
- "curl_multi_socket_action() failed: %s",
- curl_multi_strerror(mcode));
+ (void)mcode;
defer_read_info.Schedule();
}
diff --git a/src/lib/curl/Global.hxx b/src/lib/curl/Global.hxx
index 95065e9da..8eb514994 100644
--- a/src/lib/curl/Global.hxx
+++ b/src/lib/curl/Global.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2019 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright 2008-2020 Max Kellermann <max.kellermann@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/src/lib/curl/Multi.hxx b/src/lib/curl/Multi.hxx
index ecbd0c92a..2365bd801 100644
--- a/src/lib/curl/Multi.hxx
+++ b/src/lib/curl/Multi.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2018 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright 2016-2020 Max Kellermann <max.kellermann@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
#include <curl/curl.h>
+#include <chrono>
#include <utility>
#include <stdexcept>
#include <cstddef>
@@ -87,6 +88,44 @@ public:
if (code != CURLM_OK)
throw std::runtime_error(curl_multi_strerror(code));
}
+
+ void Add(CURL *easy_handle) {
+ auto code = curl_multi_add_handle(handle, easy_handle);
+ if (code != CURLM_OK)
+ throw std::runtime_error(curl_multi_strerror(code));
+ }
+
+ void Remove(CURL *easy_handle) {
+ auto code = curl_multi_remove_handle(handle, easy_handle);
+ if (code != CURLM_OK)
+ throw std::runtime_error(curl_multi_strerror(code));
+ }
+
+ CURLMsg *InfoRead() {
+ int msgs_in_queue;
+ return curl_multi_info_read(handle, &msgs_in_queue);
+ }
+
+ unsigned Perform() {
+ int running_handles;
+ auto code = curl_multi_perform(handle, &running_handles);
+ if (code != CURLM_OK)
+ throw std::runtime_error(curl_multi_strerror(code));
+ return running_handles;
+ }
+
+ unsigned Wait(int timeout=-1) {
+ int numfds;
+ auto code = curl_multi_wait(handle, nullptr, 0, timeout,
+ &numfds);
+ if (code != CURLM_OK)
+ throw std::runtime_error(curl_multi_strerror(code));
+ return numfds;
+ }
+
+ unsigned Wait(std::chrono::milliseconds timeout) {
+ return Wait(timeout.count());
+ }
};
#endif
diff --git a/src/lib/dbus/AppendIter.hxx b/src/lib/dbus/AppendIter.hxx
index 183f24537..b3dc28747 100644
--- a/src/lib/dbus/AppendIter.hxx
+++ b/src/lib/dbus/AppendIter.hxx
@@ -103,7 +103,7 @@ public:
template<typename T>
AppendMessageIter &AppendEmptyArray() {
return AppendMessageIter(*this, DBUS_TYPE_ARRAY,
- T::TypeAsString::value)
+ T::as_string)
.CloseContainer(*this);
}
@@ -120,7 +120,7 @@ public:
AppendMessageIter &AppendVariant(const T &value) {
typedef VariantTypeTraits Traits;
return AppendMessageIter(*this, Traits::TYPE,
- Traits::TypeAsString::value)
+ Traits::as_string)
.Append(value)
.CloseContainer(*this);
}
@@ -146,7 +146,7 @@ public:
typedef typename W::ContainedTraits ContainedTraits;
return AppendMessageIter(*this, Traits::TYPE,
- ContainedTraits::TypeAsString::value)
+ ContainedTraits::as_string)
.Append(value.value)
.CloseContainer(*this);
}
@@ -158,7 +158,7 @@ public:
typedef typename W::ContainedTraits ContainedTraits;
return AppendMessageIter(*this, Traits::TYPE,
- ContainedTraits::TypeAsString::value)
+ ContainedTraits::as_string)
.AppendFixedArray(value.value)
.CloseContainer(*this);
}
diff --git a/src/lib/dbus/ReadIter.hxx b/src/lib/dbus/ReadIter.hxx
index 4d549a253..ceb7675c6 100644
--- a/src/lib/dbus/ReadIter.hxx
+++ b/src/lib/dbus/ReadIter.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2017 Content Management AG
+ * Copyright 2007-2020 CM4all GmbH
* All rights reserved.
*
* author: Max Kellermann <mk@cm4all.com>
@@ -34,15 +34,8 @@
#define ODBUS_READ_ITER_HXX
#include "Iter.hxx"
-#include "util/Compiler.h"
#include "util/ConstBuffer.hxx"
-#if GCC_OLDER_THAN(8,0)
-/* switch off completely bogus shadow warnings in older GCC
- versions */
-#pragma GCC diagnostic ignored "-Wshadow"
-#endif
-
namespace ODBus {
class ReadMessageIter : public MessageIter {
diff --git a/src/lib/dbus/Types.hxx b/src/lib/dbus/Types.hxx
index 72b3d5682..99662dc45 100644
--- a/src/lib/dbus/Types.hxx
+++ b/src/lib/dbus/Types.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2017 Content Management AG
+ * Copyright 2007-2020 CM4all GmbH
* All rights reserved.
*
* author: Max Kellermann <mk@cm4all.com>
@@ -42,7 +42,7 @@ namespace ODBus {
template<int type>
struct BasicTypeTraits {
static constexpr int TYPE = type;
- typedef TemplateString::CharAsString<TYPE> TypeAsString;
+ static constexpr auto as_string = TemplateString::FromChar(TYPE);
};
template<typename T>
@@ -70,20 +70,23 @@ using BooleanTypeTraits = BasicTypeTraits<DBUS_TYPE_BOOLEAN>;
template<typename T>
struct ArrayTypeTraits {
- typedef T ContainedTraits;
+ using ContainedTraits = T;
static constexpr int TYPE = DBUS_TYPE_ARRAY;
- typedef TemplateString::InsertBefore<TYPE, typename ContainedTraits::TypeAsString> TypeAsString;
+ static constexpr auto as_string =
+ TemplateString::Concat(TemplateString::FromChar(TYPE),
+ ContainedTraits::as_string);
};
template<typename KeyT, typename ValueT>
struct DictEntryTypeTraits {
static constexpr int TYPE = DBUS_TYPE_DICT_ENTRY;
- typedef TemplateString::Concat<TemplateString::CharAsString<DBUS_DICT_ENTRY_BEGIN_CHAR>,
- typename KeyT::TypeAsString,
- typename ValueT::TypeAsString,
- TemplateString::CharAsString<DBUS_DICT_ENTRY_END_CHAR>> TypeAsString;
+ static constexpr auto as_string =
+ TemplateString::Concat(TemplateString::FromChar(DBUS_DICT_ENTRY_BEGIN_CHAR),
+ KeyT::as_string,
+ ValueT::as_string,
+ TemplateString::FromChar(DBUS_DICT_ENTRY_END_CHAR));
};
using VariantTypeTraits = BasicTypeTraits<DBUS_TYPE_VARIANT>;
@@ -92,20 +95,25 @@ using VariantTypeTraits = BasicTypeTraits<DBUS_TYPE_VARIANT>;
* Concatenate all TypeAsString members to one string.
*/
template<typename T, typename... ContainedTraits>
-struct ConcatTypeAsString
- : TemplateString::Concat<typename T::TypeAsString,
- ConcatTypeAsString<ContainedTraits...>> {};
+struct ConcatTypeAsString {
+ static constexpr auto as_string =
+ TemplateString::Concat(T::as_string,
+ ConcatTypeAsString<ContainedTraits...>::as_string);
+};
template<typename T>
-struct ConcatTypeAsString<T> : T::TypeAsString {};
+struct ConcatTypeAsString<T> {
+ static constexpr auto as_string = T::as_string;
+};
template<typename... ContainedTraits>
struct StructTypeTraits {
static constexpr int TYPE = DBUS_TYPE_STRUCT;
- typedef TemplateString::Concat<TemplateString::CharAsString<DBUS_STRUCT_BEGIN_CHAR>,
- ConcatTypeAsString<ContainedTraits...>,
- TemplateString::CharAsString<DBUS_STRUCT_END_CHAR>> TypeAsString;
+ static constexpr auto as_string =
+ TemplateString::Concat(TemplateString::FromChar(DBUS_STRUCT_BEGIN_CHAR),
+ ConcatTypeAsString<ContainedTraits...>::as_string,
+ TemplateString::FromChar(DBUS_STRUCT_END_CHAR));
};
} /* namespace ODBus */
diff --git a/src/lib/dbus/UDisks2.cxx b/src/lib/dbus/UDisks2.cxx
index 0b1fefd94..90ecc3c68 100644
--- a/src/lib/dbus/UDisks2.cxx
+++ b/src/lib/dbus/UDisks2.cxx
@@ -120,19 +120,20 @@ static void
ParseInterface(Object &o, const char *interface,
ODBus::ReadMessageIter &&i) noexcept
{
- using namespace std::placeholders;
if (StringIsEqual(interface, "org.freedesktop.UDisks2.Drive")) {
- i.ForEachProperty(std::bind(ParseDriveDictEntry,
- std::ref(o), _1, _2));
+ i.ForEachProperty([&](auto n, auto v) {
+ return ParseDriveDictEntry(o, n, std::move(v));
+ });
} else if (StringIsEqual(interface, "org.freedesktop.UDisks2.Block")) {
- i.ForEachProperty(std::bind(ParseBlockDictEntry,
- std::ref(o), _1, _2));
+ i.ForEachProperty([&](auto n, auto v) {
+ return ParseBlockDictEntry(o, n, std::move(v));
+ });
} else if (StringIsEqual(interface, "org.freedesktop.UDisks2.Filesystem")) {
o.is_filesystem = true;
- i.ForEachProperty(std::bind(ParseFileesystemDictEntry,
- std::ref(o), _1, _2));
-
+ i.ForEachProperty([&](auto n, auto v) {
+ return ParseFileesystemDictEntry(o, n, std::move(v));
+ });
}
}
diff --git a/src/lib/dbus/Values.hxx b/src/lib/dbus/Values.hxx
index aac5b9dc4..013fa812e 100644
--- a/src/lib/dbus/Values.hxx
+++ b/src/lib/dbus/Values.hxx
@@ -44,7 +44,7 @@ namespace ODBus {
template<typename T>
struct BasicValue {
- typedef TypeTraits<T> Traits;
+ using Traits = TypeTraits<T>;
const T &value;
explicit constexpr BasicValue(const T &_value) noexcept
@@ -110,7 +110,7 @@ static WrapFixedArray<T> FixedArray(const T *_data,
template<typename... T>
struct WrapStruct {
- using Traits = StructTypeTraits<T...>;
+ using Traits = StructTypeTraits<typename T::Traits...>;
std::tuple<const T&...> values;
diff --git a/src/lib/dbus/Watch.cxx b/src/lib/dbus/Watch.cxx
index c3a0758ee..d8f6c796f 100644
--- a/src/lib/dbus/Watch.cxx
+++ b/src/lib/dbus/Watch.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2018 Content Management AG
+ * Copyright 2007-2020 CM4all GmbH
* All rights reserved.
*
* author: Max Kellermann <mk@cm4all.com>
@@ -38,8 +38,8 @@ namespace ODBus {
WatchManager::Watch::Watch(EventLoop &event_loop,
WatchManager &_parent, DBusWatch &_watch) noexcept
- :SocketMonitor(event_loop),
- parent(_parent), watch(_watch)
+ :parent(_parent), watch(_watch),
+ event(event_loop, BIND_THIS_METHOD(OnSocketReady))
{
Toggled();
}
@@ -47,30 +47,29 @@ WatchManager::Watch::Watch(EventLoop &event_loop,
static constexpr unsigned
DbusToLibevent(unsigned flags) noexcept
{
- return ((flags & DBUS_WATCH_READABLE) != 0) * SocketMonitor::READ |
- ((flags & DBUS_WATCH_WRITABLE) != 0) * SocketMonitor::WRITE;
+ return ((flags & DBUS_WATCH_READABLE) != 0) * SocketEvent::READ |
+ ((flags & DBUS_WATCH_WRITABLE) != 0) * SocketEvent::WRITE;
}
void
WatchManager::Watch::Toggled() noexcept
{
- if (SocketMonitor::IsDefined())
- SocketMonitor::Cancel();
+ event.Cancel();
if (dbus_watch_get_enabled(&watch)) {
- SocketMonitor::Open(SocketDescriptor(dbus_watch_get_unix_fd(&watch)));
- SocketMonitor::Schedule(DbusToLibevent(dbus_watch_get_flags(&watch)));
+ event.Open(SocketDescriptor(dbus_watch_get_unix_fd(&watch)));
+ event.Schedule(DbusToLibevent(dbus_watch_get_flags(&watch)));
}
}
static constexpr unsigned
LibeventToDbus(unsigned flags) noexcept
{
- return ((flags & SocketMonitor::READ) != 0) * DBUS_WATCH_READABLE |
- ((flags & SocketMonitor::WRITE) != 0) * DBUS_WATCH_WRITABLE;
+ return ((flags & SocketEvent::READ) != 0) * DBUS_WATCH_READABLE |
+ ((flags & SocketEvent::WRITE) != 0) * DBUS_WATCH_WRITABLE;
}
-bool
+void
WatchManager::Watch::OnSocketReady(unsigned events) noexcept
{
/* copy the "parent" reference to the stack, because the
@@ -81,7 +80,6 @@ WatchManager::Watch::OnSocketReady(unsigned events) noexcept
dbus_watch_handle(&watch, LibeventToDbus(events));
_parent.ScheduleDispatch();
- return true;
}
void
diff --git a/src/lib/dbus/Watch.hxx b/src/lib/dbus/Watch.hxx
index 351ce46f9..923f65aa3 100644
--- a/src/lib/dbus/Watch.hxx
+++ b/src/lib/dbus/Watch.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2018 Content Management AG
+ * Copyright 2007-2020 CM4all GmbH
* All rights reserved.
*
* author: Max Kellermann <mk@cm4all.com>
@@ -34,7 +34,7 @@
#define ODBUS_WATCH_HXX
#include "Connection.hxx"
-#include "event/SocketMonitor.hxx"
+#include "event/SocketEvent.hxx"
#include "event/DeferEvent.hxx"
#include <dbus/dbus.h>
@@ -58,9 +58,10 @@ class WatchManager {
Connection connection;
- class Watch final : SocketMonitor {
+ class Watch {
WatchManager &parent;
DBusWatch &watch;
+ SocketEvent event;
public:
Watch(EventLoop &event_loop, WatchManager &_parent,
@@ -69,7 +70,7 @@ class WatchManager {
void Toggled() noexcept;
private:
- bool OnSocketReady(unsigned flags) noexcept override;
+ void OnSocketReady(unsigned events) noexcept;
};
std::map<DBusWatch *, Watch> watches;
diff --git a/src/lib/nfs/Connection.cxx b/src/lib/nfs/Connection.cxx
index 933b67cc3..3ab6813c6 100644
--- a/src/lib/nfs/Connection.cxx
+++ b/src/lib/nfs/Connection.cxx
@@ -183,17 +183,17 @@ NfsConnection::CancellableCallback::Callback(int err,
static constexpr unsigned
libnfs_to_events(int i) noexcept
{
- return ((i & POLLIN) ? SocketMonitor::READ : 0) |
- ((i & POLLOUT) ? SocketMonitor::WRITE : 0);
+ return ((i & POLLIN) ? SocketEvent::READ : 0) |
+ ((i & POLLOUT) ? SocketEvent::WRITE : 0);
}
static constexpr int
events_to_libnfs(unsigned i) noexcept
{
- return ((i & SocketMonitor::READ) ? POLLIN : 0) |
- ((i & SocketMonitor::WRITE) ? POLLOUT : 0) |
- ((i & SocketMonitor::HANGUP) ? POLLHUP : 0) |
- ((i & SocketMonitor::ERROR) ? POLLERR : 0);
+ return ((i & SocketEvent::READ) ? POLLIN : 0) |
+ ((i & SocketEvent::WRITE) ? POLLOUT : 0) |
+ ((i & SocketEvent::HANGUP) ? POLLHUP : 0) |
+ ((i & SocketEvent::ERROR) ? POLLERR : 0);
}
NfsConnection::~NfsConnection() noexcept
@@ -403,8 +403,7 @@ NfsConnection::DestroyContext() noexcept
new leases */
defer_new_lease.Cancel();
- if (SocketMonitor::IsDefined())
- SocketMonitor::Steal();
+ socket_event.ReleaseSocket();
callbacks.ForEach([](CancellableCallback &c){
c.PrepareDestroyContext();
@@ -434,25 +433,25 @@ NfsConnection::ScheduleSocket() noexcept
const int which_events = nfs_which_events(context);
- if (which_events == POLLOUT && SocketMonitor::IsDefined())
+ if (which_events == POLLOUT)
/* kludge: if libnfs asks only for POLLOUT, it means
that it is currently waiting for the connect() to
finish - rpc_reconnect_requeue() may have been
called from inside nfs_service(); we must now
unregister the old socket and register the new one
instead */
- SocketMonitor::Steal();
+ socket_event.ReleaseSocket();
- if (!SocketMonitor::IsDefined()) {
+ if (!socket_event.IsDefined()) {
SocketDescriptor _fd(nfs_get_fd(context));
if (!_fd.IsDefined())
return;
_fd.EnableCloseOnExec();
- SocketMonitor::Open(_fd);
+ socket_event.Open(_fd);
}
- SocketMonitor::Schedule(libnfs_to_events(which_events));
+ socket_event.Schedule(libnfs_to_events(which_events));
}
inline int
@@ -480,16 +479,14 @@ NfsConnection::Service(unsigned flags) noexcept
return result;
}
-bool
+void
NfsConnection::OnSocketReady(unsigned flags) noexcept
{
assert(GetEventLoop().IsInside());
assert(deferred_close.empty());
- bool closed = false;
-
const bool was_mounted = mount_finished;
- if (!mount_finished || (flags & SocketMonitor::HANGUP) != 0)
+ if (!mount_finished || (flags & SocketEvent::HANGUP) != 0)
/* until the mount is finished, the NFS client may use
various sockets, therefore we unregister and
re-register it each time */
@@ -497,7 +494,7 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
which is a sure sign that libnfs will close the
socket, which can lead to a race condition if
epoll_ctl() is called later */
- SocketMonitor::Steal();
+ socket_event.ReleaseSocket();
const int result = Service(flags);
@@ -509,7 +506,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
if (!was_mounted && mount_finished) {
if (postponed_mount_error) {
DestroyContext();
- closed = true;
BroadcastMountError(std::move(postponed_mount_error));
} else if (result == 0)
BroadcastMountSuccess();
@@ -521,7 +517,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
BroadcastError(std::make_exception_ptr(e));
DestroyContext();
- closed = true;
} else if (nfs_get_fd(context) < 0) {
/* this happens when rpc_reconnect_requeue() is called
after the connection broke, but autoreconnect was
@@ -535,7 +530,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
BroadcastError(std::make_exception_ptr(e));
DestroyContext();
- closed = true;
}
assert(context == nullptr || nfs_get_fd(context) >= 0);
@@ -547,8 +541,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
if (context != nullptr)
ScheduleSocket();
-
- return !closed;
}
inline void
diff --git a/src/lib/nfs/Connection.hxx b/src/lib/nfs/Connection.hxx
index 394163c9f..e76a7096b 100644
--- a/src/lib/nfs/Connection.hxx
+++ b/src/lib/nfs/Connection.hxx
@@ -21,7 +21,7 @@
#define MPD_NFS_CONNECTION_HXX
#include "Cancellable.hxx"
-#include "event/SocketMonitor.hxx"
+#include "event/SocketEvent.hxx"
#include "event/TimerEvent.hxx"
#include "event/DeferEvent.hxx"
#include "util/Compiler.h"
@@ -40,7 +40,7 @@ class NfsLease;
/**
* An asynchronous connection to a NFS server.
*/
-class NfsConnection : SocketMonitor {
+class NfsConnection {
class CancellableCallback : public CancellablePointer<NfsCallback> {
NfsConnection &connection;
@@ -93,6 +93,7 @@ class NfsConnection : SocketMonitor {
void Callback(int err, void *data) noexcept;
};
+ SocketEvent socket_event;
DeferEvent defer_new_lease;
TimerEvent mount_timeout_event;
@@ -141,7 +142,7 @@ public:
gcc_nonnull_all
NfsConnection(EventLoop &_loop,
const char *_server, const char *_export_name) noexcept
- :SocketMonitor(_loop),
+ :socket_event(_loop, BIND_THIS_METHOD(OnSocketReady)),
defer_new_lease(_loop, BIND_THIS_METHOD(RunDeferred)),
mount_timeout_event(_loop, BIND_THIS_METHOD(OnMountTimeout)),
server(_server), export_name(_export_name),
@@ -152,6 +153,10 @@ public:
*/
~NfsConnection() noexcept;
+ auto &GetEventLoop() const noexcept {
+ return socket_event.GetEventLoop();
+ }
+
gcc_pure
const char *GetServer() const noexcept {
return server.c_str();
@@ -162,8 +167,6 @@ public:
return export_name.c_str();
}
- using SocketMonitor::GetEventLoop;
-
/**
* Ensure that the connection is established. The connection
* is kept up while at least one #NfsLease is registered.
@@ -231,8 +234,7 @@ private:
*/
int Service(unsigned flags) noexcept;
- /* virtual methods from SocketMonitor */
- bool OnSocketReady(unsigned flags) noexcept override;
+ void OnSocketReady(unsigned flags) noexcept;
/* callback for #mount_timeout_event */
void OnMountTimeout() noexcept;
diff --git a/src/lib/nfs/Manager.hxx b/src/lib/nfs/Manager.hxx
index 0eea913aa..95645f143 100644
--- a/src/lib/nfs/Manager.hxx
+++ b/src/lib/nfs/Manager.hxx
@@ -22,7 +22,7 @@
#include "Connection.hxx"
#include "util/Compiler.h"
-#include "event/IdleMonitor.hxx"
+#include "event/IdleEvent.hxx"
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/slist.hpp>
@@ -31,7 +31,7 @@
* A manager for NFS connections. Handles multiple connections to
* multiple NFS servers.
*/
-class NfsManager final : IdleMonitor {
+class NfsManager final {
struct LookupKey {
const char *server;
const char *export_name;
@@ -87,16 +87,20 @@ class NfsManager final : IdleMonitor {
*/
List garbage;
+ IdleEvent idle_event;
+
public:
explicit NfsManager(EventLoop &_loop) noexcept
- :IdleMonitor(_loop) {}
+ :idle_event(_loop, BIND_THIS_METHOD(OnIdle)) {}
/**
* Must be run from EventLoop's thread.
*/
~NfsManager() noexcept;
- using IdleMonitor::GetEventLoop;
+ auto &GetEventLoop() const noexcept {
+ return idle_event.GetEventLoop();
+ }
gcc_pure
NfsConnection &GetConnection(const char *server,
@@ -106,7 +110,7 @@ private:
void ScheduleDelete(ManagedConnection &c) noexcept {
connections.erase(connections.iterator_to(c));
garbage.push_front(c);
- IdleMonitor::Schedule();
+ idle_event.Schedule();
}
/**
@@ -115,7 +119,7 @@ private:
void CollectGarbage() noexcept;
/* virtual methods from IdleMonitor */
- void OnIdle() noexcept override;
+ void OnIdle() noexcept;
};
#endif