From 97fc3605ce07b9528e6eca8001c3ed3b353b3713 Mon Sep 17 00:00:00 2001 From: Benedikt Galbavy Date: Tue, 14 Nov 2023 22:53:50 +0100 Subject: [PATCH] multithreading has memory leaks --- server/mail.cpp | 2 +- server/server.cpp | 40 ++++++++++++++++++++-------------------- server/user.cpp | 5 ++--- server/user_handler.cpp | 5 +++++ server/user_handler.h | 22 ++++++++++------------ 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/server/mail.cpp b/server/mail.cpp index c9e8e49..4921a4c 100644 --- a/server/mail.cpp +++ b/server/mail.cpp @@ -26,7 +26,7 @@ void mail::remove() { if (this->filename.empty()) return; - std::remove((user_handler::getInstance()->getSpoolDir()/"objects"/fs::path(this->filename.insert(2, "/"))).c_str()); + std::remove((user_handler::getInstance().getSpoolDir()/"objects"/fs::path(this->filename.insert(2, "/"))).c_str()); this->filename = ""; } diff --git a/server/server.cpp b/server/server.cpp index 5768434..d2fbe76 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -3,7 +3,6 @@ #include "mail.h" -#include #include #include #include @@ -14,10 +13,14 @@ #include #include #include +#include +#include #include #include #include +#include #include +#include #include @@ -53,7 +56,7 @@ std::string saveToFile(fs::path object_dir, std::string message); std::string getSha1(const std::string& p_arg); // from myserver.c -void *clientCommunication(void *data); +void *clientCommunication(int data); void signalHandler(int sig); std::string cmdSEND(std::vector& received); @@ -64,8 +67,6 @@ std::string cmdDEL(std::vector& received); inline void exiting(); inline std::string read_file(std::string_view path); -user_handler* user_handler::instancePtr = nullptr; - int main (int argc, char* argv[]) { if (argc < 3 || @@ -89,7 +90,7 @@ int main (int argc, char* argv[]) fs::create_directory(spool_dir/"users"); fs::create_directory(spool_dir/"messages"); - user_handler::getInstance()->setSpoolDir(spool_dir); + user_handler::getInstance().setSpoolDir(spool_dir); std::atexit(exiting); @@ -150,8 +151,8 @@ int main (int argc, char* argv[]) addrlen = sizeof(struct sockaddr_in); if ((new_socket = accept(create_socket, - (struct sockaddr *)&cliaddress, - &addrlen)) == -1) { + (struct sockaddr *)&cliaddress, + &addrlen)) == -1) { if (abortRequested) { perror("accept error after aborted"); } @@ -164,7 +165,9 @@ int main (int argc, char* argv[]) printf("Client connected from %s:%d...\n", inet_ntoa(cliaddress.sin_addr), ntohs(cliaddress.sin_port)); - clientCommunication(&new_socket); // returnValue can be ignored + // clientCommunication(&new_socket); // returnValue can be ignored + std::thread th(clientCommunication, new_socket); + th.detach(); new_socket = -1; } @@ -199,11 +202,11 @@ void printUsage() printf("Usage: \n"); } -void *clientCommunication(void *data) +void *clientCommunication(int data) { char buffer[BUF]; int size; - int *current_socket = (int *)data; + int *current_socket = &data; std::string incomplete_message = ""; @@ -360,7 +363,7 @@ std::string getSha1(const std::string& str) inline void exiting() { - user_handler::getInstance()->saveAll(); + user_handler::getInstance().saveAll(); printf("Saving... \n"); } @@ -375,9 +378,8 @@ std::string cmdSEND(std::vector& received) } } - user_handler* user_handler = user_handler::getInstance(); - user_handler->getOrCreateUser(received.at(1))->sendMail( - new struct mail(saveToFile(user_handler->getSpoolDir()/"messages", received.at(4)), received.at(3)), + user_handler::getInstance().getOrCreateUser(received.at(1))->sendMail( + new struct mail(saveToFile(user_handler::getInstance().getSpoolDir()/"messages", received.at(4)), received.at(3)), {received.at(2)} ); @@ -388,7 +390,7 @@ std::string cmdLIST(std::vector& received) { maillist inbox; user* user; - if (received.size() < 2 || (user = user_handler::getInstance()->getUser(received.at(1))) == nullptr) + if (received.size() < 2 || (user = user_handler::getInstance().getUser(received.at(1))) == nullptr) return "0\n"; inbox = user->getMails(); @@ -406,7 +408,6 @@ std::string cmdREAD(std::vector& received) { std::string response = "OK\n"; - user_handler* user_handler = user_handler::getInstance(); user* user; mail* mail; @@ -414,13 +415,13 @@ std::string cmdREAD(std::vector& received) if(received.size() < 3 || !isInteger(received.at(2)) || - (user = user_handler->getUser(received.at(1))) == nullptr || + (user = user_handler::getInstance().getUser(received.at(1))) == nullptr || (mail = user->getMail(strtoul(received.at(2).c_str(), &p, 10))) == nullptr || mail->deleted) return "ERR\n"; try { - std::string path_str = user_handler->getSpoolDir()/"messages"/mail->filename; + std::string path_str = user_handler::getInstance().getSpoolDir()/"messages"/mail->filename; response.append(read_file(path_str)).append("\n"); } catch (...) { // TODO: more specific error handling - then again, it will respond with ERR either way @@ -432,14 +433,13 @@ std::string cmdREAD(std::vector& received) std::string cmdDEL(std::vector& received) { - user_handler* user_handler = user_handler::getInstance(); user* user; char* p; if(received.size() < 3 || !isInteger(received.at(2)) || - (user = user_handler->getUser(received.at(1))) == nullptr || + (user = user_handler::getInstance().getUser(received.at(1))) == nullptr || (user->delMail(strtoul(received.at(2).c_str(), &p, 10))) == false) return "ERR\n"; diff --git a/server/user.cpp b/server/user.cpp index ad51508..8a27843 100644 --- a/server/user.cpp +++ b/server/user.cpp @@ -77,11 +77,10 @@ void user::addMail(mail* mail) void user::sendMail(mail* mail, std::vector recipients) { - user_handler* user_handler = user_handler::getInstance(); std::vector users; for ( auto& name : recipients) { // TODO: error handling for non existing user - users.push_back(user_handler->getOrCreateUser(name)); + users.push_back(user_handler::getInstance().getOrCreateUser(name)); } mail->sender = this->name; @@ -114,7 +113,7 @@ bool user::delMail(u_int id) return false; if (!(*it)->filename.empty()) - success = fs::remove(user_handler::getInstance()->getSpoolDir()/"messages"/(*it)->filename); + success = fs::remove(user_handler::getInstance().getSpoolDir()/"messages"/(*it)->filename); if (success) { this->user_data["mails"]["received"][std::to_string((*it)->id)]["subject"] = ""; diff --git a/server/user_handler.cpp b/server/user_handler.cpp index 9866fbf..7321e01 100644 --- a/server/user_handler.cpp +++ b/server/user_handler.cpp @@ -13,6 +13,11 @@ user_handler::user_handler() } } +user_handler::~user_handler() +{ + // +} + user* user_handler::getUser(std::string name) { if (this->users.find(name) == this->users.end()) { diff --git a/server/user_handler.h b/server/user_handler.h index 2589c9c..0468d74 100644 --- a/server/user_handler.h +++ b/server/user_handler.h @@ -12,17 +12,15 @@ namespace fs = std::filesystem; class user_handler { public: - user_handler(const user_handler& obj) = delete; - - static user_handler* getInstance() { - if (instancePtr == nullptr) { - instancePtr = new user_handler(); - return instancePtr; - } else { - return instancePtr; - } + static user_handler& getInstance() { + static user_handler instance; + return instance; }; - ~user_handler(); + + user_handler(user_handler const&) = delete; + user_handler(user_handler&&) = delete; + user_handler& operator=(user_handler const&) = delete; + user_handler& operator=(user_handler &&) = delete; void setSpoolDir(fs::path p) { this->spool_dir = p; }; fs::path getSpoolDir() { return this->spool_dir; }; @@ -32,10 +30,10 @@ public: void saveAll(); -private: +protected: - static user_handler* instancePtr; user_handler(); + ~user_handler(); fs::path spool_dir; std::map users;