diff --git a/Transmission.xcodeproj/project.pbxproj b/Transmission.xcodeproj/project.pbxproj index c6bee06e5..645306395 100644 --- a/Transmission.xcodeproj/project.pbxproj +++ b/Transmission.xcodeproj/project.pbxproj @@ -286,6 +286,7 @@ BE1183700CE160D50002D0F3 /* miniupnpc.c in Sources */ = {isa = PBXBuildFile; fileRef = BE1183680CE160D50002D0F3 /* miniupnpc.c */; }; BE1183780CE161390002D0F3 /* libminiupnp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE1183480CE160960002D0F3 /* libminiupnp.a */; }; BE75C38A0C72A1ED00DBEFE0 /* libevent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE75C3490C729E9500DBEFE0 /* libevent.a */; }; + BE7AA337F6752914B0C416B0 /* utils-ev.h in Headers */ = {isa = PBXBuildFile; fileRef = BE7AA337F6752914B0C416B1 /* utils-ev.h */; }; BEFC1C050C07753500B0BB3C /* libtransmission.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D18389709DEC0030047D688 /* libtransmission.a */; }; BEFC1C1A0C07756200B0BB3C /* daemon.cc in Sources */ = {isa = PBXBuildFile; fileRef = BEFC1C0E0C07756200B0BB3C /* daemon.cc */; }; BEFC1D050C07825A00B0BB3C /* remote.cc in Sources */ = {isa = PBXBuildFile; fileRef = BEFC1C140C07756200B0BB3C /* remote.cc */; }; @@ -1061,6 +1062,7 @@ BE1183670CE160D50002D0F3 /* upnpcommands.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = upnpcommands.c; sourceTree = ""; }; BE1183680CE160D50002D0F3 /* miniupnpc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = miniupnpc.c; sourceTree = ""; }; BE75C3490C729E9500DBEFE0 /* libevent.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libevent.a; sourceTree = BUILT_PRODUCTS_DIR; }; + BE7AA337F6752914B0C416B1 /* utils-ev.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utils-ev.h; sourceTree = ""; }; BEFC1C000C07750000B0BB3C /* transmission-daemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "transmission-daemon"; sourceTree = BUILT_PRODUCTS_DIR; }; BEFC1C0E0C07756200B0BB3C /* daemon.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = daemon.cc; sourceTree = ""; }; BEFC1C140C07756200B0BB3C /* remote.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = remote.cc; sourceTree = ""; }; @@ -1732,6 +1734,7 @@ BEFC1DF50C07861A00B0BB3C /* transmission.h */, A24621360C769CF400088E81 /* session-thread.cc */, A24621350C769CF400088E81 /* session-thread.h */, + BE7AA337F6752914B0C416B1 /* utils-ev.h */, BEFC1DF40C07861A00B0BB3C /* port-forwarding-upnp.cc */, BEFC1DF30C07861A00B0BB3C /* port-forwarding-upnp.h */, BEFC1DF20C07861A00B0BB3C /* utils.cc */, @@ -2157,6 +2160,7 @@ C1077A51183EB29600634C22 /* file.h in Headers */, BEFC1E290C07861A00B0BB3C /* version.h in Headers */, BEFC1E2A0C07861A00B0BB3C /* utils.h in Headers */, + BE7AA337F6752914B0C416B0 /* utils-ev.h in Headers */, BEFC1E2C0C07861A00B0BB3C /* port-forwarding-upnp.h in Headers */, A2AAB65D0DE0CF6200E04DDA /* rpcimpl.h in Headers */, A2AAB65E0DE0CF6200E04DDA /* rpc-server.h in Headers */, diff --git a/libtransmission/CMakeLists.txt b/libtransmission/CMakeLists.txt index 8c6980418..ddaffc2b2 100644 --- a/libtransmission/CMakeLists.txt +++ b/libtransmission/CMakeLists.txt @@ -209,6 +209,7 @@ set(${PROJECT_NAME}_PRIVATE_HEADERS tr-dht.h tr-lpd.h tr-utp.h + utils-ev.h variant-common.h verify.h version.h diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 5ff87ac5a..5c794b1fb 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -502,8 +502,8 @@ std::shared_ptr tr_peerIo::create( { case TR_PEER_SOCKET_TYPE_TCP: tr_logAddTraceIo(io, fmt::format("socket (tcp) is {}", socket.handle.tcp)); - io->event_read = event_new(session->eventBase(), socket.handle.tcp, EV_READ, event_read_cb, io.get()); - io->event_write = event_new(session->eventBase(), socket.handle.tcp, EV_WRITE, event_write_cb, io.get()); + io->event_read.reset(event_new(session->eventBase(), socket.handle.tcp, EV_READ, event_read_cb, io.get())); + io->event_write.reset(event_new(session->eventBase(), socket.handle.tcp, EV_WRITE, event_write_cb, io.get())); break; #ifdef WITH_UTP @@ -597,12 +597,8 @@ static void event_enable(tr_peerIo* io, short event) TR_ASSERT(io->session != nullptr); bool const need_events = io->socket.type == TR_PEER_SOCKET_TYPE_TCP; - - if (need_events) - { - TR_ASSERT(event_initialized(io->event_read)); - TR_ASSERT(event_initialized(io->event_write)); - } + TR_ASSERT(!need_events || io->event_read); + TR_ASSERT(!need_events || io->event_write); if ((event & EV_READ) != 0 && (io->pendingEvents & EV_READ) == 0) { @@ -610,7 +606,7 @@ static void event_enable(tr_peerIo* io, short event) if (need_events) { - event_add(io->event_read, nullptr); + event_add(io->event_read.get(), nullptr); } io->pendingEvents |= EV_READ; @@ -622,7 +618,7 @@ static void event_enable(tr_peerIo* io, short event) if (need_events) { - event_add(io->event_write, nullptr); + event_add(io->event_write.get(), nullptr); } io->pendingEvents |= EV_WRITE; @@ -632,12 +628,8 @@ static void event_enable(tr_peerIo* io, short event) static void event_disable(tr_peerIo* io, short event) { bool const need_events = io->socket.type == TR_PEER_SOCKET_TYPE_TCP; - - if (need_events) - { - TR_ASSERT(event_initialized(io->event_read)); - TR_ASSERT(event_initialized(io->event_write)); - } + TR_ASSERT(!need_events || io->event_read); + TR_ASSERT(!need_events || io->event_write); if ((event & EV_READ) != 0 && (io->pendingEvents & EV_READ) != 0) { @@ -645,7 +637,7 @@ static void event_disable(tr_peerIo* io, short event) if (need_events) { - event_del(io->event_read); + event_del(io->event_read.get()); } io->pendingEvents &= ~EV_READ; @@ -657,7 +649,7 @@ static void event_disable(tr_peerIo* io, short event) if (need_events) { - event_del(io->event_write); + event_del(io->event_write.get()); } io->pendingEvents &= ~EV_WRITE; @@ -708,19 +700,9 @@ static void io_close_socket(tr_peerIo* io) tr_logAddDebugIo(io, fmt::format("unsupported peer socket type {}", io->socket.type)); } + io->event_write.reset(); + io->event_read.reset(); io->socket = {}; - - if (io->event_read != nullptr) - { - event_free(io->event_read); - io->event_read = nullptr; - } - - if (io->event_write != nullptr) - { - event_free(io->event_write); - io->event_write = nullptr; - } } tr_peerIo::~tr_peerIo() @@ -773,8 +755,8 @@ int tr_peerIo::reconnect() return -1; } - this->event_read = event_new(session->eventBase(), this->socket.handle.tcp, EV_READ, event_read_cb, this); - this->event_write = event_new(session->eventBase(), this->socket.handle.tcp, EV_WRITE, event_write_cb, this); + this->event_read.reset(event_new(session->eventBase(), this->socket.handle.tcp, EV_READ, event_read_cb, this)); + this->event_write.reset(event_new(session->eventBase(), this->socket.handle.tcp, EV_WRITE, event_write_cb, this)); event_enable(this, pending_events); this->session->setSocketTOS(this->socket.handle.tcp, addr.type); diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index 0efbe7bd4..be9be9bcf 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -22,8 +22,6 @@ #include #include // std::make_pair -#include - #include "transmission.h" #include "bandwidth.h" @@ -32,6 +30,7 @@ #include "peer-socket.h" #include "tr-assert.h" #include "tr-buffer.h" +#include "utils-ev.h" class tr_peerIo; struct tr_bandwidth; @@ -51,16 +50,6 @@ enum ReadState auto inline constexpr PEER_IO_MAGIC_NUMBER = 206745; -struct evbuffer_deleter -{ - void operator()(struct evbuffer* buf) const noexcept - { - evbuffer_free(buf); - } -}; - -using tr_evbuffer_ptr = std::unique_ptr; - namespace libtransmission::test { @@ -255,8 +244,8 @@ public: std::deque> outbuf_info; - struct event* event_read = nullptr; - struct event* event_write = nullptr; + libtransmission::evhelpers::event_unique_ptr event_read; + libtransmission::evhelpers::event_unique_ptr event_write; short int pendingEvents = 0; diff --git a/libtransmission/session-thread.cc b/libtransmission/session-thread.cc index cb72edf0d..2b0bba8e2 100644 --- a/libtransmission/session-thread.cc +++ b/libtransmission/session-thread.cc @@ -27,6 +27,7 @@ #include "session-thread.h" #include "tr-assert.h" #include "utils.h" // for tr_net_init() +#include "utils-ev.h" using namespace std::literals; @@ -135,7 +136,7 @@ auto makeEventBase() { tr_session_thread::tr_evthread_init(); - return std::unique_ptr{ event_base_new(), event_base_free }; + return libtransmission::evhelpers::evbase_unique_ptr{ event_base_new() }; } } // namespace @@ -153,7 +154,7 @@ class tr_session_thread_impl final : public tr_session_thread public: explicit tr_session_thread_impl() : evbase_{ makeEventBase() } - , work_queue_event_{ event_new(evbase_.get(), -1, 0, onWorkAvailableStatic, this), event_free } + , work_queue_event_{ event_new(evbase_.get(), -1, 0, onWorkAvailableStatic, this) } { auto lock = std::unique_lock(is_looping_mutex_); @@ -273,8 +274,8 @@ private: } } - std::unique_ptr const evbase_; - std::unique_ptr const work_queue_event_; + libtransmission::evhelpers::evbase_unique_ptr const evbase_; + libtransmission::evhelpers::event_unique_ptr work_queue_event_; work_queue_t work_queue_; std::mutex work_queue_mutex_; diff --git a/libtransmission/session.cc b/libtransmission/session.cc index 7096528bb..e15dd1aa5 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -276,6 +276,7 @@ tr_session::BoundSocket::BoundSocket( : cb_{ cb } , cb_data_{ cb_data } , socket_{ tr_netBindTCP(addr, port, false) } + , ev_{ event_new(evbase, socket_, EV_READ | EV_PERSIST, &BoundSocket::onCanRead, this) } { if (socket_ == TR_BAD_SOCKET) { @@ -284,27 +285,12 @@ tr_session::BoundSocket::BoundSocket( tr_logAddInfo( fmt::format(_("Listening to incoming peer connections on {hostport}"), fmt::arg("hostport", addr.readable(port)))); - - ev_ = event_new( - evbase, - socket_, - EV_READ | EV_PERSIST, - [](evutil_socket_t fd, short /*evtype*/, void* vself) - { - auto* const self = static_cast(vself); - self->cb_(fd, self->cb_data_); - }, - this); - event_add(ev_, nullptr); + event_add(ev_.get(), nullptr); } tr_session::BoundSocket::~BoundSocket() { - if (ev_ != nullptr) - { - event_free(ev_); - ev_ = nullptr; - } + ev_.reset(); if (socket_ != TR_BAD_SOCKET) { diff --git a/libtransmission/session.h b/libtransmission/session.h index 9656189de..1c34d0414 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -42,6 +42,7 @@ #include "stats.h" #include "torrents.h" #include "tr-lpd.h" +#include "utils-ev.h" #include "verify.h" #include "web.h" @@ -89,10 +90,16 @@ private: ~BoundSocket(); private: + static void onCanRead(evutil_socket_t fd, short /*what*/, void* vself) + { + auto* const self = static_cast(vself); + self->cb_(fd, self->cb_data_); + } + IncomingCallback cb_; void* cb_data_; tr_socket_t socket_ = TR_BAD_SOCKET; - struct event* ev_ = nullptr; + libtransmission::evhelpers::event_unique_ptr ev_; }; class AltSpeedMediator final : public tr_session_alt_speeds::Mediator @@ -254,11 +261,11 @@ private: private: tr_port const udp_port_; tr_session& session_; - struct event* udp_event_ = nullptr; - struct event* udp6_event_ = nullptr; - std::optional udp6_bound_; tr_socket_t udp_socket_ = TR_BAD_SOCKET; tr_socket_t udp6_socket_ = TR_BAD_SOCKET; + libtransmission::evhelpers::event_unique_ptr udp4_event_; + libtransmission::evhelpers::event_unique_ptr udp6_event_; + std::optional udp6_bound_; void rebind_ipv6(bool); }; diff --git a/libtransmission/timer-ev.cc b/libtransmission/timer-ev.cc index 94be5b2b9..98d047a19 100644 --- a/libtransmission/timer-ev.cc +++ b/libtransmission/timer-ev.cc @@ -9,28 +9,12 @@ #include -#include "tr-assert.h" #include "timer-ev.h" +#include "tr-assert.h" +#include "utils-ev.h" using namespace std::literals; -namespace -{ - -struct EventDeleter -{ - void operator()(struct event* event) - { - if (event != nullptr) - { - event_del(event); - event_free(event); - } - } -}; - -} // namespace - namespace libtransmission { @@ -118,7 +102,7 @@ private: } struct event_base* const base_; - std::unique_ptr evtimer_; + evhelpers::event_unique_ptr evtimer_; std::function callback_; std::chrono::milliseconds interval_ = 100ms; diff --git a/libtransmission/tr-buffer.h b/libtransmission/tr-buffer.h index d6ecf147c..5e158ae32 100644 --- a/libtransmission/tr-buffer.h +++ b/libtransmission/tr-buffer.h @@ -16,6 +16,7 @@ #include "error.h" #include "net.h" // tr_socket_t +#include "utils-ev.h" #include "utils.h" namespace libtransmission @@ -359,7 +360,7 @@ public: } private: - std::unique_ptr buf_{ evbuffer_new(), evbuffer_free }; + evhelpers::evbuffer_unique_ptr buf_{ evbuffer_new() }; }; } // namespace libtransmission diff --git a/libtransmission/tr-lpd.cc b/libtransmission/tr-lpd.cc index 3fa1e28e2..28f28e870 100644 --- a/libtransmission/tr-lpd.cc +++ b/libtransmission/tr-lpd.cc @@ -18,7 +18,6 @@ #include /* sockaddr_in */ #endif -#include #include #include @@ -32,6 +31,7 @@ #include "tr-assert.h" #include "tr-lpd.h" #include "utils.h" // for tr_net_init() +#include "utils-ev.h" // for tr_net_init() using namespace std::literals; @@ -227,10 +227,7 @@ public: ~tr_lpd_impl() override { - if (event_ != nullptr) - { - event_free(event_); - } + event_.reset(); if (mcast_rcv_socket_ != TR_BAD_SOCKET) { @@ -382,8 +379,8 @@ private: /* Note: lpd_unsolicitedMsgCounter remains 0 until the first timeout event, thus * any announcement received during the initial interval will be discarded. */ - event_ = event_new(event_base, mcast_rcv_socket_, EV_READ | EV_PERSIST, event_callback, this); - event_add(event_, nullptr); + event_.reset(event_new(event_base, mcast_rcv_socket_, EV_READ | EV_PERSIST, event_callback, this)); + event_add(event_.get(), nullptr); tr_logAddDebug("Local Peer Discovery initialised"); @@ -571,7 +568,7 @@ private: Mediator& mediator_; tr_socket_t mcast_rcv_socket_ = TR_BAD_SOCKET; /** + +#include +#include + +namespace libtransmission::evhelpers +{ + +struct BufferDeleter +{ + void operator()(struct evbuffer* buf) const noexcept + { + if (buf != nullptr) + { + evbuffer_free(buf); + } + } +}; + +using evbuffer_unique_ptr = std::unique_ptr; + +struct EventBaseDeleter +{ + void operator()(struct event_base* evbase) const noexcept + { + if (evbase != nullptr) + { + event_base_free(evbase); + } + } +}; + +using evbase_unique_ptr = std::unique_ptr; + +struct EventDeleter +{ + void operator()(struct event* event) + { + if (event != nullptr) + { + event_del(event); + event_free(event); + } + } +}; + +using event_unique_ptr = std::unique_ptr; + +} // namespace libtransmission::evhelpers diff --git a/libtransmission/watchdir-kqueue.cc b/libtransmission/watchdir-kqueue.cc index 5200e8647..af06ade3e 100644 --- a/libtransmission/watchdir-kqueue.cc +++ b/libtransmission/watchdir-kqueue.cc @@ -28,6 +28,7 @@ #include "log.h" #include "tr-strbuf.h" #include "utils.h" // for _() +#include "utils-ev.h" #include "watchdir-base.h" namespace libtransmission @@ -51,11 +52,7 @@ public: ~KQueueWatchdir() override { - if (event_ != nullptr) - { - event_del(event_); - event_free(event_); - } + event_.reset(); if (kq_ != -1) { @@ -112,8 +109,8 @@ private: } // create libevent task for event descriptor - event_ = event_new(evbase, kq_, EV_READ | EV_ET | EV_PERSIST, &onKqueueEvent, this); - if (event_ == nullptr) + event_.reset(event_new(evbase, kq_, EV_READ | EV_ET | EV_PERSIST, &onKqueueEvent, this)); + if (!event_) { auto const error_code = errno; tr_logAddError(fmt::format( @@ -123,7 +120,7 @@ private: return; } - if (event_add(event_, nullptr) == -1) + if (event_add(event_.get(), nullptr) == -1) { auto const error_code = errno; tr_logAddError(fmt::format( @@ -158,7 +155,7 @@ private: int kq_ = -1; int dirfd_ = -1; - struct event* event_ = nullptr; + libtransmission::evhelpers::event_unique_ptr event_; }; } // namespace diff --git a/libtransmission/web.cc b/libtransmission/web.cc index 8c14f0905..8eea04d7b 100644 --- a/libtransmission/web.cc +++ b/libtransmission/web.cc @@ -21,8 +21,6 @@ #include -#include - #include #include @@ -30,6 +28,7 @@ #include "log.h" #include "peer-io.h" #include "tr-assert.h" +#include "utils-ev.h" #include "utils.h" #include "web.h" @@ -180,7 +179,7 @@ public: class Task { private: - tr_evbuffer_ptr const privbuf = tr_evbuffer_ptr{ evbuffer_new() }; + libtransmission::evhelpers::evbuffer_unique_ptr privbuf{ evbuffer_new() }; std::unique_ptr const easy_handle{ curl_easy_init(), curl_easy_cleanup }; tr_web::FetchOptions options; diff --git a/libtransmission/webseed.cc b/libtransmission/webseed.cc index e1aae1951..86703f9f2 100644 --- a/libtransmission/webseed.cc +++ b/libtransmission/webseed.cc @@ -13,8 +13,6 @@ #include #include -#include - #include #include "transmission.h" @@ -25,6 +23,7 @@ #include "peer-mgr.h" #include "timer.h" #include "torrent.h" +#include "utils-ev.h" #include "utils.h" #include "web-utils.h" #include "web.h" @@ -42,7 +41,7 @@ void on_idle(tr_webseed* w); class tr_webseed_task { private: - tr_evbuffer_ptr const content_{ evbuffer_new() }; + libtransmission::evhelpers::evbuffer_unique_ptr const content_{ evbuffer_new() }; public: tr_webseed_task(tr_torrent* tor, tr_webseed* webseed_in, tr_block_span_t blocks_in) @@ -328,7 +327,7 @@ private: struct write_block_data { private: - tr_evbuffer_ptr const content_{ evbuffer_new() }; + libtransmission::evhelpers::evbuffer_unique_ptr const content_{ evbuffer_new() }; public: write_block_data(