diff --git a/client.cpp b/client.cpp index bcacb79..bc60b56 100644 --- a/client.cpp +++ b/client.cpp @@ -21,17 +21,18 @@ Client::~Client() { Logger *logger = Logger::getInstance(); logger->logf(LOG_NOTICE, "Removing client '%s'", repr().c_str()); + if (epoll_ctl(threadData->epollfd, EPOLL_CTL_DEL, fd, NULL) != 0) + logger->logf(LOG_ERR, "Removing fd %d of client '%s' from epoll produced error: %s", fd, repr().c_str(), strerror(errno)); close(fd); } -// Do this from a place you'll know ownwership of the shared_ptr is being given up everywhere, so the close happens when the last owner gives it up. +// Causes future activity on the client to cause a disconnect. void Client::markAsDisconnecting() { if (disconnecting) return; disconnecting = true; - check(epoll_ctl(threadData->epollfd, EPOLL_CTL_DEL, fd, NULL)); } // false means any kind of error we want to get rid of the client for. diff --git a/mqttpacket.cpp b/mqttpacket.cpp index a3bc0c9..afaaff3 100644 --- a/mqttpacket.cpp +++ b/mqttpacket.cpp @@ -110,6 +110,8 @@ void MqttPacket::handle() if (packetType == PacketType::CONNECT) handleConnect(); + else if (packetType == PacketType::DISCONNECT) + handleDisconnect(); else if (packetType == PacketType::PINGREQ) sender->writePingResp(); else if (packetType == PacketType::SUBSCRIBE) @@ -247,6 +249,15 @@ void MqttPacket::handleConnect() } } +void MqttPacket::handleDisconnect() +{ + logger->logf(LOG_NOTICE, "Client '%s' cleanly disconnecting", sender->repr().c_str()); + sender->markAsDisconnecting(); + sender->getThreadData()->removeClient(sender); + + // TODO: clear will +} + void MqttPacket::handleSubscribe() { uint16_t packet_id = readTwoBytesToUInt16(); diff --git a/mqttpacket.h b/mqttpacket.h index f2092d7..af00b55 100644 --- a/mqttpacket.h +++ b/mqttpacket.h @@ -57,6 +57,7 @@ public: void handle(); void handleConnect(); + void handleDisconnect(); void handleSubscribe(); void handlePing(); void handlePublish();