/* Removes the loop source for the given socket from the current run loop. */ void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop) { Q_ASSERT(runloop); CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runloop, kCFRunLoopCommonModes); CFSocketDisableCallBacks(socket, kCFSocketReadCallBack); CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack); CFRunLoopSourceInvalidate(runloop); }
/* Unregister QSocketNotifer. The CFSocket correspoding to this notifier is removed from the runloop of this is the last notifier that users that CFSocket. */ void QEventDispatcherMac::unregisterSocketNotifier(QSocketNotifier *notifier) { Q_ASSERT(notifier); int nativeSocket = notifier->socket(); int type = notifier->type(); #ifndef QT_NO_DEBUG if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { qWarning("QSocketNotifier: Internal error"); return; } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) { qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); return; } #endif Q_D(QEventDispatcherMac); QEventDispatcherUNIX::unregisterSocketNotifier(notifier); if (type == QSocketNotifier::Exception) { qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); return; } MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); if (!socketInfo) { qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier"); return; } // Decrement read/write counters and disable callbacks if necessary. if (type == QSocketNotifier::Read) { if (--socketInfo->read == 0) CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); } else if (type == QSocketNotifier::Write) { if (--socketInfo->write == 0) CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); } // Remove CFSocket from runloop if this was the last QSocketNotifier. if (socketInfo->read <= 0 && socketInfo->write <= 0) { if (CFSocketIsValid(socketInfo->socket)) qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); CFRunLoopSourceInvalidate(socketInfo->runloop); CFRelease(socketInfo->runloop); CFSocketInvalidate(socketInfo->socket); CFRelease(socketInfo->socket); delete socketInfo; d->macSockets.remove(nativeSocket); } }
void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket, GSocketEvent event) { int c; struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket); if (!data) return; switch (event) { case GSOCK_CONNECTION: if(socket->m_server) c = kCFSocketReadCallBack; else c = kCFSocketConnectCallBack; break; case GSOCK_LOST: case GSOCK_INPUT: c = kCFSocketReadCallBack; break; case GSOCK_OUTPUT: c = kCFSocketWriteCallBack; break; default: c = 0; } CFSocketDisableCallBacks(data->socket, c); }
void wxSocketManagerMac::Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event) { wxSocketImplMac * const socket = static_cast<wxSocketImplMac *>(socket_); CFSocketDisableCallBacks(socket->GetSocket(), GetCFCallback(socket, event)); }
static int _cf_runloop_clear_write( void * info, int fd ) { struct CFMIDIRunloop * runloop = info; CFSocketRef socket; MIDIAssert( runloop != NULL ); socket = CFSocketCreateWithNative( NULL, fd, kCFSocketWriteCallBack, &_cf_socket_callback, &(runloop->socket_context) ); CFSocketDisableCallBacks( socket, kCFSocketWriteCallBack ); CFRelease( socket ); return 0; }
static void xmmsc_io_cf_toggle_socket_flags (int toggle, void *userdata) { CFSocketRef sockRef = (CFSocketRef) userdata; if (toggle) CFSocketEnableCallBacks (sockRef, kCFSocketWriteCallBack); else CFSocketDisableCallBacks (sockRef, kCFSocketWriteCallBack); }
/* Register a QSocketNotifier with the mac event system by creating a CFSocket with with a read/write callback. Qt has separate socket notifiers for reading and writing, but on the mac there is a limitation of one CFSocket object for each native socket. */ void QEventDispatcherMac::registerSocketNotifier(QSocketNotifier *notifier) { Q_ASSERT(notifier); int nativeSocket = notifier->socket(); int type = notifier->type(); #ifndef QT_NO_DEBUG if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { qWarning("QSocketNotifier: Internal error"); return; } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) { qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); return; } #endif Q_D(QEventDispatcherMac); QEventDispatcherUNIX::registerSocketNotifier(notifier); if (type == QSocketNotifier::Exception) { qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); return; } // Check if we have a CFSocket for the native socket, create one if not. MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); if (!socketInfo) { socketInfo = new MacSocketInfo(); // Create CFSocket, specify that we want both read and write callbacks (the callbacks // are enabled/disabled later on). const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack; CFSocketContext context = {0, this, NULL, NULL, NULL}; socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context); if (CFSocketIsValid(socketInfo->socket) == false) { qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket"); return; } CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket); flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation CFSocketSetSocketFlags(socketInfo->socket, flags); // Add CFSocket to runloop. if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) { qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop"); CFSocketInvalidate(socketInfo->socket); CFRelease(socketInfo->socket); return; } // Disable both callback types by default. This must be done after // we add the CFSocket to the runloop, or else these calls will have // no effect. CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); d->macSockets.insert(nativeSocket, socketInfo); } // Increment read/write counters and select enable callbacks if necessary. if (type == QSocketNotifier::Read) { if (++socketInfo->read == 1) CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack); } else if (type == QSocketNotifier::Write) { if (++socketInfo->write == 1) CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); } }