Commit 069877ae authored by PierreEngelstein's avatar PierreEngelstein
Browse files

Cleaned memory leakage

parent e40e03a5
#include <iostream>
#include <thread/Socket/SocketThread.hpp>
#include <thread/Socket/Client.hpp>
#include <thread/Delay/DelayThread.hpp>
#include <thread/ThreadPool.hpp>
#include <memory>
std::shared_ptr<threads::DelayThread> delay;
#include <signal.h>
threads::DelayThread *delay;
threads::ThreadPool *pool;
bool running;
int server_socket;
int threads::Client::nb_client_socket = 0;
void handle_close(int signal_num)
{
delay->End();
delay->Join();
threads::Client::Close(server_socket);
server_socket = -1;
running = false;
}
int main()
{
printf("Hello World !\n");
signal(SIGINT, handle_close);
int server_socket = threads::SocketThread::CreateServerSocket(9999, "tcp", 10);
server_socket = threads::SocketThread::CreateServerSocket(9999, "tcp", 10);
// threads::DelayThread delay;
// delay.Create();
if(server_socket == -1)
{
return -1;
}
delay = std::make_shared<threads::DelayThread>();
delay = new threads::DelayThread();
delay->Create();
// threads::ThreadPool pool(5);
// std::shared_ptr<threads::ThreadPool> pool = std::make_shared<threads::ThreadPool>(5);
pool = new threads::ThreadPool(5);
threads::ThreadPool pool(5);
running = true;
while(1)
char flag = 0;
while(running)
{
// threads::SocketThread _socket;
threads::Client client;
std::shared_ptr<threads::SocketThread> _socket = std::make_shared<threads::SocketThread>();
_socket->CreateSocket(server_socket);
if(!pool.AddThread(_socket, delay))
{
_socket->Create();
_socket->RegisterPool(&pool);
}else
if(pool->Size() < pool->Max())
{
_socket->End();
flag = _socket->CreateSocket(client, server_socket);
if(!flag)
flag = pool->AddThread(_socket, delay);
if(!flag && running)
{
flag = _socket->Create();
_socket->RegisterPool(pool);
_socket->RegisterDelay(delay);
}
if(flag)
{
_socket->End();
}
if(!running)
{
_socket->End();
break;
}
}
}
delay->End();
pool->KillAll();
delete delay;
delete pool;
printf("Finished server !\n");
return 0;
}
\ No newline at end of file
......@@ -4,13 +4,25 @@ namespace threads
{
DelayThread::DelayThread() : IThread(0){}
DelayThread::~DelayThread(){
// Join();
DelayThread::~DelayThread()
{
for(auto iter = cooldown_list.begin(); iter != cooldown_list.end();)
{
iter = cooldown_list.erase(iter);
}
// DelayThread::Detach();
}
std::string DelayThread::ToString()
{
return "";
std::string str = "Delay thread :\n";
for(auto iter = cooldown_list.begin(); iter != cooldown_list.end(); iter++)
{
str.append(iter->ToString());
str.append("\n");
}
return str;
}
void DelayThread::Run()
......@@ -19,27 +31,84 @@ namespace threads
while(DelayThread::Running())
{
DelayThread::Decrease_All();
sleep(1);
}
return;
}
void DelayThread::Decrease_All()
{
for(auto iter = cooldown_list.begin(); iter != cooldown_list.end(); iter++)
for(auto iter = cooldown_list.begin(); iter != cooldown_list.end();)
{
if(iter->cooldown > 0)
iter->cooldown--;
if(iter->Cooldown() > 0)
{
iter->Decrease();
iter++;
}
else
{
iter = cooldown_list.erase(iter);
}
}
}
int DelayThread::IsOnCooldown(std::string ip)
{
for(auto iter = cooldown_list.begin(); iter != cooldown_list.end(); iter++)
if(!(iter->ip.compare(ip)))
return iter->cooldown;
if(iter->Compare(ip))
return iter->Cooldown();
return -1;
}
void DelayThread::AddIP(std::string ip)
{
printf("Coucou !\n");
ip_cooldown cooldown(ip, 10);
cooldown_list.push_back(cooldown);
printf("Added ip %s in cooldown !\n", ip.c_str());
}
///// ip_cooldown /////
ip_cooldown::ip_cooldown(std::string ip, int cooldown)
{
ip_cooldown::_ip = ip;
ip_cooldown::_cooldown = cooldown;
}
ip_cooldown::~ip_cooldown()
{
}
int ip_cooldown::Cooldown()
{
return ip_cooldown::_cooldown;
}
void ip_cooldown::Decrease()
{
ip_cooldown::_cooldown--;
}
bool ip_cooldown::Compare(std::string ip)
{
return !ip_cooldown::_ip.compare(ip);
}
std::string ip_cooldown::ToString()
{
std::string str = "ip ";
str.append(ip_cooldown::_ip);
str.append(" is on cooldown of ");
str.append(std::to_string(ip_cooldown::_cooldown));
str.append(" seconds.");
return str;
}
std::string ip_cooldown::IP()
{
return ip_cooldown::_ip;
}
}
......@@ -10,8 +10,16 @@ namespace threads
class ip_cooldown
{
public:
std::string ip;
int cooldown;
ip_cooldown(std::string ip, int cooldown);
~ip_cooldown();
int Cooldown();
void Decrease();
bool Compare(std::string ip);
std::string ToString();
std::string IP();
private:
std::string _ip;
int _cooldown;
};
class DelayThread : public IThread
......@@ -22,6 +30,7 @@ namespace threads
void Run() override;
std::string ToString() override;
int IsOnCooldown(std::string ip);
void AddIP(std::string ip);
protected:
private:
std::vector<ip_cooldown> cooldown_list;
......
......@@ -2,32 +2,35 @@
namespace threads
{
void EmptyRun(void)
{
fprintf(stdout, "Coucou :)\n");
}
IThread::IThread(int id)
{
printf("Creating thread of id %d\n", id);
IThread::_id = id;
// printf("Creating thread of id %d\n", id);
IThread::_id = id;
IThread::_running = false;
}
IThread::~IThread()
{
if(IThread::_running)
{
IThread::_running = false;
_thread.join();
}
fprintf(stdout, "Trying to end thread !\n");
IThread::Detach();
}
int IThread::Create()
{
IThread::_thread = std::thread([this] { this->Run(); });
IThread::_thread = std::thread([this] { Run(); });
if(!IThread::_thread.joinable())
{
fprintf(stderr, "Thread %lu is not joinable !\n", IThread::_thread.native_handle());
fprintf(stderr, "Thread is not joinable !\n");
fprintf(stderr, "%s\n", strerror(errno));
return 1;
}
fprintf(stdout, "Created thread %lu\n", IThread::_thread.native_handle());
// fprintf(stdout, "Created thread %lu\n", IThread::_thread.native_handle());
// _thread.detach();
IThread::_running = true;
return 0;
}
......@@ -44,6 +47,18 @@ namespace threads
return 1;
}
int IThread::Detach()
{
if(IThread::_thread.joinable())
{
IThread::_thread.detach();
fprintf(stdout, "Detached thread !\n");
return 0;
}
fprintf(stderr, "Thread is not joinable\n");
return 1;
}
void IThread::Run(){}
bool IThread::Running()
......
......@@ -20,6 +20,7 @@ namespace threads
int Create();
int Join();
int Detach();
protected:
bool _running;
......
......@@ -4,8 +4,10 @@ namespace threads
{
Client::Client()
{
Client::port = 0;
Client::socket = 0;
Client::port = 0;
Client::socket = 0;
Client::socket_length = 0;
Client::active = true;
}
Client::~Client()
......@@ -46,10 +48,21 @@ namespace threads
int Client::SetSocket(int server_socket)
{
if(server_socket == -1)
return 1;
Client::socket_length = sizeof(Client::socket_address);
Client::socket = accept(server_socket, (struct sockaddr *)&(Client::socket_address), &(Client::socket_length));
nb_client_socket++;
if(nb_client_socket > ACCEPT_MAX)
{
fprintf(stderr, "Error, too much sockets %d!\n", nb_client_socket);
return 1;
}
if(Client::socket < 1)
{
fprintf(stderr, "Accept failed ! (%d)\n", Client::socket);
fprintf(stderr, "Accept failed ! (%d) (%d)\n", Client::socket, nb_client_socket);
fprintf(stderr, "%s\n", strerror(errno));
return 1;
}
......@@ -65,4 +78,31 @@ namespace threads
str.append("\n");
return str;
}
int Client::Close(int socket)
{
int res = close(socket);
if(res)
{
fprintf(stderr, "Socket %d close failed ! (%d)\n", socket, res);
fprintf(stderr, "%s\n", strerror(errno));
return 1;
}
fprintf(stdout, "Socket closed !\n");
return 0;
}
int Client::CloseClient()
{
int res = 1;
if(Client::active)
{
if(!Client::Close(Client::socket))
{
active = false;
res = 0;
}
}
return res;
}
}
\ No newline at end of file
......@@ -4,6 +4,7 @@
#include <memory>
#include <string>
#include <cstring>
#include <unistd.h>
#ifdef __linux
#include <netdb.h>
......@@ -12,6 +13,8 @@
#include <winsock2.h>
#endif
#define ACCEPT_MAX 5
typedef struct sockaddr_in address_t;
namespace threads
......@@ -19,6 +22,7 @@ namespace threads
class Client
{
public:
static int nb_client_socket;
Client();
virtual ~Client();
......@@ -31,6 +35,9 @@ namespace threads
void Set();
/* Set the client socket */
int SetSocket(int server_socket);
/* Close the client socket */
int CloseClient();
static int Close(int socket);
std::string ToString();
......@@ -38,6 +45,7 @@ namespace threads
std::string ip;
uint16_t port;
int socket;
bool active;
__socklen_t socket_length;
struct sockaddr_in socket_address;
};
......
#include "ThreadPool.hpp"
#include "Socket/SocketThread.hpp"
#include "Socket/Client.hpp"
#include "Delay/DelayThread.hpp"
namespace threads
......@@ -15,11 +16,13 @@ namespace threads
ThreadPool::~ThreadPool(){}
int ThreadPool::AddThread(std::shared_ptr<threads::SocketThread> thread, std::shared_ptr<threads::DelayThread> delay)
int ThreadPool::AddThread(std::shared_ptr<threads::SocketThread> thread, threads::DelayThread *delay)
{
if(ThreadPool::pool.size() >= ThreadPool::max_thread)
{
fprintf(stderr, "Already too much clients connected !\n");
thread->End();
thread->Close();
return -1;
}
......@@ -34,6 +37,9 @@ namespace threads
if(iter->get()->EqualIP(thread))
{
fprintf(stderr, "Client %s is already connected, cannot accept connection.\n", thread->IP().c_str());
thread->End();
Client::nb_client_socket--;
thread->Close();
return -1;
}
}
......@@ -49,6 +55,9 @@ namespace threads
if((cooldown = delay->IsOnCooldown(thread->IP())) != -1)
{
fprintf(stderr, "IP %s is still in cooldown mode, please wait %d seconds before connecting !\n", thread->IP().c_str(), cooldown);
Client::nb_client_socket--;
thread->End();
thread->Close();
return -1;
}
ThreadPool::pool.push_back(thread);
......@@ -60,25 +69,48 @@ namespace threads
std::string str = "Thread pool containing ";
str.append(std::to_string(ThreadPool::pool.size()));
str.append(" elements");
for(auto iter = ThreadPool::pool.begin(); iter < ThreadPool::pool.end(); iter++)
{
str.append(iter->get()->ToString());
}
str.append("\n");
// for(auto iter = ThreadPool::pool.begin(); iter < ThreadPool::pool.end(); iter++)
// {
// str.append(iter->get()->ToString());
// }
// str.append("\n");
return str;
}
void ThreadPool::RemoveIP(std::string ip)
{
for(auto iter = ThreadPool::pool.begin(); iter < ThreadPool::pool.end(); iter++)
fprintf(stdout, "REMOVE IP AHAHAHAHAHAH !\n");
for(auto iter = ThreadPool::pool.begin(); iter < ThreadPool::pool.end();)
{
printf("HEY !\n");
if(!iter->get()->IP().compare(ip))
{
printf("Found IP %s, removing !\n", iter->get()->IP().c_str());
iter = pool.erase(iter);
}
// str.append(iter->get()->ToString());
else
iter++;
}
}
void ThreadPool::KillAll()
{
fprintf(stdout, "\n##########\nKilling all socket threads !\n");
for(auto iter = ThreadPool::pool.begin(); iter < ThreadPool::pool.end(); iter++)
{
fprintf(stdout, "%s\n", iter->get()->IP().c_str());
iter->get()->End();
iter->get()->Close();
// iter->get()->Detach();
iter = pool.erase(iter);
printf("**********\n");
}
fprintf(stdout, "##########\n");
}
int ThreadPool::Size()
{
return ThreadPool::pool.size();
}
int ThreadPool::Max()
{
return max_thread;
}
}
......@@ -11,16 +11,18 @@ namespace threads
{
class SocketThread;
class DelayThread;
class ThreadPool
{
public:
ThreadPool(int max);
virtual ~ThreadPool();
int AddThread(std::shared_ptr<threads::SocketThread> thread, std::shared_ptr<threads::DelayThread> delay);
int AddThread(std::shared_ptr<threads::SocketThread> thread, threads::DelayThread *delay);
std::string ToString();
void RemoveIP(std::string ip);
void KillAll();
int Size();
int Max();
private:
std::vector<std::shared_ptr<threads::SocketThread>> pool;
size_t max_thread;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment