aboutsummaryrefslogtreecommitdiff
path: root/src/itoserver.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2007-09-11 04:05:26 +0000
committerMike Buland <eichlan@xagasoft.com>2007-09-11 04:05:26 +0000
commitc82dc43edc9fd913e8ddb20bebe778781ec0d6f7 (patch)
tree101382ab930a2fa895a0ca3ea9e781ac71a1a625 /src/itoserver.cpp
parentace50b182f318b96a87505aa3d6b509959d49544 (diff)
downloadlibbu++-c82dc43edc9fd913e8ddb20bebe778781ec0d6f7.tar.gz
libbu++-c82dc43edc9fd913e8ddb20bebe778781ec0d6f7.tar.bz2
libbu++-c82dc43edc9fd913e8ddb20bebe778781ec0d6f7.tar.xz
libbu++-c82dc43edc9fd913e8ddb20bebe778781ec0d6f7.zip
Everything seems to work with the new Bu::ItoServer class, it operates very,
very similarly to the Bu::Server class, except that every incoming connection gets it's own thread. This functionality may have to be tuned later, to allow for maintaining a pool of connections as an option, but this is fine for now.
Diffstat (limited to 'src/itoserver.cpp')
-rw-r--r--src/itoserver.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/itoserver.cpp b/src/itoserver.cpp
new file mode 100644
index 0000000..0337057
--- /dev/null
+++ b/src/itoserver.cpp
@@ -0,0 +1,178 @@
1#include "bu/itoserver.h"
2#include <errno.h>
3#include "bu/serversocket.h"
4#include "bu/client.h"
5#include "bu/socket.h"
6#include "osx_compatibility.h"
7
8Bu::ItoServer::ItoServer() :
9 nTimeoutSec( 1 ),
10 nTimeoutUSec( 0 )
11{
12 FD_ZERO( &fdActive );
13}
14
15Bu::ItoServer::~ItoServer()
16{
17}
18
19void Bu::ItoServer::addPort( int nPort, int nPoolSize )
20{
21 ServerSocket *s = new ServerSocket( nPort, nPoolSize );
22 int nSocket = s->getSocket();
23 FD_SET( nSocket, &fdActive );
24 hServers.insert( nSocket, s );
25}
26
27void Bu::ItoServer::addPort( const FString &sAddr, int nPort, int nPoolSize )
28{
29 ServerSocket *s = new ServerSocket( sAddr, nPort, nPoolSize );
30 int nSocket = s->getSocket();
31 FD_SET( nSocket, &fdActive );
32 hServers.insert( nSocket, s );
33}
34
35void Bu::ItoServer::setTimeout( int nTimeoutSec, int nTimeoutUSec )
36{
37 this->nTimeoutSec = nTimeoutSec;
38 this->nTimeoutUSec = nTimeoutUSec;
39}
40/*
41void Bu::ItoServer::scan()
42{
43 struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec };
44
45 fd_set fdRead = fdActive;
46 fd_set fdWrite = fdActive;
47 fd_set fdException = fdActive;
48
49 if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, &fdRead, NULL, &fdException, &xTimeout ) ) < 0 )
50 {
51 throw ExceptionBase("Error attempting to scan open connections.");
52 }
53
54 for( int j = 0; j < FD_SETSIZE; j++ )
55 {
56 if( FD_ISSET( j, &fdRead ) )
57 {
58 if( hServers.has( j ) )
59 {
60 ServerSocket *pSrv = hServers.get( j );
61 addClient( pSrv->accept(), pSrv->getPort() );
62 }
63 else
64 {
65 Client *pClient = hClients.get( j );
66 pClient->processInput();
67 if( !pClient->isOpen() )
68 {
69 onClosedConnection( pClient );
70 hClients.erase( j );
71 FD_CLR( j, &fdActive );
72 }
73 }
74 }
75 }
76
77 // Now we just try to write all the pending data on all the sockets.
78 // this could be done better eventually, if we care about the socket
79 // wanting to accept writes (using a select).
80 for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ )
81 {
82 (*i)->processOutput();
83 }
84}
85*/
86void Bu::ItoServer::addClient( int nSocket, int nPort )
87{
88 ItoClient *pC = new ItoClient( *this, nSocket, nPort, nTimeoutSec,
89 nTimeoutUSec );
90 pC->start();
91
92}
93
94void *Bu::ItoServer::run()
95{
96 for(;;)
97 {
98 struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec };
99
100 fd_set fdRead = fdActive;
101 fd_set fdWrite = fdActive;
102 fd_set fdException = fdActive;
103
104 if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, &fdRead, NULL, &fdException, &xTimeout ) ) < 0 )
105 {
106 throw ExceptionBase("Error attempting to scan open connections.");
107 }
108
109 for( ServerHash::iterator i = hServers.begin(); i != hServers.end(); i++ )
110 {
111 if( FD_ISSET( i.getKey(), &fdRead ) )
112 {
113 ServerSocket *pSrv = i.getValue();
114 addClient( pSrv->accept(), pSrv->getPort() );
115 }
116 }
117 }
118
119 return NULL;
120}
121
122Bu::ItoServer::ItoClient::ItoClient( ItoServer &rSrv, int iSocket, int iPort,
123 int nTimeoutSec, int nTimeoutUSec ) :
124 rSrv( rSrv ),
125 iSocket( iSocket ),
126 iPort( iPort ),
127 nTimeoutSec( nTimeoutSec ),
128 nTimeoutUSec( nTimeoutUSec )
129{
130 FD_ZERO( &fdActive );
131 FD_SET( iSocket, &fdActive );
132
133 pClient = new Client(
134 new Bu::Socket( iSocket )
135 );
136
137}
138
139Bu::ItoServer::ItoClient::~ItoClient()
140{
141}
142
143void *Bu::ItoServer::ItoClient::run()
144{
145 rSrv.onNewConnection( pClient, iPort );
146
147 for(;;)
148 {
149 struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec };
150
151 fd_set fdRead = fdActive;
152 fd_set fdException = fdActive;
153
154 if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, &fdRead, NULL, &fdException, &xTimeout ) ) < 0 )
155 {
156 throw ExceptionBase("Error attempting to scan open connections.");
157 }
158
159 if( FD_ISSET( iSocket, &fdRead ) )
160 {
161 pClient->processInput();
162 if( !pClient->isOpen() )
163 {
164 rSrv.onClosedConnection( pClient );
165
166 return NULL;
167 }
168 }
169
170 // Now we just try to write all the pending data on the socket.
171 // this could be done better eventually, if we care about the socket
172 // wanting to accept writes (using a select).
173 pClient->processOutput();
174 }
175
176 return NULL;
177}
178