diff options
Diffstat (limited to '')
-rw-r--r-- | src/stable/server.cpp | 252 |
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 | ||
16 | Bu::Server::Server() : | 16 | Bu::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 | ||
24 | Bu::Server::~Server() | 24 | Bu::Server::~Server() |
25 | { | 25 | { |
26 | shutdown(); | 26 | shutdown(); |
27 | } | 27 | } |
28 | 28 | ||
29 | void Bu::Server::addPort( int nPort, int nPoolSize ) | 29 | void 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 | ||
37 | void Bu::Server::addPort( const String &sAddr, int nPort, int nPoolSize ) | 37 | void 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 | ||
45 | void Bu::Server::setTimeout( int nTimeoutSec, int nTimeoutUSec ) | 45 | void 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 | ||
51 | void Bu::Server::scan() | 51 | void 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 | ||
134 | void Bu::Server::addClient( socket_t nSocket, int nPort ) | 134 | void 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 | ||
147 | Bu::Server::SrvClientLink::SrvClientLink( Bu::Client *pClient ) : | 147 | Bu::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 | ||
156 | void Bu::Server::SrvClientLink::sendMessage( const Bu::String &sMsg ) | 156 | void Bu::Server::SrvClientLink::sendMessage( const Bu::String &sMsg ) |
157 | { | 157 | { |
158 | pClient->onMessage( sMsg ); | 158 | pClient->onMessage( sMsg ); |
159 | } | 159 | } |
160 | 160 | ||
161 | Bu::Server::SrvClientLinkFactory::SrvClientLinkFactory() | 161 | Bu::Server::SrvClientLinkFactory::SrvClientLinkFactory() |
@@ -167,48 +167,48 @@ Bu::Server::SrvClientLinkFactory::~SrvClientLinkFactory() | |||
167 | } | 167 | } |
168 | 168 | ||
169 | Bu::ClientLink *Bu::Server::SrvClientLinkFactory::createLink( | 169 | Bu::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 | ||
175 | void Bu::Server::setAutoTick( bool bEnable ) | 175 | void Bu::Server::setAutoTick( bool bEnable ) |
176 | { | 176 | { |
177 | bAutoTick = bEnable; | 177 | bAutoTick = bEnable; |
178 | } | 178 | } |
179 | 179 | ||
180 | void Bu::Server::tick() | 180 | void 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 | ||
188 | void Bu::Server::shutdown() | 188 | void 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 | ||
205 | void Bu::Server::closeClient( socket_t iSocket ) | 205 | void 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 | ||