Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

connection_provider_unix.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: connection_provider_unix.cpp,v 1.2 2001/02/23 00:04:50 cybernerd Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 
00015 #include "Core/precomp.h"
00016 
00017 #ifdef USE_NETWORK
00018 
00019 #include <API/Core/System/cl_assert.h>
00020 #include <API/Core/System/error.h>
00021 #include <API/Core/System/mutex.h>
00022 #include <Network/Generic/network_delivery_impl.h>
00023 #include <Network/Generic/network_delivery_socket.h>
00024 #include <Network/Unix/network_unix.h>
00025 #include <Network/Unix/unix_pipe_connection.h>
00026 #include <Network/Unix/connection_provider_unix.h>
00027 
00028 /*********************************************************************
00029                                 CL_Connections_Unix Implementation
00030 *********************************************************************/
00031 
00032 CL_Connections_Unix::CL_Connections_Unix(CL_UnixPipeConnection *_client_connection)
00033 {
00034         client_connection = _client_connection;
00035 }
00036 
00037 CL_Connections_Unix::~CL_Connections_Unix()
00038 {
00039 }
00040 
00041 CL_UDPConnection *CL_Connections_Unix::create_udp_connection(unsigned int port)
00042 {
00043         CL_UniformUDPConnection *ret = new CL_UniformUDPConnection;
00044         bool res = ret->bind(port);
00045 
00046         if (res) 
00047         {
00048                 udp_connections.push_back(ret);
00049                 return ret;
00050         }
00051         else
00052         {
00053                 delete ret;
00054                 return NULL;
00055         }
00056 }
00057 
00058 CL_Connection *CL_Connections_Unix::get_client()
00059 {
00060         return client_connection;
00061 }
00062 
00063 CL_Connection *CL_Connections_Unix::create_tcp_connection(
00064         int ip_addr,
00065         int port)
00066 {
00067         CL_UniformSocket *socket = new CL_UniformSocket(this);
00068         socket->init_socket();
00069         bool res = socket->try_connect(ip_addr, port);
00070 
00071         if (res) 
00072         {
00073                 connections.push_back(socket);
00074                 return socket;
00075         }
00076         else
00077         {
00078                 delete socket;
00079                 return NULL;
00080         }
00081 }
00082 
00083 CL_Connection *CL_Connections_Unix::accept()
00084 {
00085         for (
00086                 std::list<CL_UniformAcceptSocket*>::iterator it = accepting_connections.begin();
00087                 it != accepting_connections.end();
00088                 it++)
00089         {
00090                 CL_UniformSocket *ret = (*it)->accept();
00091                 if (ret != NULL) 
00092                 {
00093                         connections.push_back(ret);
00094                         return ret;
00095                 }
00096         }
00097         return NULL;
00098 }
00099 
00100 void CL_Connections_Unix::start_accept_on_port(int port)
00101 {
00102         CL_UniformAcceptSocket *new_accept_socket = new CL_UniformAcceptSocket(this);
00103         bool res = new_accept_socket->bind(port);
00104 
00105         // Argh - we need some robustness bad!
00106         if (res == false) throw CL_Error("Port already in use an other application!");
00107 
00108         accepting_connections.push_back(new_accept_socket);
00109 }
00110 
00111 void CL_Connections_Unix::stop_accept_on_port(int port)
00112 {
00113         for (
00114                 std::list<CL_UniformAcceptSocket *>::iterator it = accepting_connections.begin();
00115                 it != accepting_connections.end();
00116                 it++)
00117         {
00118                 if ((*it)->get_port() == port)
00119                 {
00120                         delete (*it);
00121                         it = accepting_connections.erase(it);
00122                         return;
00123                 }
00124         }
00125 }
00126 
00127 void CL_Connections_Unix::wait_for_connection_data(CL_Mutex *mutex)
00128 {
00129         mutex->enter();
00130 
00131         fd_set fdread;
00132         FD_ZERO(&fdread);
00133 
00134         fd_set fdwrite;
00135         FD_ZERO(&fdwrite);
00136 
00137         int highest_fd = -1;
00138         if (client_connection != NULL)
00139         {
00140                 highest_fd = client_connection->get_socket();
00141                 FD_SET(client_connection->get_socket(), &fdread);
00142         }
00143 
00144         for (
00145                 std::list<CL_UniformSocket *>::iterator counter = connections.begin();
00146                 counter != connections.end();
00147                 counter++)
00148         {
00149                 if ((*counter)->connection_lost() == false)
00150                 {
00151                         if ((*counter)->get_socket() > highest_fd)
00152                                 highest_fd = (*counter)->get_socket();
00153 
00154                         FD_SET((*counter)->get_socket(), &fdread);
00155 
00156                         if ((*counter)->send_avail() == false)
00157                                 FD_SET((*counter)->get_socket(), &fdwrite);
00158                 }
00159         }
00160 
00161         for (
00162                 std::list<CL_UniformUDPConnection *>::iterator counter2 = udp_connections.begin();
00163                 counter2 != udp_connections.end();
00164                 counter2++)
00165         {
00166                 if ((*counter2)->get_socket() > highest_fd)
00167                         highest_fd = (*counter2)->get_socket();
00168 
00169                 FD_SET((*counter2)->get_socket(), &fdread);
00170 //              if ((*counter2)->send_avail() == false)
00171 //                      FD_SET((*counter)->get_socket(), &fdwrite);
00172         }
00173 
00174         for (
00175                 std::list<CL_UniformAcceptSocket *>::iterator counter3 = accepting_connections.begin();
00176                 counter3 != accepting_connections.end();
00177                 counter3++)
00178         {
00179                 if ((*counter3)->get_socket() > highest_fd)
00180                         highest_fd = (*counter3)->get_socket();
00181 
00182                 if ((*counter3)->send_avail() == false)
00183                         FD_SET((*counter3)->get_socket(), &fdwrite);
00184 
00185                 FD_SET((*counter3)->get_socket(), &fdread);
00186         }
00187         
00188         mutex->leave();
00189 
00190         timeval tv;
00191         tv.tv_sec = 0;
00192         tv.tv_usec = 1000;
00193 
00194         ::select(highest_fd+1, &fdread, &fdwrite, NULL, &tv);
00195 
00196         // don't assert if select() fails. It can happen because we select
00197         // outside the mutex section, and the game thread may close a socket in
00198         // the mean time.
00199 }
00200 
00201 void CL_Connections_Unix::remove_connection(CL_Connection *removed_connection)
00202 {
00203         connections.remove((CL_UniformSocket *) removed_connection);
00204 }
00205 
00206 #endif // USE_NETWORK

Generated at Wed Apr 4 19:53:59 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001