From: Leandro Lucarella Date: Thu, 23 Oct 2003 02:59:19 +0000 (+0000) Subject: Se agregan un par de mutex porque el server se muere con segmentation fault X-Git-Tag: svn_import~376 X-Git-Url: https://git.llucax.com/z.facultad/75.42/plaqui.git/commitdiff_plain/751302dd67ffdeb0dfe72c4d2a7a2d58303cf5f3?hp=ab9300aaf1217f0c3b45dd5f1f1fdc1c5e5bd1be Se agregan un par de mutex porque el server se muere con segmentation fault cuando recibe muchas conexiones simultaneas. Tambien se agrega un limite a las conexiones pendientes en el listen(). Con todo esto se sigue colgando. --- diff --git a/Server/include/plaqui/server/runnable.h b/Server/include/plaqui/server/runnable.h index 7896090..cc3bb0e 100644 --- a/Server/include/plaqui/server/runnable.h +++ b/Server/include/plaqui/server/runnable.h @@ -64,6 +64,12 @@ namespace Server { */ bool stop; + /** + * Exclusión mutua. + * Recurso usado para recibir la exclusividad sobre un recurso. + */ + Glib::Mutex mutex; + // Métodos. private: diff --git a/Server/include/plaqui/server/tcpserver.h b/Server/include/plaqui/server/tcpserver.h index b3ecfa6..0290629 100644 --- a/Server/include/plaqui/server/tcpserver.h +++ b/Server/include/plaqui/server/tcpserver.h @@ -47,6 +47,9 @@ namespace Server { private: + /// Cantidad máxima de conexiones pendientes. + static const unsigned MAX_PENDING_CONNECTIONS; + /// Lista de conexiones de control. typedef std::list ConnectionList; diff --git a/Server/src/runnable.cpp b/Server/src/runnable.cpp index 7fd4105..cb3ba6f 100644 --- a/Server/src/runnable.cpp +++ b/Server/src/runnable.cpp @@ -61,10 +61,6 @@ void PlaQui::Server::Runnable::run(bool 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( @@ -81,7 +77,6 @@ void PlaQui::Server::Runnable::finish(bool attach) { #ifdef DEBUG std::cerr << __FILE__ << ": finish(attach = " << attach << ")" << std::endl; #endif // DEBUG - // TODO - necesita un mutex? stop = true; if (attach) { thread->join(); diff --git a/Server/src/tcpserver.cpp b/Server/src/tcpserver.cpp index 4131224..a9ce030 100644 --- a/Server/src/tcpserver.cpp +++ b/Server/src/tcpserver.cpp @@ -31,6 +31,8 @@ # include #endif // DEBUG +const unsigned PlaQui::Server::TCPServer::MAX_PENDING_CONNECTIONS = 5; + PlaQui::Server::TCPServer::~TCPServer(void) { #ifdef DEBUG std::cerr << __FILE__ << ": destructor." << std::endl; @@ -47,7 +49,7 @@ PlaQui::Server::TCPServer::TCPServer(int port): std::cerr << __FILE__ << ": escuchando en " << socket.localhost() << ":" << socket.localport() << "." << std::endl; #endif // DEBUG - socket.listen(); + socket.listen(MAX_PENDING_CONNECTIONS); #ifdef DEBUG std::cerr << __FILE__ << ": [despues de listen()] escuchando en " << socket.localhost() << ":" << socket.localport() << "." << std::endl; @@ -60,7 +62,7 @@ void PlaQui::Server::TCPServer::on_connection_finished( std::cerr << __FILE__ << ": on_connection_finished(connection = " << connection << ")" << std::endl; #endif // DEBUG - // TODO: poner lock. + mutex.lock(); connections.remove(connection); #ifdef DEBUG std::cerr << __FILE__ << ": lista de conexiones" << std::endl; @@ -69,33 +71,32 @@ void PlaQui::Server::TCPServer::on_connection_finished( std::cerr << "\t " << *i << std::endl; } #endif // DEBUG - // TODO: sacar lock. + mutex.unlock(); } +/// \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) { - // 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 - std::cerr << __FILE__ << ": real_run(): connection = " << connection - << std::endl; + std::cerr << __FILE__ << ": real_run(): connection = " << connection + << std::endl; #endif // DEBUG - // TODO: poner lock. + mutex.lock(); 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; + } #endif // DEBUG - // TODO: sacar lock. - // TODO: esto va en Server::new_connection() + mutex.unlock(); // Conecto la señal para cuando termina una conexión, borrarla. connection->signal_finished().connect( SigC::bind( diff --git a/Server/tests/server_test.cpp b/Server/tests/server_test.cpp index eddd8dd..1927af4 100644 --- a/Server/tests/server_test.cpp +++ b/Server/tests/server_test.cpp @@ -53,6 +53,9 @@ int main(int argc, char* argv[]) { str >> port; } + // Inicializa threads. + Glib::thread_init(); + // Corre el server. Server server(port); server.run(false);