diff --git a/src/serverconn.cpp b/src/serverconn.cpp index fee0bfe..7a63a01 100644 --- a/src/serverconn.cpp +++ b/src/serverconn.cpp @@ -457,7 +457,12 @@ void ServIface::onConnS(struct evconnlistener *listener, evutil_socket_t sock, s } } -ServerOp::~ServerOp() {} +ServerOp::~ServerOp() +{ + // cleanup() should have happened already (from tcp worker) + // this check may run from any thread, but at this point it should not matter. + assert(state==Dead); +} /* reached from: * 1. connection close @@ -478,10 +483,8 @@ void ServerOp::cleanup() state = ServerOp::Dead; - decltype (onClose) closer; - if(onClose) { - closer = std::move(onClose); - } + onCancel = nullptr; + auto closer(std::move(onClose)); bool notify = closer.operator bool(); if(auto ch = chan.lock()) { diff --git a/src/serverconn.h b/src/serverconn.h index a068bb1..3b79e6a 100644 --- a/src/serverconn.h +++ b/src/serverconn.h @@ -51,7 +51,9 @@ struct ServerOp ServerOp& operator=(const ServerOp&) = delete; virtual ~ServerOp() =0; - void cleanup(); + // called from tcp worker. + // do any cleanup which must be done from that worker. + virtual void cleanup(); virtual void show(std::ostream& strm) const =0; }; diff --git a/src/serverget.cpp b/src/serverget.cpp index 2441b6b..4cf5a7c 100644 --- a/src/serverget.cpp +++ b/src/serverget.cpp @@ -27,7 +27,7 @@ cmd2op(pva_app_msg_t cmd){ } // generalized Get/Put/RPC -struct ServerGPR : public ServerOp +struct ServerGPR final : public ServerOp { ServerGPR(const std::shared_ptr& chan, uint32_t ioid) :ServerOp(chan, ioid) @@ -123,6 +123,13 @@ struct ServerGPR : public ServerOp } } + void cleanup() override final + { + ServerOp::cleanup(); + onPut = nullptr; + onGet = nullptr; + } + void show(std::ostream& strm) const override final { switch(cmd) { diff --git a/src/serverintrospect.cpp b/src/serverintrospect.cpp index 6379552..8e67151 100644 --- a/src/serverintrospect.cpp +++ b/src/serverintrospect.cpp @@ -14,7 +14,7 @@ namespace pvxs { namespace impl { DEFINE_LOGGER(connsetup, "pvxs.tcp.setup"); namespace { -struct ServerIntrospect : public ServerOp +struct ServerIntrospect final : public ServerOp { ServerIntrospect(const std::shared_ptr& chan, uint32_t ioid) :ServerOp(chan, ioid) diff --git a/src/servermon.cpp b/src/servermon.cpp index e61dbbc..57598bc 100644 --- a/src/servermon.cpp +++ b/src/servermon.cpp @@ -24,7 +24,7 @@ namespace { typedef epicsGuard Guard; -struct MonitorOp : public ServerOp +struct MonitorOp final : public ServerOp { MonitorOp(const std::shared_ptr& chan, uint32_t ioid) :ServerOp(chan, ioid) @@ -207,6 +207,15 @@ struct MonitorOp : public ServerOp } } + void cleanup() override final + { + ServerOp::cleanup(); // calls onCancel() + // release any bound variables + onHighMark = nullptr; + onLowMark = nullptr; + onStart = nullptr; + } + void show(std::ostream& strm) const override final { strm<<"MONITOR\n";