multithreading

has memory leaks
This commit is contained in:
Benedikt Galbavy 2023-11-14 22:53:50 +01:00
parent 5a26943315
commit 97fc3605ce
5 changed files with 38 additions and 36 deletions

View File

@ -26,7 +26,7 @@ void mail::remove()
{ {
if (this->filename.empty()) if (this->filename.empty())
return; 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 = ""; this->filename = "";
} }

View File

@ -3,7 +3,6 @@
#include "mail.h" #include "mail.h"
#include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
@ -14,10 +13,14 @@
#include <fstream> #include <fstream>
#include <cctype> #include <cctype>
#include <algorithm> #include <algorithm>
#include <future>
#include <pthread.h>
#include <string_view> #include <string_view>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <thread>
#include <vector> #include <vector>
#include <algorithm>
#include <locale> #include <locale>
@ -53,7 +56,7 @@ std::string saveToFile(fs::path object_dir, std::string message);
std::string getSha1(const std::string& p_arg); std::string getSha1(const std::string& p_arg);
// from myserver.c // from myserver.c
void *clientCommunication(void *data); void *clientCommunication(int data);
void signalHandler(int sig); void signalHandler(int sig);
std::string cmdSEND(std::vector<std::string>& received); std::string cmdSEND(std::vector<std::string>& received);
@ -64,8 +67,6 @@ std::string cmdDEL(std::vector<std::string>& received);
inline void exiting(); inline void exiting();
inline std::string read_file(std::string_view path); inline std::string read_file(std::string_view path);
user_handler* user_handler::instancePtr = nullptr;
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
if (argc < 3 || if (argc < 3 ||
@ -89,7 +90,7 @@ int main (int argc, char* argv[])
fs::create_directory(spool_dir/"users"); fs::create_directory(spool_dir/"users");
fs::create_directory(spool_dir/"messages"); fs::create_directory(spool_dir/"messages");
user_handler::getInstance()->setSpoolDir(spool_dir); user_handler::getInstance().setSpoolDir(spool_dir);
std::atexit(exiting); std::atexit(exiting);
@ -150,8 +151,8 @@ int main (int argc, char* argv[])
addrlen = sizeof(struct sockaddr_in); addrlen = sizeof(struct sockaddr_in);
if ((new_socket = accept(create_socket, if ((new_socket = accept(create_socket,
(struct sockaddr *)&cliaddress, (struct sockaddr *)&cliaddress,
&addrlen)) == -1) { &addrlen)) == -1) {
if (abortRequested) { if (abortRequested) {
perror("accept error after aborted"); perror("accept error after aborted");
} }
@ -164,7 +165,9 @@ int main (int argc, char* argv[])
printf("Client connected from %s:%d...\n", printf("Client connected from %s:%d...\n",
inet_ntoa(cliaddress.sin_addr), inet_ntoa(cliaddress.sin_addr),
ntohs(cliaddress.sin_port)); 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; new_socket = -1;
} }
@ -199,11 +202,11 @@ void printUsage()
printf("Usage: <twmailer-server [port] [path spool_directory]>\n"); printf("Usage: <twmailer-server [port] [path spool_directory]>\n");
} }
void *clientCommunication(void *data) void *clientCommunication(int data)
{ {
char buffer[BUF]; char buffer[BUF];
int size; int size;
int *current_socket = (int *)data; int *current_socket = &data;
std::string incomplete_message = ""; std::string incomplete_message = "";
@ -360,7 +363,7 @@ std::string getSha1(const std::string& str)
inline void exiting() inline void exiting()
{ {
user_handler::getInstance()->saveAll(); user_handler::getInstance().saveAll();
printf("Saving... \n"); printf("Saving... \n");
} }
@ -375,9 +378,8 @@ std::string cmdSEND(std::vector<std::string>& received)
} }
} }
user_handler* user_handler = user_handler::getInstance(); user_handler::getInstance().getOrCreateUser(received.at(1))->sendMail(
user_handler->getOrCreateUser(received.at(1))->sendMail( new struct mail(saveToFile(user_handler::getInstance().getSpoolDir()/"messages", received.at(4)), received.at(3)),
new struct mail(saveToFile(user_handler->getSpoolDir()/"messages", received.at(4)), received.at(3)),
{received.at(2)} {received.at(2)}
); );
@ -388,7 +390,7 @@ std::string cmdLIST(std::vector<std::string>& received)
{ {
maillist inbox; maillist inbox;
user* user; 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"; return "0\n";
inbox = user->getMails(); inbox = user->getMails();
@ -406,7 +408,6 @@ std::string cmdREAD(std::vector<std::string>& received)
{ {
std::string response = "OK\n"; std::string response = "OK\n";
user_handler* user_handler = user_handler::getInstance();
user* user; user* user;
mail* mail; mail* mail;
@ -414,13 +415,13 @@ std::string cmdREAD(std::vector<std::string>& received)
if(received.size() < 3 || if(received.size() < 3 ||
!isInteger(received.at(2)) || !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 = user->getMail(strtoul(received.at(2).c_str(), &p, 10))) == nullptr ||
mail->deleted) mail->deleted)
return "ERR\n"; return "ERR\n";
try { 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"); response.append(read_file(path_str)).append("\n");
} }
catch (...) { // TODO: more specific error handling - then again, it will respond with ERR either way catch (...) { // TODO: more specific error handling - then again, it will respond with ERR either way
@ -432,14 +433,13 @@ std::string cmdREAD(std::vector<std::string>& received)
std::string cmdDEL(std::vector<std::string>& received) std::string cmdDEL(std::vector<std::string>& received)
{ {
user_handler* user_handler = user_handler::getInstance();
user* user; user* user;
char* p; char* p;
if(received.size() < 3 || if(received.size() < 3 ||
!isInteger(received.at(2)) || !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) (user->delMail(strtoul(received.at(2).c_str(), &p, 10))) == false)
return "ERR\n"; return "ERR\n";

View File

@ -77,11 +77,10 @@ void user::addMail(mail* mail)
void user::sendMail(mail* mail, std::vector<std::string> recipients) void user::sendMail(mail* mail, std::vector<std::string> recipients)
{ {
user_handler* user_handler = user_handler::getInstance();
std::vector<user*> users; std::vector<user*> users;
for ( auto& name : recipients) { for ( auto& name : recipients) {
// TODO: error handling for non existing user // 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; mail->sender = this->name;
@ -114,7 +113,7 @@ bool user::delMail(u_int id)
return false; return false;
if (!(*it)->filename.empty()) 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) { if (success) {
this->user_data["mails"]["received"][std::to_string((*it)->id)]["subject"] = ""; this->user_data["mails"]["received"][std::to_string((*it)->id)]["subject"] = "";

View File

@ -13,6 +13,11 @@ user_handler::user_handler()
} }
} }
user_handler::~user_handler()
{
//
}
user* user_handler::getUser(std::string name) user* user_handler::getUser(std::string name)
{ {
if (this->users.find(name) == this->users.end()) { if (this->users.find(name) == this->users.end()) {

View File

@ -12,17 +12,15 @@ namespace fs = std::filesystem;
class user_handler { class user_handler {
public: public:
user_handler(const user_handler& obj) = delete; static user_handler& getInstance() {
static user_handler instance;
static user_handler* getInstance() { return instance;
if (instancePtr == nullptr) {
instancePtr = new user_handler();
return instancePtr;
} else {
return instancePtr;
}
}; };
~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; }; void setSpoolDir(fs::path p) { this->spool_dir = p; };
fs::path getSpoolDir() { return this->spool_dir; }; fs::path getSpoolDir() { return this->spool_dir; };
@ -32,10 +30,10 @@ public:
void saveAll(); void saveAll();
private: protected:
static user_handler* instancePtr;
user_handler(); user_handler();
~user_handler();
fs::path spool_dir; fs::path spool_dir;
std::map<std::string, user*> users; std::map<std::string, user*> users;