From b98265d732bad274f66de66cb93d891e9c41a112 Mon Sep 17 00:00:00 2001 From: Determinant Date: Thu, 12 Jul 2018 20:25:41 -0400 Subject: fix bugs --- include/salticidae/conn.h | 6 ++--- include/salticidae/network.h | 2 +- include/salticidae/ref.h | 60 ++++++++++++++++++++++++++++++++------------ include/salticidae/util.h | 40 ++++++++++------------------- src/conn.cpp | 8 +++--- 5 files changed, 65 insertions(+), 51 deletions(-) diff --git a/include/salticidae/conn.h b/include/salticidae/conn.h index 589bf16..c8ccf31 100644 --- a/include/salticidae/conn.h +++ b/include/salticidae/conn.h @@ -212,9 +212,9 @@ class ConnPool { protected: /** close the connection and free all on-going or planned events. */ virtual void close() { - ev_read.del(); - ev_write.del(); - ev_connect.del(); + ev_read.clear(); + ev_write.clear(); + ev_connect.clear(); ::close(fd); fd = -1; } diff --git a/include/salticidae/network.h b/include/salticidae/network.h index 1b20ce1..cede475 100644 --- a/include/salticidae/network.h +++ b/include/salticidae/network.h @@ -315,7 +315,7 @@ void PeerNetwork::Conn::on_teardown() { auto it = pn->id2peer.find(peer_id); if (it == pn->id2peer.end()) return; Peer *p = it->second; - if (this != p->conn) return; + if (this != p->conn.get()) return; p->ev_ping_timer.del(); p->connected = false; p->conn = nullptr; diff --git a/include/salticidae/ref.h b/include/salticidae/ref.h index a1c5dc7..c0b77a3 100644 --- a/include/salticidae/ref.h +++ b/include/salticidae/ref.h @@ -89,7 +89,17 @@ class _BoxObj { return *this; } - operator T*() const { return obj; } + T &operator *() const { return *obj; } + T *get() const { return obj; } + operator bool() const { return obj != nullptr; } + bool operator==(const _BoxObj &other) const { return obj == other.obj; } + bool operator!=(const _BoxObj &other) const { return obj != other.obj; } + bool operator==(std::nullptr_t) const { return obj == nullptr; } + bool operator!=(std::nullptr_t) const { return obj != nullptr; } + bool operator<(const _BoxObj &other) const { return obj < other.obj; } + bool operator>(const _BoxObj &other) const { return obj > other.obj; } + bool operator<=(const _BoxObj &other) const { return obj <= other.obj; } + bool operator>=(const _BoxObj &other) const { return obj >= other.obj; } }; template> @@ -102,7 +112,7 @@ class BoxObj: public _BoxObj { BoxObj() = default; BoxObj(T *obj): base_t(obj) {} template::value>::value> + typename std::enable_if::value>::type> BoxObj(BoxObj &&other): base_t(other) {} T *operator->() const { return base_t::obj; } @@ -175,6 +185,7 @@ struct _ARCCtl { ~_ARCCtl() {} }; +template class _RcObjBase; template class RcObjBase; template @@ -182,9 +193,8 @@ class _WeakObjBase { T *obj; R *ctl; - template using ROB = RcObjBase; - friend class ROB; - friend std::hash<_WeakObjBase>; + template + friend class _RcObjBase; public: _WeakObjBase(): ctl(nullptr) {} @@ -223,7 +233,7 @@ class _WeakObjBase { } template - _WeakObjBase(const RcObjBase &other); + _WeakObjBase(const _RcObjBase &other); ~_WeakObjBase() { if (ctl) ctl->release_weak(); } }; @@ -231,22 +241,30 @@ class _WeakObjBase { template class WeakObjBase: public _WeakObjBase { + using base_t = _WeakObjBase; + friend std::hash; public: WeakObjBase() = default; WeakObjBase(const WeakObjBase &other) = default; WeakObjBase(WeakObjBase &&other) = default; template - WeakObjBase(const RcObjBase &other); + WeakObjBase(const RcObjBase &other): base_t(other) {} + WeakObjBase &operator=(const WeakObjBase &) = default; + WeakObjBase &operator=(WeakObjBase &&) = default; }; template class WeakObjBase: public _WeakObjBase { + using base_t = _WeakObjBase; + friend std::hash; public: WeakObjBase() = default; WeakObjBase(const WeakObjBase &other) = default; WeakObjBase(WeakObjBase &&other) = default; template - WeakObjBase(const RcObjBase &other); + WeakObjBase(const RcObjBase &other): base_t(other) {} + WeakObjBase &operator=(const WeakObjBase &) = default; + WeakObjBase &operator=(WeakObjBase &&) = default; }; @@ -257,13 +275,11 @@ class _RcObjBase { ptr_type obj; R *ctl; - friend WeakObjBase; - friend std::hash<_RcObjBase>; + friend _WeakObjBase; template friend class _RcObjBase; public: - operator T*() const { return obj; } _RcObjBase(): obj(nullptr), ctl(nullptr) {} _RcObjBase(ptr_type obj): obj(obj), ctl(new R()) {} _RcObjBase(BoxObj &&box_ref): obj(box_ref.obj), ctl(new R()) { @@ -315,7 +331,7 @@ class _RcObjBase { other.ctl = nullptr; } - _RcObjBase(const WeakObjBase &other) { + _RcObjBase(const _WeakObjBase &other) { if (other.ctl && other.ctl->ref_cnt) { obj = other.obj; @@ -335,11 +351,23 @@ class _RcObjBase { } size_t get_cnt() const { return ctl ? ctl->get_cnt() : 0; } + T &operator *() const { return *obj; } + T *get() const { return obj; } + operator bool() const { return obj != nullptr; } + bool operator==(const _RcObjBase &other) const { return obj == other.obj; } + bool operator!=(const _RcObjBase &other) const { return obj != other.obj; } + bool operator==(std::nullptr_t) const { return obj == nullptr; } + bool operator!=(std::nullptr_t) const { return obj != nullptr; } + bool operator<(const _RcObjBase &other) const { return obj < other.obj; } + bool operator>(const _RcObjBase &other) const { return obj > other.obj; } + bool operator<=(const _RcObjBase &other) const { return obj <= other.obj; } + bool operator>=(const _RcObjBase &other) const { return obj >= other.obj; } }; template> class RcObjBase: public _RcObjBase { using base_t = _RcObjBase; + friend std::hash; template friend RcObjBase static_pointer_cast(const RcObjBase &other); template @@ -352,16 +380,15 @@ class RcObjBase: public _RcObjBase { RcObjBase(BoxObj &&box_ref): base_t(std::move(box_ref)) {} template::value>::value> + typename = typename std::enable_if::value>::type> RcObjBase(const RcObjBase &other): base_t(other) {} template::value>::value> + typename = typename std::enable_if::value>::type> RcObjBase(RcObjBase &&other): base_t(std::move(other)) {} RcObjBase(const WeakObjBase &other): base_t(other) {} - RcObjBase(const RcObjBase &other) = default; RcObjBase(RcObjBase &&other) = default; RcObjBase &operator=(const RcObjBase &) = default; @@ -371,6 +398,7 @@ class RcObjBase: public _RcObjBase { template class RcObjBase: public _RcObjBase { using base_t = _RcObjBase; + friend std::hash; template friend RcObjBase static_pointer_cast(const RcObjBase &other); template @@ -419,7 +447,7 @@ RcObjBase static_pointer_cast(RcObjBase &&other) { template template -inline _WeakObjBase::_WeakObjBase(const RcObjBase &other): +inline _WeakObjBase::_WeakObjBase(const _RcObjBase &other): obj(other.obj), ctl(other.ctl) { if (ctl) ctl->add_weak(); } diff --git a/include/salticidae/util.h b/include/salticidae/util.h index 0324215..de63146 100644 --- a/include/salticidae/util.h +++ b/include/salticidae/util.h @@ -271,47 +271,33 @@ class Event { eb(eb), fd(fd), events(events), ev(event_new(eb, fd, events, Event::_then, this)), callback(callback) {} - Event(const Event &other): - eb(other.eb), fd(other.fd), events(other.events), - ev(event_new(eb, fd, events, Event::_then, this)), - callback(other.callback) {} Event(Event &&other): eb(other.eb), fd(other.fd), events(other.events), - ev(event_new(eb, fd, events, Event::_then, this)), - callback(std::move(other.callback)) {} - - void swap(Event &other) { - std::swap(eb, other.eb); - std::swap(fd, other.fd); - std::swap(events, other.events); - std::swap(ev, other.ev); - std::swap(callback, other.callback); + callback(std::move(other.callback)) { + other.clear(); + ev = event_new(eb, fd, events, Event::_then, this); } Event &operator=(Event &&other) { - if (this != &other) - { - Event tmp(std::move(other)); - tmp.swap(*this); - } + clear(); + other.clear(); + eb = other.eb; + fd = other.fd; + events = other.events; + ev = event_new(eb, fd, events, Event::_then, this); + callback = std::move(other.callback); return *this; } - Event &operator=(const Event &other) { - if (this != &other) - { - Event tmp(other); - tmp.swap(*this); - } - return *this; - } + ~Event() { clear(); } - ~Event() { + void clear() { if (ev != nullptr) { event_del(ev); event_free(ev); + ev = nullptr; } } diff --git a/src/conn.cpp b/src/conn.cpp index 2bcd0ae..0b42853 100644 --- a/src/conn.cpp +++ b/src/conn.cpp @@ -136,7 +136,7 @@ void ConnPool::accept_client(evutil_socket_t fd, short) { NetAddr addr((struct sockaddr_in *)&client_addr); conn_t conn = create_conn(); - Conn *conn_ptr = conn; + Conn *conn_ptr = conn.get(); conn->fd = client_fd; conn->cpool = this; conn->mode = Conn::PASSIVE; @@ -165,7 +165,7 @@ void ConnPool::Conn::conn_server(evutil_socket_t fd, short events) { std::bind(&Conn::send_data, this, _1, _2)); ev_read.add(); ev_write.add(); - ev_connect.del(); + ev_connect.clear(); ready_send = false; SALTICIDAE_LOG_INFO("connected to peer %s", std::string(*this).c_str()); on_setup(); @@ -212,7 +212,7 @@ void ConnPool::Conn::terminate() { { /* temporarily pin the conn before it dies */ auto conn = it->second; - assert(conn == this); + assert(conn.get() == this); pool.erase(it); close(); /* inform the upper layer the connection will be destroyed */ @@ -252,7 +252,7 @@ ConnPool::conn_t ConnPool::create_conn(const NetAddr &addr) { if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) throw ConnPoolError(std::string("unable to set nonblocking socket")); conn_t conn = create_conn(); - Conn * conn_ptr = conn; + Conn * conn_ptr = conn.get(); conn->fd = fd; conn->cpool = this; conn->mode = Conn::ACTIVE; -- cgit v1.2.3