server: rework cleanup of connection, channel, and operation

This commit is contained in:
Michael Davidsaver
2023-02-21 11:57:25 -08:00
parent 9c546f0ed4
commit fedbec649b
5 changed files with 104 additions and 95 deletions
+57 -13
View File
@@ -280,10 +280,7 @@ void ServerConn::handle_DESTROY_REQUEST()
if(it!=opByIOID.end()) {
auto op = it->second;
opByIOID.erase(it);
op->state = ServerOp::Dead;
if(op->onClose)
op->onClose("");
op->cleanup();
}
}
@@ -326,22 +323,25 @@ std::shared_ptr<ConnBase> ServerConn::self_from_this()
return shared_from_this();
}
// see also ServerChannel_shutdown()
/* reached from:
* 1. connection close
*/
void ServerConn::cleanup()
{
log_debug_printf(connsetup, "Client %s Cleanup TCP Connection\n", peerName.c_str());
iface->server->connections.erase(this);
for(auto& pair : opByIOID) {
if(pair.second->onClose)
pair.second->onClose("");
// grab maps before cleanup()s would modify
auto ops(std::move(opByIOID));
auto chans(std::move(chanBySID));
for(auto& op : ops) {
op.second->cleanup();
}
for(auto& pair : chanBySID) {
pair.second->state = ServerChan::Destroy;
if(pair.second->onClose) {
auto fn(std::move(pair.second->onClose));
fn("");
}
for(auto& pair : chans) {
pair.second->cleanup();
}
}
@@ -449,4 +449,48 @@ void ServIface::onConnS(struct evconnlistener *listener, evutil_socket_t sock, s
ServerOp::~ServerOp() {}
/* reached from:
* 1. connection close
* 2. DESTROY_CHANNEL
* 3. DESTROY_REQUEST
* 4. individual op DESTROY
* 5. local user calls ServerChannelControl::close()
*/
void ServerOp::cleanup()
{
if(state==ServerOp::Dead)
return;
if(state==ServerOp::Executing && onCancel) {
auto fn(std::move(onCancel));
fn();
}
state = ServerOp::Dead;
decltype (onClose) closer;
if(onClose) {
closer = std::move(onClose);
}
bool notify = closer.operator bool();
if(auto ch = chan.lock()) {
ch->opByIOID.erase(ioid);
if(auto conn = ch->conn.lock()) {
conn->opByIOID.erase(ioid);
if(notify) {
conn->iface->server->acceptor_loop.dispatch([closer](){
closer("");
});
notify = false;
}
}
}
if(notify)
closer("");
}
}} // namespace pvxs::impl