/* GSocket_Shutdown: * Disallow further read/write operations on this socket, close * the fd and disable all callbacks. */ void GSocket_Shutdown(GSocket *socket) { OSStatus err ; int evt; assert(socket != NULL); /* If socket has been created, shutdown it */ if (socket->m_endpoint != kOTInvalidEndpointRef ) { err = OTSndOrderlyDisconnect( socket->m_endpoint ) ; if ( err != kOTNoError ) { } err = OTRcvOrderlyDisconnect( socket->m_endpoint ) ; err = OTUnbind( socket->m_endpoint ) ; err = OTCloseProvider( socket->m_endpoint ) ; socket->m_endpoint = kOTInvalidEndpointRef ; } /* Disable GUI callbacks */ for (evt = 0; evt < GSOCK_MAX_EVENT; evt++) socket->m_cbacks[evt] = NULL; socket->m_detected = 0; _GSocket_Disable_Events(socket); wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , socket ) ; }
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); }
// This function is taken from GUSI interface. // ( 01/02/19 masahiro minami<*****@*****.**> ) static void AsyncTCPPopEvent( TCPsocket sock ) { // Make sure OT calls are not interrupted // Not sure if we really need this. OTEnterNotifier( sock->channel ); sock->event |= (sock->curEvent = sock->newEvent ); sock->completion |= ( sock->curCompletion = sock->newCompletion ); sock->newEvent = sock->newCompletion = 0; OTLeaveNotifier( sock->channel ); if( sock->curEvent & T_UDERR) { // We just clear the error. // Should we feed this back to users ? // (TODO ) OTRcvUDErr( sock->channel, NULL ); #ifdef DEBUG_NET printf("AsyncTCPPopEvent T_UDERR recognized"); #endif } // Remote is disconnecting... if( sock->curEvent & ( T_DISCONNECT | T_ORDREL )) { sock->readShutdown = true; } if( sock->curEvent &T_CONNECT ) { // Ignore the info of remote (second parameter). // Shoule we care ? // (TODO) OTRcvConnect( sock->channel, NULL ); sock->connected = 1; } if( sock->curEvent & T_ORDREL ) { OTRcvOrderlyDisconnect( sock->channel ); } if( sock->curEvent & T_DISCONNECT ) { OTRcvDisconnect( sock->channel, NULL ); } // Do we need to ? // (masahiro minami<*****@*****.**>) //YieldToAnyThread(); }
static PRBool GetState(EndpointRef endpoint, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady) { OSStatus err; OTResult resultOT; TDiscon discon; PRBool result = PR_FALSE; *readReady = *writeReady = *exceptReady = PR_FALSE; resultOT = OTLook(endpoint); switch (resultOT) { case T_DATA: case T_LISTEN: *readReady = PR_TRUE; break; case T_CONNECT: err = OTRcvConnect(endpoint, NULL); PR_ASSERT(err == kOTNoError); break; case T_DISCONNECT: memset(&discon, 0 , sizeof(discon)); err = OTRcvDisconnect(endpoint, &discon); PR_ASSERT(err == kOTNoError); macsock_map_error(discon.reason); *exceptReady = PR_TRUE; break; case T_ORDREL: *readReady = PR_TRUE; err = OTRcvOrderlyDisconnect(endpoint); PR_ASSERT(err == kOTNoError); break; } resultOT = OTGetEndpointState(endpoint); switch (resultOT) { case T_DATAXFER: case T_INREL: *writeReady = PR_TRUE; break; default: *writeReady = PR_FALSE; } if ((*readReady == PR_TRUE) || (*writeReady==PR_TRUE) || (*exceptReady==PR_TRUE)) result = PR_TRUE; return result; }
pascal void OTTCPNotifier(void* vobj, OTEventCode code, OTResult result, void* cookie) { OTTCP *x = (OTTCP *) vobj; long oldA5; OSStatus s; EnterCallback(); oldA5 = SetA5(x->o_a5); post("*** OTTCPNotifier(code %x, result %ld)", (long) code, (long) result); if (code == T_OPENCOMPLETE) { if (result != noErr) { post("OTTCPNotifier got a T_OPENCOMPLETE code with error %ld", result); } // Even if we got an error, we'll use the endpoint. x->o_tcp_ep = (EndpointRef) cookie; if (x->o_inetHostName != 0) { BindTheEndpoint(x); // Now we expect a T_BINDCOMPLETE message. } } else if (code == T_BINDCOMPLETE) { TCall sndCall; InetAddress inAddr; // See what ephemeral port number OT gave us x->o_receiveInetPort = x->o_addrWeActuallyGot.fPort; // Now the endpoint has been bound; next trick is connecting OTInitInetAddress(&inAddr, x->o_inetPort, x->o_inetHost); OTMemzero(&sndCall, sizeof(TCall)); sndCall.addr.buf = (void *) &inAddr; sndCall.addr.len = sizeof(InetAddress); post("** About to OTConnect"); s = OTConnect(x->o_tcp_ep, &sndCall, NULL); if (s == kOTNoDataErr) { // No problem; that means connection is in progress post("** OTConnect returned kOTNoDataErr - good"); } else { post("е OTTCP: error: OTConnect returned %ld; not connecting.", s); } // Now we expect T_CONNECT } else if (code == T_CONNECT) { if (result == kOTBadAddressErr) { post("е OTTCP: error: bad address. Disconnecting"); x->o_inetHost = 0; change_connection(x); } else { post("** Got T_CONNECT"); post("** Result passed to notifier: %ld", (long) result); post("** Endpoint state before OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep)); // We could pass in buffers to find out the actual address we connected to, etc. s = OTRcvConnect(x->o_tcp_ep, nil); if (s != kOTNoError) { post("е OTTCP: error: RcvConnect returned %ld", s); } post("** Endpoint state after OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep)); ChangeState(x, NO_REQUEST); x->o_connectionSymbol = ps_connected; clock_delay(x->o_connectedclock, 0); } } else if (code == T_UNBINDCOMPLETE) { // If we have a new inetHost, try to bind it if (x->o_inetHost != 0) { BindTheEndpoint(x); // Now we expect T_BINDCOMPLETE } else { // No inetHost, so we're disonnected x->o_connectionSymbol = ps_disconnected; clock_delay(x->o_connectedclock, 0); } } else if (code == T_DISCONNECTCOMPLETE) { // We always want to rebind when we reconnect, so after disconnecting we unbind s = OTUnbind(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTUnbind returned %ld", s); } } else if (code == T_DATA) { ottcp_handleIncomingData(x); } else if (code == T_UDERR) { if (x->o_errorreporting) { PostUDERR("OTTCPNotifier was called for a T_UDERR code", x->o_tcp_ep); } else { /* We still have to receive the error to clear the condition */ OTRcvUDErr(x->o_tcp_ep, 0); } } else if (code == T_GODATA) { // Flow control restriction has lifted; now it's OK to send more data. do_write(x, 0, 0); } else if (code == T_DISCONNECT) { // The other dude wants to disconnect post("OTTCP: peer wants to disconnect"); s = OTRcvDisconnect(x->o_tcp_ep, NULL); if (s == kOTNoError) { x->o_inetHost = 0; change_connection(x); } else if (s == kOTNoDisconnectErr) { // false alarm } else { post("е OTTCP: error: OTRcvDisconnect returned %ld", s); } } else if (code == T_ORDREL) { post("*** Got T_ORDREL"); s = OTRcvOrderlyDisconnect(x->o_tcp_ep); if (s == kOTNoReleaseErr) { post("...false alarm!"); } else if (s == kOTNoError) { x->o_inetHost = 0; change_connection(x); } else { post("е OTTCP: error: OTRcvOrderlyDisconnect returned %ld", s); } } else { if (x->o_errorreporting) { post("OTTCP: Unrecognized OTEventCode %ld in event handler. Oh well.", (long) code); } } done: SetA5(oldA5); ExitCallback(); }