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"
38 #include <simgear/debug/logstream.hxx>
42 static NetChannel* channels = 0 ;
44 NetChannel::NetChannel ()
49 write_blocked = false ;
50 should_delete = false ;
52 next_channel = channels ;
56 NetChannel::~NetChannel ()
60 NetChannel* prev = NULL ;
62 for ( NetChannel* ch = channels; ch != NULL;
63 ch = ch -> next_channel )
67 ch = ch -> next_channel ;
69 prev -> next_channel = ch ;
80 NetChannel::setHandle (int handle, bool is_connected)
83 Socket::setHandle ( handle ) ;
84 connected = is_connected ;
85 //if ( connected ) this->handleConnect();
90 NetChannel::open (void)
93 if (Socket::open(true)) {
95 setBlocking ( false ) ;
102 NetChannel::listen ( int backlog )
105 return Socket::listen ( backlog ) ;
109 NetChannel::connect ( const char* host, int port )
111 int result = Socket::connect ( host, port ) ;
114 //this->handleConnect();
116 } else if (isNonBlockingError ()) {
119 // some other error condition
120 this->handleError (result);
127 NetChannel::send (const void * buffer, int size, int flags)
129 int result = Socket::send (buffer, size, flags);
131 if (result == (int)size) {
132 // everything was sent
133 write_blocked = false ;
135 } else if (result >= 0) {
136 // not all of it was sent, but no error
137 write_blocked = true ;
139 } else if (isNonBlockingError ()) {
140 write_blocked = true ;
143 this->handleError (result);
151 NetChannel::recv (void * buffer, int size, int flags)
153 int result = Socket::recv (buffer, size, flags);
157 } else if (result == 0) {
160 } else if (isNonBlockingError ()) {
163 this->handleError (result);
170 NetChannel::close (void)
179 write_blocked = false ;
186 NetChannel::handleReadEvent (void)
191 //this->handleConnect();
193 this->handleAccept();
194 } else if (!connected) {
196 //this->handleConnect();
204 NetChannel::handleWriteEvent (void)
208 //this->handleConnect();
210 write_blocked = false ;
215 NetChannel::poll (unsigned int timeout)
220 enum { MAX_SOCKETS = 256 } ;
221 Socket* reads [ MAX_SOCKETS+1 ] ;
222 Socket* writes [ MAX_SOCKETS+1 ] ;
223 Socket* deletes [ MAX_SOCKETS+1 ] ;
229 for ( ch = channels; ch != NULL; ch = ch -> next_channel )
231 if ( ch -> should_delete )
233 assert(ndeletes<MAX_SOCKETS);
234 deletes[ndeletes++] = ch ;
236 else if ( ! ch -> closed )
239 if (ch -> readable()) {
240 assert(nreads<MAX_SOCKETS);
241 reads[nreads++] = ch ;
243 if (ch -> writable()) {
244 assert(nwrites<MAX_SOCKETS);
245 writes[nwrites++] = ch ;
249 reads[nreads] = NULL ;
250 writes[nwrites] = NULL ;
251 deletes[ndeletes] = NULL ;
254 for ( i=0; deletes[i]; i++ )
256 ch = (NetChannel*)deletes[i];
262 if (!nreads && !nwrites)
263 return true ; //hmmm- should we shutdown?
265 Socket::select (reads, writes, timeout) ;
267 for ( i=0; reads[i]; i++ )
269 ch = (NetChannel*)reads[i];
270 if ( ! ch -> closed )
271 ch -> handleReadEvent();
274 for ( i=0; writes[i]; i++ )
276 ch = (NetChannel*)writes[i];
277 if ( ! ch -> closed )
278 ch -> handleWriteEvent();
285 NetChannel::loop (unsigned int timeout)
287 while ( poll (timeout) ) ;
291 void NetChannel::handleRead (void) {
292 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled read");
295 void NetChannel::handleWrite (void) {
296 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled write");
299 void NetChannel::handleAccept (void) {
300 SG_LOG(SG_IO, SG_WARN, "Network:" << getHandle() << ": unhandled accept");
303 void NetChannel::handleError (int error) {
304 SG_LOG(SG_IO, SG_WARN,"Network:" << getHandle() << ": errno: " << strerror(errno) <<"(" << errno << ")");
307 } // of namespace simgear