2 Copied from PLIB into SimGear
4 PLIB - A Suite of Portable Game Libraries
5 Copyright (C) 1998,2002 Steve Baker
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 For further information visit http://plib.sourceforge.net
23 $Id: netChannel.cxx 1906 2004-03-22 19:44:50Z sjbaker $
27 // have all socket-related functions assert that the socket has not
28 // been closed. [a read event may close it, and a write event may try
29 // to write or something...]
30 // Maybe assert valid handle, too?
32 #include "sg_netChannel.hxx"
39 #include <simgear/debug/logstream.hxx>
43 static NetChannel* channels = 0 ;
45 NetChannel::NetChannel ()
50 write_blocked = false ;
51 should_delete = false ;
53 next_channel = channels ;
57 NetChannel::~NetChannel ()
61 NetChannel* prev = NULL ;
63 for ( NetChannel* ch = channels; ch != NULL;
64 ch = ch -> next_channel )
68 ch = ch -> next_channel ;
70 prev -> next_channel = ch ;
81 NetChannel::setHandle (int handle, bool is_connected)
84 Socket::setHandle ( handle ) ;
85 connected = is_connected ;
86 //if ( connected ) this->handleConnect();
91 NetChannel::open (void)
94 if (Socket::open(true)) {
96 setBlocking ( false ) ;
103 NetChannel::listen ( int backlog )
106 return Socket::listen ( backlog ) ;
110 NetChannel::connect ( const char* host, int port )
112 int result = Socket::connect ( host, port ) ;
115 //this->handleConnect();
117 } else if (isNonBlockingError ()) {
120 // some other error condition
121 this->handleError (result);
128 NetChannel::send (const void * buffer, int size, int flags)
130 int result = Socket::send (buffer, size, flags);
132 if (result == (int)size) {
133 // everything was sent
134 write_blocked = false ;
136 } else if (result >= 0) {
137 // not all of it was sent, but no error
138 write_blocked = true ;
140 } else if (isNonBlockingError ()) {
141 write_blocked = true ;
144 this->handleError (result);
152 NetChannel::recv (void * buffer, int size, int flags)
154 int result = Socket::recv (buffer, size, flags);
158 } else if (result == 0) {
161 } else if (isNonBlockingError ()) {
164 this->handleError (result);
171 NetChannel::close (void)
180 write_blocked = false ;
187 NetChannel::handleReadEvent (void)
192 //this->handleConnect();
194 this->handleAccept();
195 } else if (!connected) {
197 //this->handleConnect();
205 NetChannel::handleWriteEvent (void)
209 //this->handleConnect();
211 write_blocked = false ;
216 NetChannel::poll (unsigned int timeout)
221 enum { MAX_SOCKETS = 256 } ;
222 Socket* reads [ MAX_SOCKETS+1 ] ;
223 Socket* writes [ MAX_SOCKETS+1 ] ;
224 Socket* deletes [ MAX_SOCKETS+1 ] ;
230 for ( ch = channels; ch != NULL; ch = ch -> next_channel )
232 if ( ch -> should_delete )
234 assert(ndeletes<MAX_SOCKETS);
235 deletes[ndeletes++] = ch ;
237 else if ( ! ch -> closed )
240 if (ch -> readable()) {
241 assert(nreads<MAX_SOCKETS);
242 reads[nreads++] = ch ;
244 if (ch -> writable()) {
245 assert(nwrites<MAX_SOCKETS);
246 writes[nwrites++] = ch ;
250 reads[nreads] = NULL ;
251 writes[nwrites] = NULL ;
252 deletes[ndeletes] = NULL ;
255 for ( i=0; deletes[i]; i++ )
257 ch = (NetChannel*)deletes[i];
263 if (!nreads && !nwrites)
264 return true ; //hmmm- should we shutdown?
266 Socket::select (reads, writes, timeout) ;
268 for ( i=0; reads[i]; i++ )
270 ch = (NetChannel*)reads[i];
271 if ( ! ch -> closed )
272 ch -> handleReadEvent();
275 for ( i=0; writes[i]; i++ )
277 ch = (NetChannel*)writes[i];
278 if ( ! ch -> closed )
279 ch -> handleWriteEvent();
286 NetChannel::loop (unsigned int timeout)
288 while ( poll (timeout) ) ;
292 void NetChannel::handleRead (void) {
293 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled read");
296 void NetChannel::handleWrite (void) {
297 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled write");
300 void NetChannel::handleAccept (void) {
301 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled accept");
304 void NetChannel::handleError (int error) {
305 SG_LOG(SG_IO, SG_WARN,"Network:" << getHandle() << ": errno: " << strerror(errno) <<"(" << errno << ")");
308 } // of namespace simgear