Bonjour a tous,
J'ai un soucis de logique et d'organisation de mon code.
Il est difficile d'expliqué le problème, je vais donc vous montrer le code et expliqué mon soucis par la suite.
Il s'agit d'un simple serveur/client standard. Hors pour un certaine organisation du code j'ai décidé de mettre un Thread par écoute client. On retrouve donc deux classe : Gestionnaire et Client.
La classe Gestionnaire qui gèrent tout les clients et la classe Client gére le Thread d’écoute.
Gestionnaire.cpp
#include "Gestionnaire.h"
Gestionnaire::Gestionnaire()
{
std::cout << "Instance Gestionnaire - OK" << std::endl;
sf::TcpListener ecoute;
ecoute.listen(PORT_ECOUTE);
std::cout << "Lancement ecoute : port " << PORT_ECOUTE << std::endl;
while (true)
{
sf::TcpSocket *client = new sf::TcpSocket();
std::cout << "Attente de connexion " << std::endl;
if (ecoute.accept(*client) == sf::Socket::Done)
{
std::cout << "Tentative connexion (" << client->getRemoteAddress() << ")" << std::endl;
m_mutexGlobale.lock();
m_listeClients.push_back(new Client(this, client));
m_mutexGlobale.unlock();
std::cout << "Connexion de " << client->getRemoteAddress() << "- OK" << std::endl;
}
}
}
Gestionnaire::~Gestionnaire()
{
for (unsigned int i = 0; i < m_listeClients.size(); i++)
{
std::cout << "Liberation Client (" << m_listeClients[i] << ")" << std::endl;
delete m_listeClients[i];
}
std::cout << "Liberation Gestionnaire - OK" << std::endl;
}
Client.cpp
Client::Client(Gestionnaire *gestionnaire, sf::TcpSocket *socket)
{
m_gestionnaire = gestionnaire;
m_socket = socket;
m_threadEnCour = true;
m_threadSocket = new sf::Thread(&Client::debuterEcoute, this);
std::cout << "Instance Client - OK" << std::endl;
m_threadSocket->launch();
}
Client::~Client()
{
delete m_threadSocket;
delete m_socket;
}
void Client::debuterEcoute()
{
std::cout << "Lancement d\'ecoute (" << m_socket->getRemoteAddress() << ")" << std::endl;
while (m_threadEnCour)
{
sf::Packet packetReception;
sf::TcpSocket::Status status = m_socket->receive(packetReception);
if (status == sf::TcpSocket::Disconnected)
{
m_threadEnCour = false;
std::cout << "Deconnexion Client (" << m_socket->getRemoteAddress() << ")" << std::endl;
}
else if (status == sf::TcpSocket::Error)
{
m_threadEnCour = false;
std::cout << "Erreur : Paquet erreur (" << m_socket->getRemoteAddress() << ")" << std::endl;
}
else if (status == sf::TcpSocket::Done)
{
std::cout << "Reception paquet - OK (" << m_socket->getRemoteAddress() << ")" << std::endl;
}
}
std::cout << "Fin d\'ecoute (" << m_socket->getRemoteAddress() << ")" << std::endl;
// ici, code susceptible de devoir désalloué la classe client et supprimer le pointeur dans la classe Gestionnaire.
}
Mon soucis est le suivant : je souhaite que lorsque mon Thread soit terminé, donc en gros que le client c'est déconnecté ou qu'il y a eu une erreur, que le Thread demande a la classe Gestionnaire de non seulement désalloué la mémoire de l'instance de Client mais aussi de supprimer le pointeur dans le vector.
Hors problème, car si a la fin de mon Thread je demande a la classe Gestionnaire de supprimer Client (du style m_gestionnaire->supprClient(this); ), étant donné que c'est le Thread qui la appelé, le Thread sera donc toujours en fonction et donc provoque une erreur lors de sa destruction.
J’espère avoir été le plus claire possible, ma question est donc la suivante : peut-on demander a un Thread de d'auto détruire la classe qui le contient, si oui comment ?
En cas de question ou de non compréhension j'essayerai de mieux reformulé
Merci beaucoup de votre aide.