From 7725dc7c0a1daf8116f5d3f2bcf45557a3e7443f Mon Sep 17 00:00:00 2001 From: Kevin Hock Date: Wed, 6 Oct 2004 16:20:50 +0000 Subject: [PATCH] Mac sockets events must be added to the RunLoop in the main thread, very similar to MSW. OnInit will now statically store the main RunLoop when wxSocketBase::Initialize is called (which should be called from the main thread), allowing sockets to be created in secondary threads and still receive events git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29672 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/mac/carbon/gsockosx.cpp | 21 +++++++++++++++++++-- src/mac/corefoundation/gsockosx.cpp | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/mac/carbon/gsockosx.cpp b/src/mac/carbon/gsockosx.cpp index f9c8028a34..52e9323347 100644 --- a/src/mac/carbon/gsockosx.cpp +++ b/src/mac/carbon/gsockosx.cpp @@ -24,6 +24,10 @@ struct MacGSocketData CFRunLoopSourceRef source; }; +// Sockets must use the event loop on the main thread +// We will store the main loop's reference when Initialize is called +static CFRunLoopRef s_mainRunLoop = NULL; + void Mac_Socket_Callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void* data, void* info) { @@ -81,11 +85,24 @@ bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop() bool GSocketGUIFunctionsTableConcrete::OnInit(void) { + // No need to store the main loop again + if (s_mainRunLoop != NULL) + return true; + + // Get the loop for the main thread so our events will actually fire. + // The common socket.cpp code will assert if initialize is called from a + // secondary thread, otherwise Mac would have the same problems as MSW + s_mainRunLoop = CFRunLoopGetCurrent(); + CFRetain(s_mainRunLoop); + return true; } void GSocketGUIFunctionsTableConcrete::OnExit(void) { + // Release the reference count, and set the reference back to NULL + CFRelease(s_mainRunLoop); + s_mainRunLoop = NULL; } bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket *socket) @@ -168,7 +185,7 @@ void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket *socket) struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket); if (!data) return; - CFRunLoopAddSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopCommonModes); + CFRunLoopAddSource(s_mainRunLoop, data->source, kCFRunLoopCommonModes); } void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket) @@ -177,7 +194,7 @@ void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket) if (!data) return; /* CFSocketInvalidate does CFRunLoopRemoveSource anyway */ - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopCommonModes); + CFRunLoopRemoveSource(s_mainRunLoop, data->source, kCFRunLoopCommonModes); CFSocketInvalidate(data->socket); } diff --git a/src/mac/corefoundation/gsockosx.cpp b/src/mac/corefoundation/gsockosx.cpp index f9c8028a34..52e9323347 100644 --- a/src/mac/corefoundation/gsockosx.cpp +++ b/src/mac/corefoundation/gsockosx.cpp @@ -24,6 +24,10 @@ struct MacGSocketData CFRunLoopSourceRef source; }; +// Sockets must use the event loop on the main thread +// We will store the main loop's reference when Initialize is called +static CFRunLoopRef s_mainRunLoop = NULL; + void Mac_Socket_Callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void* data, void* info) { @@ -81,11 +85,24 @@ bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop() bool GSocketGUIFunctionsTableConcrete::OnInit(void) { + // No need to store the main loop again + if (s_mainRunLoop != NULL) + return true; + + // Get the loop for the main thread so our events will actually fire. + // The common socket.cpp code will assert if initialize is called from a + // secondary thread, otherwise Mac would have the same problems as MSW + s_mainRunLoop = CFRunLoopGetCurrent(); + CFRetain(s_mainRunLoop); + return true; } void GSocketGUIFunctionsTableConcrete::OnExit(void) { + // Release the reference count, and set the reference back to NULL + CFRelease(s_mainRunLoop); + s_mainRunLoop = NULL; } bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket *socket) @@ -168,7 +185,7 @@ void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket *socket) struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket); if (!data) return; - CFRunLoopAddSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopCommonModes); + CFRunLoopAddSource(s_mainRunLoop, data->source, kCFRunLoopCommonModes); } void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket) @@ -177,7 +194,7 @@ void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket) if (!data) return; /* CFSocketInvalidate does CFRunLoopRemoveSource anyway */ - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopCommonModes); + CFRunLoopRemoveSource(s_mainRunLoop, data->source, kCFRunLoopCommonModes); CFSocketInvalidate(data->socket); } -- 2.47.2