summaryrefslogtreecommitdiff
path: root/src/stable/server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/server.cpp')
-rw-r--r--src/stable/server.cpp252
1 files changed, 126 insertions, 126 deletions
diff --git a/src/stable/server.cpp b/src/stable/server.cpp
index 39ff7bb..e6c256e 100644
--- a/src/stable/server.cpp
+++ b/src/stable/server.cpp
@@ -14,138 +14,138 @@
14#include "bu/config.h" 14#include "bu/config.h"
15 15
16Bu::Server::Server() : 16Bu::Server::Server() :
17 nTimeoutSec( 0 ), 17 nTimeoutSec( 0 ),
18 nTimeoutUSec( 0 ), 18 nTimeoutUSec( 0 ),
19 bAutoTick( false ) 19 bAutoTick( false )
20{ 20{
21 FD_ZERO( &fdActive ); 21 FD_ZERO( &fdActive );
22} 22}
23 23
24Bu::Server::~Server() 24Bu::Server::~Server()
25{ 25{
26 shutdown(); 26 shutdown();
27} 27}
28 28
29void Bu::Server::addPort( int nPort, int nPoolSize ) 29void Bu::Server::addPort( int nPort, int nPoolSize )
30{ 30{
31 TcpServerSocket *s = new TcpServerSocket( nPort, nPoolSize ); 31 TcpServerSocket *s = new TcpServerSocket( nPort, nPoolSize );
32 socket_t nSocket = s->getSocket(); 32 socket_t nSocket = s->getSocket();
33 FD_SET( nSocket, &fdActive ); 33 FD_SET( nSocket, &fdActive );
34 hServers.insert( nSocket, s ); 34 hServers.insert( nSocket, s );
35} 35}
36 36
37void Bu::Server::addPort( const String &sAddr, int nPort, int nPoolSize ) 37void Bu::Server::addPort( const String &sAddr, int nPort, int nPoolSize )
38{ 38{
39 TcpServerSocket *s = new TcpServerSocket( sAddr, nPort, nPoolSize ); 39 TcpServerSocket *s = new TcpServerSocket( sAddr, nPort, nPoolSize );
40 socket_t nSocket = s->getSocket(); 40 socket_t nSocket = s->getSocket();
41 FD_SET( nSocket, &fdActive ); 41 FD_SET( nSocket, &fdActive );
42 hServers.insert( nSocket, s ); 42 hServers.insert( nSocket, s );
43} 43}
44 44
45void Bu::Server::setTimeout( int nTimeoutSec, int nTimeoutUSec ) 45void Bu::Server::setTimeout( int nTimeoutSec, int nTimeoutUSec )
46{ 46{
47 this->nTimeoutSec = nTimeoutSec; 47 this->nTimeoutSec = nTimeoutSec;
48 this->nTimeoutUSec = nTimeoutUSec; 48 this->nTimeoutUSec = nTimeoutUSec;
49} 49}
50 50
51void Bu::Server::scan() 51void Bu::Server::scan()
52{ 52{
53 struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; 53 struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec };
54 54
55 fd_set fdRead = fdActive; 55 fd_set fdRead = fdActive;
56 fd_set fdWrite /* = fdActive*/; 56 fd_set fdWrite /* = fdActive*/;
57 fd_set fdException = fdActive; 57 fd_set fdException = fdActive;
58 58
59 FD_ZERO( &fdWrite ); 59 FD_ZERO( &fdWrite );
60 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ ) 60 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ )
61 { 61 {
62 if( (*i)->hasOutput() ) 62 if( (*i)->hasOutput() )
63 FD_SET( i.getKey(), &fdWrite ); 63 FD_SET( i.getKey(), &fdWrite );
64 } 64 }
65 65
66 if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, 66 if( TEMP_FAILURE_RETRY( select( FD_SETSIZE,
67 &fdRead, &fdWrite, &fdException, &xTimeout ) ) < 0 ) 67 &fdRead, &fdWrite, &fdException, &xTimeout ) ) < 0 )
68 { 68 {
69 throw ExceptionBase("Error attempting to scan open connections."); 69 throw ExceptionBase("Error attempting to scan open connections.");
70 } 70 }
71 71
72 for( int j = 0; j < FD_SETSIZE; j++ ) 72 for( int j = 0; j < FD_SETSIZE; j++ )
73 { 73 {
74 if( FD_ISSET( j, &fdRead ) ) 74 if( FD_ISSET( j, &fdRead ) )
75 { 75 {
76 if( hServers.has( j ) ) 76 if( hServers.has( j ) )
77 { 77 {
78 TcpServerSocket *pSrv = hServers.get( j ); 78 TcpServerSocket *pSrv = hServers.get( j );
79 addClient( pSrv->accept(), pSrv->getPort() ); 79 addClient( pSrv->accept(), pSrv->getPort() );
80 } 80 }
81 else 81 else
82 { 82 {
83 Client *pClient = hClients.get( j ); 83 Client *pClient = hClients.get( j );
84 pClient->processInput(); 84 pClient->processInput();
85 if( !pClient->isOpen() ) 85 if( !pClient->isOpen() )
86 { 86 {
87 closeClient( j ); 87 closeClient( j );
88 } 88 }
89 } 89 }
90 } 90 }
91 if( FD_ISSET( j, &fdWrite ) ) 91 if( FD_ISSET( j, &fdWrite ) )
92 { 92 {
93 try 93 try
94 { 94 {
95 Client *pClient = hClients.get( j ); 95 Client *pClient = hClients.get( j );
96 try 96 try
97 { 97 {
98 pClient->processOutput(); 98 pClient->processOutput();
99 } 99 }
100 catch( Bu::TcpSocketException &e ) 100 catch( Bu::TcpSocketException &e )
101 { 101 {
102 closeClient( j ); 102 closeClient( j );
103 } 103 }
104 } 104 }
105 catch( Bu::HashException &e ) 105 catch( Bu::HashException &e )
106 { 106 {
107 // Do nothing, I guess, the client is already dead... 107 // Do nothing, I guess, the client is already dead...
108 // TODO: Someday, we may want to handle this more graceully. 108 // TODO: Someday, we may want to handle this more graceully.
109 } 109 }
110 } 110 }
111 } 111 }
112 112
113 Bu::List<int> lDelete; 113 Bu::List<int> lDelete;
114 // Now we just try to write all the pending data on all the sockets. 114 // Now we just try to write all the pending data on all the sockets.
115 // this could be done better eventually, if we care about the socket 115 // this could be done better eventually, if we care about the socket
116 // wanting to accept writes (using a select). 116 // wanting to accept writes (using a select).
117 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ ) 117 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ )
118 { 118 {
119 if( (*i)->wantsDisconnect() && !(*i)->hasOutput() ) 119 if( (*i)->wantsDisconnect() && !(*i)->hasOutput() )
120 { 120 {
121 lDelete.append( i.getKey() ); 121 lDelete.append( i.getKey() );
122 } 122 }
123 } 123 }
124 124
125 for( Bu::List<int>::iterator i = lDelete.begin(); i != lDelete.end(); i++ ) 125 for( Bu::List<int>::iterator i = lDelete.begin(); i != lDelete.end(); i++ )
126 { 126 {
127 closeClient( *i ); 127 closeClient( *i );
128 } 128 }
129 129
130 if( bAutoTick ) 130 if( bAutoTick )
131 tick(); 131 tick();
132} 132}
133 133
134void Bu::Server::addClient( socket_t nSocket, int nPort ) 134void Bu::Server::addClient( socket_t nSocket, int nPort )
135{ 135{
136 FD_SET( nSocket, &fdActive ); 136 FD_SET( nSocket, &fdActive );
137 137
138 Client *c = new Client( 138 Client *c = new Client(
139 new Bu::TcpSocket( nSocket ), 139 new Bu::TcpSocket( nSocket ),
140 new SrvClientLinkFactory() 140 new SrvClientLinkFactory()
141 ); 141 );
142 hClients.insert( nSocket, c ); 142 hClients.insert( nSocket, c );
143 143
144 onNewConnection( c, nPort ); 144 onNewConnection( c, nPort );
145} 145}
146 146
147Bu::Server::SrvClientLink::SrvClientLink( Bu::Client *pClient ) : 147Bu::Server::SrvClientLink::SrvClientLink( Bu::Client *pClient ) :
148 pClient( pClient ) 148 pClient( pClient )
149{ 149{
150} 150}
151 151
@@ -155,7 +155,7 @@ Bu::Server::SrvClientLink::~SrvClientLink()
155 155
156void Bu::Server::SrvClientLink::sendMessage( const Bu::String &sMsg ) 156void Bu::Server::SrvClientLink::sendMessage( const Bu::String &sMsg )
157{ 157{
158 pClient->onMessage( sMsg ); 158 pClient->onMessage( sMsg );
159} 159}
160 160
161Bu::Server::SrvClientLinkFactory::SrvClientLinkFactory() 161Bu::Server::SrvClientLinkFactory::SrvClientLinkFactory()
@@ -167,48 +167,48 @@ Bu::Server::SrvClientLinkFactory::~SrvClientLinkFactory()
167} 167}
168 168
169Bu::ClientLink *Bu::Server::SrvClientLinkFactory::createLink( 169Bu::ClientLink *Bu::Server::SrvClientLinkFactory::createLink(
170 Bu::Client *pClient ) 170 Bu::Client *pClient )
171{ 171{
172 return new SrvClientLink( pClient ); 172 return new SrvClientLink( pClient );
173} 173}
174 174
175void Bu::Server::setAutoTick( bool bEnable ) 175void Bu::Server::setAutoTick( bool bEnable )
176{ 176{
177 bAutoTick = bEnable; 177 bAutoTick = bEnable;
178} 178}
179 179
180void Bu::Server::tick() 180void Bu::Server::tick()
181{ 181{
182 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ ) 182 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ )
183 { 183 {
184 (*i)->tick(); 184 (*i)->tick();
185 } 185 }
186} 186}
187 187
188void Bu::Server::shutdown() 188void Bu::Server::shutdown()
189{ 189{
190 for( SrvHash::iterator i = hServers.begin(); i != hServers.end(); i++ ) 190 for( SrvHash::iterator i = hServers.begin(); i != hServers.end(); i++ )
191 { 191 {
192 delete *i; 192 delete *i;
193 } 193 }
194 194
195 hServers.clear(); 195 hServers.clear();
196 196
197 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ ) 197 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ )
198 { 198 {
199 closeClient( i.getKey() ); 199 closeClient( i.getKey() );
200 } 200 }
201 201
202 hClients.clear(); 202 hClients.clear();
203} 203}
204 204
205void Bu::Server::closeClient( socket_t iSocket ) 205void Bu::Server::closeClient( socket_t iSocket )
206{ 206{
207 Bu::Client *pClient = hClients.get( iSocket ); 207 Bu::Client *pClient = hClients.get( iSocket );
208 onClosedConnection( pClient ); 208 onClosedConnection( pClient );
209 pClient->close(); 209 pClient->close();
210 hClients.erase( iSocket ); 210 hClients.erase( iSocket );
211 FD_CLR( iSocket, &fdActive ); 211 FD_CLR( iSocket, &fdActive );
212 delete pClient; 212 delete pClient;
213} 213}
214 214