void SocketStreamHandle::platformClose() { LOG(Network, "SocketStreamHandle %p platformClose", this); if (m_pacRunLoopSource) removePACRunLoopSource(); ASSERT(!m_readStream == !m_writeStream); if (!m_readStream) { if (m_connectingSubstate == New || m_connectingSubstate == ExecutingPACFile) m_client->didCloseSocketStream(this); return; } #if PLATFORM(WIN) CFReadStreamUnscheduleFromRunLoop(m_readStream.get(), loaderRunLoop(), kCFRunLoopDefaultMode); CFWriteStreamUnscheduleFromRunLoop(m_writeStream.get(), loaderRunLoop(), kCFRunLoopDefaultMode); #else CFReadStreamUnscheduleFromRunLoop(m_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes); CFWriteStreamUnscheduleFromRunLoop(m_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes); #endif CFReadStreamClose(m_readStream.get()); CFWriteStreamClose(m_writeStream.get()); m_readStream = 0; m_writeStream = 0; m_client->didCloseSocketStream(this); }
/* MyStreamInfoDestroy destroys a MyStreamInfo 'object', cleaning up any resources that it owns. */ static void MyStreamInfoDestroy(MyStreamInfo * info) { assert(info != NULL); if (info->readStream) { CFReadStreamUnscheduleFromRunLoop(info->readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); (void) CFReadStreamSetClient(info->readStream, kCFStreamEventNone, NULL, NULL); /* CFReadStreamClose terminates the stream. */ CFReadStreamClose(info->readStream); CFRelease(info->readStream); } if (info->writeStream) { CFWriteStreamUnscheduleFromRunLoop(info->writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); (void) CFWriteStreamSetClient(info->writeStream, kCFStreamEventNone, NULL, NULL); /* CFWriteStreamClose terminates the stream. */ CFWriteStreamClose(info->writeStream); CFRelease(info->writeStream); } if (info->proxyDict) { CFRelease(info->proxyDict); // see discussion of <rdar://problem/3745574> below } free(info); }
static void CleanupAfterWAAN(MyStreamInfoPtr myInfoPtr) { assert(myInfoPtr != NULL); if (myInfoPtr->isClientSet) { CFWriteStreamSetClient(myInfoPtr->wStreamRef, 0, NULL, NULL); CFWriteStreamUnscheduleFromRunLoop(myInfoPtr->wStreamRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); myInfoPtr->isClientSet = FALSE; } }
/* extern */ void HttpContextClose(HttpContextRef context) { CFRunLoopRef runLoop = CFRunLoopGetCurrent(); // Check if the read stream exists. if (context->_inStream) { // Unschedule, close, and release it. CFReadStreamSetClient(context->_inStream, 0, NULL, NULL); CFReadStreamUnscheduleFromRunLoop(context->_inStream, runLoop, kCFRunLoopCommonModes); CFReadStreamClose(context->_inStream); CFRelease(context->_inStream); // Remove the reference. context->_inStream = NULL; } // Check if the write stream exists. if (context->_outStream) { // Unschedule, close, and release it. CFWriteStreamSetClient(context->_outStream, 0, NULL, NULL); CFWriteStreamUnscheduleFromRunLoop(context->_outStream, runLoop, kCFRunLoopCommonModes); CFWriteStreamClose(context->_outStream); CFRelease(context->_outStream); // Remove the reference. context->_outStream = NULL; } // Get rid of the timer, if it still exists if (context->_timer != NULL) { CFRunLoopTimerInvalidate(context->_timer); CFRelease(context->_timer); context->_timer = NULL; } }
void SocketStreamHandle::platformClose() { LOG(Network, "SocketStreamHandle %p platformClose", this); #ifndef BUILDING_ON_TIGER if (m_pacRunLoopSource) removePACRunLoopSource(); #endif ASSERT(!m_readStream == !m_writeStream); if (!m_readStream) return; CFReadStreamUnscheduleFromRunLoop(m_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes); CFWriteStreamUnscheduleFromRunLoop(m_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes); CFReadStreamClose(m_readStream.get()); CFWriteStreamClose(m_writeStream.get()); m_readStream = 0; m_writeStream = 0; m_client->didClose(this); }
static int wait_runloop(mailstream_low * s, int wait_state) { struct mailstream_cfstream_data * cfstream_data; int read_scheduled; int write_scheduled; int error; setup_runloop(s); cfstream_data = (struct mailstream_cfstream_data *) s->data; cfstream_data->state = wait_state; read_scheduled = 0; write_scheduled = 0; error = WAIT_RUNLOOP_EXIT_NO_ERROR; switch (wait_state) { case STATE_WAIT_OPEN: //fprintf(stderr, "wait open\n"); CFReadStreamScheduleWithRunLoop(cfstream_data->readStream, cfstream_data->runloop, kCFRunLoopDefaultMode); CFWriteStreamScheduleWithRunLoop(cfstream_data->writeStream, cfstream_data->runloop, kCFRunLoopDefaultMode); read_scheduled = 1; write_scheduled = 1; break; case STATE_WAIT_READ: //fprintf(stderr, "wait read\n"); CFReadStreamScheduleWithRunLoop(cfstream_data->readStream, cfstream_data->runloop, kCFRunLoopDefaultMode); read_scheduled = 1; break; case STATE_WAIT_WRITE: //fprintf(stderr, "wait write\n"); CFWriteStreamScheduleWithRunLoop(cfstream_data->writeStream, cfstream_data->runloop, kCFRunLoopDefaultMode); write_scheduled = 1; break; case STATE_WAIT_IDLE: //fprintf(stderr, "wait idle\n"); CFReadStreamScheduleWithRunLoop(cfstream_data->readStream, cfstream_data->runloop, kCFRunLoopDefaultMode); read_scheduled = 1; break; case STATE_WAIT_SSL: //fprintf(stderr, "wait ssl\n"); CFReadStreamScheduleWithRunLoop(cfstream_data->readStream, cfstream_data->runloop, kCFRunLoopDefaultMode); CFWriteStreamScheduleWithRunLoop(cfstream_data->writeStream, cfstream_data->runloop, kCFRunLoopDefaultMode); read_scheduled = 1; write_scheduled = 1; break; } if (read_scheduled) { if (CFReadStreamHasBytesAvailable(cfstream_data->readStream)) { readStreamCallback(cfstream_data->readStream, kCFStreamEventHasBytesAvailable, s); } } if (write_scheduled) { if (CFWriteStreamCanAcceptBytes(cfstream_data->writeStream)) { writeStreamCallback(cfstream_data->writeStream, kCFStreamEventCanAcceptBytes, s); } } while (1) { struct timeval timeout; CFTimeInterval delay; int r; int done; if (cfstream_data->cancelled) { error = WAIT_RUNLOOP_EXIT_CANCELLED; break; } if (cfstream_data->state == STATE_WAIT_IDLE) { if (cfstream_data->idleInterrupted) { error = WAIT_RUNLOOP_EXIT_INTERRUPTED; break; } } done = 0; switch (cfstream_data->state) { case STATE_OPEN_READ_DONE: CFReadStreamUnscheduleFromRunLoop(cfstream_data->readStream, cfstream_data->runloop, kCFRunLoopDefaultMode); read_scheduled = 0; break; case STATE_OPEN_WRITE_DONE: CFWriteStreamUnscheduleFromRunLoop(cfstream_data->writeStream, cfstream_data->runloop, kCFRunLoopDefaultMode); write_scheduled = 0; break; case STATE_OPEN_READ_WRITE_DONE: done = 1; break; case STATE_OPEN_WRITE_READ_DONE: done = 1; break; case STATE_READ_DONE: done = 1; break; case STATE_WRITE_DONE: done = 1; break; case STATE_IDLE_DONE: done = 1; break; case STATE_SSL_READ_DONE: done = 1; break; case STATE_SSL_WRITE_DONE: done = 1; break; case STATE_SSL_READ_WRITE_DONE: done = 1; break; case STATE_SSL_WRITE_READ_DONE: done = 1; break; } if (done) { break; } if (wait_state == STATE_WAIT_IDLE) { timeout.tv_sec = cfstream_data->idleMaxDelay; timeout.tv_usec = 0; } else { if (s->timeout == 0) { timeout = mailstream_network_delay; } else { timeout.tv_sec = s->timeout; timeout.tv_usec = 0; } } delay = (CFTimeInterval) timeout.tv_sec + (CFTimeInterval) timeout.tv_usec / (CFTimeInterval) 1e6; r = CFRunLoopRunInMode(kCFRunLoopDefaultMode, delay, true); if (r == kCFRunLoopRunTimedOut) { error = WAIT_RUNLOOP_EXIT_TIMEOUT; break; } } if (read_scheduled) { CFReadStreamUnscheduleFromRunLoop(cfstream_data->readStream, cfstream_data->runloop, kCFRunLoopDefaultMode); } if (write_scheduled) { CFWriteStreamUnscheduleFromRunLoop(cfstream_data->writeStream, cfstream_data->runloop, kCFRunLoopDefaultMode); } unsetup_runloop(s); if (error != WAIT_RUNLOOP_EXIT_NO_ERROR) return error; return WAIT_RUNLOOP_EXIT_NO_ERROR; }
/*=== Main thread */ void *tnet_transport_mainthread(void *param) { tnet_transport_t *transport = param; transport_context_t *context = transport->context; int i; /* check whether the transport is already prepared */ if (!transport->prepared) { TSK_DEBUG_ERROR("Transport must be prepared before strating."); goto bail; } TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d}...", transport->description, transport->master->ip, transport->master->port); // Set the RunLoop of the context context->cf_run_loop = CFRunLoopGetCurrent(); while(TSK_RUNNABLE(transport)->running) { // Check if new socket were added and wrap them. // We go backward as new socket are always added at the end. for(i = context->count - 1; i >= 0; i--) { if (tnet_transport_wrap(transport, i)) { break; } } // Give some time to process sources CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); if (!TSK_RUNNABLE(transport)->running) { goto bail; } } // Remove all the sockets, streams and sources from the run loop for(i = 0; i < context->count; i++) { transport_context_t *context = transport->context; transport_socket_t *sock = context->sockets[i]; if (sock) { continue; } if (sock->cf_run_loop_source) { CFRunLoopRemoveSource(context->cf_run_loop, sock->cf_run_loop_source, kCFRunLoopDefaultMode); } if (sock->cf_read_stream) { //CFReadStreamClose(sock->cf_read_stream); CFReadStreamUnscheduleFromRunLoop(sock->cf_read_stream, context->cf_run_loop, kCFRunLoopDefaultMode); } if (sock->cf_write_stream) { //CFWriteStreamClose(sock->cf_write_stream); CFWriteStreamUnscheduleFromRunLoop(sock->cf_write_stream, context->cf_run_loop, kCFRunLoopDefaultMode); } } bail: TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d}...", transport->description, transport->master->ip, transport->master->port); return 0; }