diff -r 09bcdcd78379 -r 86984c1034a5 project_files/Android-build/SDL-android-project/jni/sdl_net/SDLnetselect.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/jni/sdl_net/SDLnetselect.c Thu Jun 23 14:30:04 2011 +0200 @@ -0,0 +1,226 @@ +/* + SDL_net: An example cross-platform network library for use with SDL + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* $Id: SDLnetselect.c 1192 2004-01-04 17:41:55Z slouken $ */ + +#include "SDLnetsys.h" +#include "SDL_net.h" + +/* The select() API for network sockets */ + +struct SDLNet_Socket { + int ready; + SOCKET channel; +#ifdef MACOS_OPENTRANSPORT + OTEventCode curEvent; +#endif +}; + +struct _SDLNet_SocketSet { + int numsockets; + int maxsockets; + struct SDLNet_Socket **sockets; +}; + +/* Allocate a socket set for use with SDLNet_CheckSockets() + This returns a socket set for up to 'maxsockets' sockets, or NULL if + the function ran out of memory. + */ +SDLNet_SocketSet SDLNet_AllocSocketSet(int maxsockets) +{ + struct _SDLNet_SocketSet *set; + int i; + + set = (struct _SDLNet_SocketSet *)malloc(sizeof(*set)); + if ( set != NULL ) { + set->numsockets = 0; + set->maxsockets = maxsockets; + set->sockets = (struct SDLNet_Socket **)malloc + (maxsockets*sizeof(*set->sockets)); + if ( set->sockets != NULL ) { + for ( i=0; isockets[i] = NULL; + } + } else { + free(set); + set = NULL; + } + } + return(set); +} + +/* Add a socket to a set of sockets to be checked for available data */ +int SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock) +{ + if ( sock != NULL ) { + if ( set->numsockets == set->maxsockets ) { + SDLNet_SetError("socketset is full"); + return(-1); + } + set->sockets[set->numsockets++] = (struct SDLNet_Socket *)sock; + } + return(set->numsockets); +} + +/* Remove a socket from a set of sockets to be checked for available data */ +int SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock) +{ + int i; + + if ( sock != NULL ) { + for ( i=0; inumsockets; ++i ) { + if ( set->sockets[i] == (struct SDLNet_Socket *)sock ) { + break; + } + } + if ( i == set->numsockets ) { + SDLNet_SetError("socket not found in socketset"); + return(-1); + } + --set->numsockets; + for ( ; inumsockets; ++i ) { + set->sockets[i] = set->sockets[i+1]; + } + } + return(set->numsockets); +} + +/* This function checks to see if data is available for reading on the + given set of sockets. If 'timeout' is 0, it performs a quick poll, + otherwise the function returns when either data is available for + reading, or the timeout in milliseconds has elapsed, which ever occurs + first. This function returns the number of sockets ready for reading, + or -1 if there was an error with the select() system call. +*/ +#ifdef MACOS_OPENTRANSPORT +int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout) +{ +Uint32 stop; +int numReady; + + /* Loop, polling the network devices */ + + stop = SDL_GetTicks() + timeout; + + do + { + OTResult status; + size_t numBytes; + int i; + + numReady = 0; + + for (i = set->numsockets-1;i >= 0;--i) + { + status = OTLook( set->sockets[i]->channel ); + if( status > 0 ) + { + switch( status ) + { + case T_UDERR: + OTRcvUDErr( set->sockets[i]->channel , nil); + break; + case T_DISCONNECT: + OTRcvDisconnect( set->sockets[i]->channel, nil ); + break; + case T_ORDREL: + OTRcvOrderlyDisconnect(set->sockets[i]->channel ); + break; + case T_CONNECT: + OTRcvConnect( set->sockets[i]->channel, nil ); + break; + + + default: + set->sockets[i]->ready = 1; + ++numReady; + } + } + else if( OTCountDataBytes(set->sockets[i]->channel, &numBytes ) != kOTNoDataErr ) + { + set->sockets[i]->ready = 1; + ++numReady; + } + else + set->sockets[i]->ready = 0; + } + + } while (!numReady && (SDL_GetTicks() < stop)); + + return(numReady); +} +#else +int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout) +{ + int i; + SOCKET maxfd; + int retval; + struct timeval tv; + fd_set mask; + + /* Find the largest file descriptor */ + maxfd = 0; + for ( i=set->numsockets-1; i>=0; --i ) { + if ( set->sockets[i]->channel > maxfd ) { + maxfd = set->sockets[i]->channel; + } + } + + /* Check the file descriptors for available data */ + do { + errno = 0; + + /* Set up the mask of file descriptors */ + FD_ZERO(&mask); + for ( i=set->numsockets-1; i>=0; --i ) { + FD_SET(set->sockets[i]->channel, &mask); + } + + /* Set up the timeout */ + tv.tv_sec = timeout/1000; + tv.tv_usec = (timeout%1000)*1000; + + /* Look! */ + retval = select(maxfd+1, &mask, NULL, NULL, &tv); + } while ( errno == EINTR ); + + /* Mark all file descriptors ready that have data available */ + if ( retval > 0 ) { + for ( i=set->numsockets-1; i>=0; --i ) { + if ( FD_ISSET(set->sockets[i]->channel, &mask) ) { + set->sockets[i]->ready = 1; + } + } + } + return(retval); +} +#endif /* MACOS_OPENTRANSPORT */ + +/* Free a set of sockets allocated by SDL_NetAllocSocketSet() */ +extern void SDLNet_FreeSocketSet(SDLNet_SocketSet set) +{ + if ( set ) { + free(set->sockets); + free(set); + } +} +