cuando recibe muchas conexiones simultaneas. Tambien se agrega un limite a las
conexiones pendientes en el listen(). Con todo esto se sigue colgando.
+ /**
+ * Exclusión mutua.
+ * Recurso usado para recibir la exclusividad sobre un recurso.
+ */
+ Glib::Mutex mutex;
+
+ /// Cantidad máxima de conexiones pendientes.
+ static const unsigned MAX_PENDING_CONNECTIONS;
+
/// Lista de conexiones de control.
typedef std::list<Connection*> ConnectionList;
/// Lista de conexiones de control.
typedef std::list<Connection*> ConnectionList;
#endif // DEBUG
// Si vamos a correr la tarea en un thread.
if (detach) {
#endif // DEBUG
// Si vamos a correr la tarea en un thread.
if (detach) {
- // Nos aseguramos de tener threads.
- if (!Glib::thread_supported()) {
- Glib::thread_init();
- }
// Corremos el thread en una funcion estática para poder destruirlo al
// finalizar, pasandole el puntero al objeto.
thread = Glib::Thread::create(
// Corremos el thread en una funcion estática para poder destruirlo al
// finalizar, pasandole el puntero al objeto.
thread = Glib::Thread::create(
#ifdef DEBUG
std::cerr << __FILE__ << ": finish(attach = " << attach << ")" << std::endl;
#endif // DEBUG
#ifdef DEBUG
std::cerr << __FILE__ << ": finish(attach = " << attach << ")" << std::endl;
#endif // DEBUG
- // TODO - necesita un mutex?
stop = true;
if (attach) {
thread->join();
stop = true;
if (attach) {
thread->join();
# include <iostream>
#endif // DEBUG
# include <iostream>
#endif // DEBUG
+const unsigned PlaQui::Server::TCPServer::MAX_PENDING_CONNECTIONS = 5;
+
PlaQui::Server::TCPServer::~TCPServer(void) {
#ifdef DEBUG
std::cerr << __FILE__ << ": destructor." << std::endl;
PlaQui::Server::TCPServer::~TCPServer(void) {
#ifdef DEBUG
std::cerr << __FILE__ << ": destructor." << std::endl;
std::cerr << __FILE__ << ": escuchando en " << socket.localhost()
<< ":" << socket.localport() << "." << std::endl;
#endif // DEBUG
std::cerr << __FILE__ << ": escuchando en " << socket.localhost()
<< ":" << socket.localport() << "." << std::endl;
#endif // DEBUG
+ socket.listen(MAX_PENDING_CONNECTIONS);
#ifdef DEBUG
std::cerr << __FILE__ << ": [despues de listen()] escuchando en "
<< socket.localhost() << ":" << socket.localport() << "." << std::endl;
#ifdef DEBUG
std::cerr << __FILE__ << ": [despues de listen()] escuchando en "
<< socket.localhost() << ":" << socket.localport() << "." << std::endl;
std::cerr << __FILE__ << ": on_connection_finished(connection = "
<< connection << ")" << std::endl;
#endif // DEBUG
std::cerr << __FILE__ << ": on_connection_finished(connection = "
<< connection << ")" << std::endl;
#endif // DEBUG
connections.remove(connection);
#ifdef DEBUG
std::cerr << __FILE__ << ": lista de conexiones" << std::endl;
connections.remove(connection);
#ifdef DEBUG
std::cerr << __FILE__ << ": lista de conexiones" << std::endl;
std::cerr << "\t " << *i << std::endl;
}
#endif // DEBUG
std::cerr << "\t " << *i << std::endl;
}
#endif // DEBUG
+/// \todo TODO: ver tema de timeout o como salir de un accept().
void PlaQui::Server::TCPServer::real_run(void) {
#ifdef DEBUG
std::cerr << __FILE__ << ": real_run()" << std::endl;
#endif // DEBUG
Connection* connection;
while (!stop) {
void PlaQui::Server::TCPServer::real_run(void) {
#ifdef DEBUG
std::cerr << __FILE__ << ": real_run()" << std::endl;
#endif // DEBUG
Connection* connection;
while (!stop) {
- // TODO: ver tema de timeout o como salir de un accept().
// Forma grasa de salir del accept: crear conexion que salga al toque.
connection = new_connection(socket.accept());
#ifdef DEBUG
// Forma grasa de salir del accept: crear conexion que salga al toque.
connection = new_connection(socket.accept());
#ifdef DEBUG
- std::cerr << __FILE__ << ": real_run(): connection = " << connection
- << std::endl;
+ std::cerr << __FILE__ << ": real_run(): connection = " << connection
+ << std::endl;
connections.push_back(connection);
#ifdef DEBUG
connections.push_back(connection);
#ifdef DEBUG
- std::cerr << __FILE__ << ": real_run(): lista de conexiones" << std::endl;
- for (ConnectionList::const_iterator i = connections.begin();
- i != connections.end(); i++) {
- std::cerr << "\t " << *i << std::endl;
- }
+ std::cerr << __FILE__ << ": real_run(): lista de conexiones" << std::endl;
+ for (ConnectionList::const_iterator i = connections.begin();
+ i != connections.end(); i++) {
+ std::cerr << "\t " << *i << std::endl;
+ }
- // TODO: sacar lock.
- // TODO: esto va en Server::new_connection()
// Conecto la señal para cuando termina una conexión, borrarla.
connection->signal_finished().connect(
SigC::bind<Connection*>(
// Conecto la señal para cuando termina una conexión, borrarla.
connection->signal_finished().connect(
SigC::bind<Connection*>(
+ // Inicializa threads.
+ Glib::thread_init();
+
// Corre el server.
Server server(port);
server.run(false);
// Corre el server.
Server server(port);
server.run(false);