Skip to content

Commit 4503540

Browse files
[[ AuxSocketThread ]] Refactor the socket code so that select is called on an auxiliary thread.
This was already the case on Android. Updated so all platfroms other than Windows check for socket updates by calling select on an auxiliary thread. Using the platform specific callbacks was not always working: the event loop was not always waking up on Mac since the update to Cocoa and the interupting of the runloop on iOS was causing oddities. Linux was updated for consitency. Windows would be a little more fiddly (and appears to be working well) so was left as is for the time being.
1 parent 1ee6450 commit 4503540

10 files changed

Lines changed: 26 additions & 174 deletions

File tree

docs/notes/bugfix-15938.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Mouse messages are sometimes not sent on iOS when using sockets

docs/notes/bugfix-16707.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Socket messages are sometimes not sent on Mac

engine/src/desktop-dc.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -878,20 +878,6 @@ Boolean MCScreenDC::wait(real8 duration, Boolean dispatch, Boolean anyevent)
878878
// IM-2014-06-25: [[ Bug 12671 ]] If there are runloop actions then set a timeout instead of waiting for the next event
879879
if (HasRunloopActions())
880880
t_sleep = MCMin(0.01, t_sleep);
881-
882-
// MW-2014-07-16: [[ Bug 12799 ]] If polling sockets does something then don't wait for long.
883-
extern Boolean MCS_handle_sockets();
884-
885-
// SN-2014-10-17: [[ Bug 13360 ]] If MCS_handle_sockets returns true, we don't want to get stuck in a
886-
// loop waiting 0.0 s for events. That was causing issues in MCRead::readuntil, if data arrived after
887-
// the call to read()
888-
if (MCS_handle_sockets())
889-
{
890-
if (anyevent)
891-
done = True;
892-
t_sleep = 0.0;
893-
}
894-
895881

896882
// Wait for t_sleep seconds and collect at most one event. If an event
897883
// is collected and anyevent is True, then we are done.

engine/src/dsklnx.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3290,8 +3290,6 @@ class MCLinuxDesktop: public MCSystemInterface
32903290
maxfd = MCinputfd;
32913291
}
32923292

3293-
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
3294-
32953293
if (g_notify_pipe[0] != -1)
32963294
{
32973295
FD_SET(g_notify_pipe[0], &rmaskfd);
@@ -3345,7 +3343,6 @@ class MCLinuxDesktop: public MCSystemInterface
33453343
return True;
33463344
if (MCinputfd != -1 && FD_ISSET(MCinputfd, &rmaskfd))
33473345
readinput = True;
3348-
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
33493346

33503347
// Check whether any of the GLib file descriptors were signalled
33513348
for (uindex_t i = 0; i < t_glib_fds.Size(); i++)

engine/src/dskmac.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7479,7 +7479,6 @@ struct MCMacDesktop: public MCSystemInterface, public MCMacSystemService
74797479

74807480
return True;
74817481
#endif /* MCS_poll_dsk_mac */
7482-
Boolean handled = False;
74837482
fd_set rmaskfd, wmaskfd, emaskfd;
74847483
FD_ZERO(&rmaskfd);
74857484
FD_ZERO(&wmaskfd);
@@ -7498,10 +7497,6 @@ struct MCMacDesktop: public MCSystemInterface, public MCMacSystemService
74987497
maxfd = MCshellfd;
74997498
}
75007499

7501-
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
7502-
if (handled)
7503-
p_delay = 0.0;
7504-
75057500
struct timeval timeoutval;
75067501
timeoutval.tv_sec = (long)p_delay;
75077502
timeoutval.tv_usec = (long)((p_delay - floor(p_delay)) * 1000000.0);
@@ -7510,13 +7505,11 @@ struct MCMacDesktop: public MCSystemInterface, public MCMacSystemService
75107505
n = select(maxfd + 1, &rmaskfd, &wmaskfd, &emaskfd, &timeoutval);
75117506

75127507
if (n <= 0)
7513-
return handled;
7508+
return False;
75147509

75157510
if (MCshellfd != -1 && FD_ISSET(MCshellfd, &rmaskfd))
75167511
return True;
75177512

7518-
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
7519-
75207513
return True;
75217514
}
75227515

engine/src/lnxspec.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,7 +1693,6 @@ Boolean MCS_poll(real8 delay, int fd)
16931693
int4 n;
16941694
uint2 i;
16951695
Boolean wasalarm = alarmpending;
1696-
Boolean handled = False;
16971696
if (alarmpending)
16981697
MCS_alarm(0.0);
16991698

@@ -1721,9 +1720,6 @@ Boolean MCS_poll(real8 delay, int fd)
17211720
if (MCinputfd > maxfd)
17221721
maxfd = MCinputfd;
17231722
}
1724-
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
1725-
if (handled)
1726-
delay = 0.0;
17271723

17281724
if (g_notify_pipe[0] != -1)
17291725
{
@@ -1740,12 +1736,11 @@ Boolean MCS_poll(real8 delay, int fd)
17401736

17411737
n = select(maxfd + 1, &rmaskfd, &wmaskfd, &emaskfd, &timeoutval);
17421738
if (n <= 0)
1743-
return handled;
1739+
return False;
17441740
if (MCshellfd != -1 && FD_ISSET(MCshellfd, &rmaskfd))
17451741
return True;
17461742
if (MCinputfd != -1 && FD_ISSET(MCinputfd, &rmaskfd))
17471743
readinput = True;
1748-
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
17491744

17501745
if (g_notify_pipe[0] != -1 && FD_ISSET(g_notify_pipe[0], &rmaskfd))
17511746
{

engine/src/mbliphone.mm

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,31 +1149,9 @@ virtual int64_t GetFileSize(void)
11491149
return;
11501150
}
11511151

1152-
// MM-2015-06-08: [[ MobileSockets ]] Poll sockets.
11531152
Boolean MCIPhoneSystem::Poll(real8 p_delay, int p_fd)
11541153
{
1155-
Boolean handled = False;
1156-
fd_set rmaskfd, wmaskfd, emaskfd;
1157-
FD_ZERO(&rmaskfd);
1158-
FD_ZERO(&wmaskfd);
1159-
FD_ZERO(&emaskfd);
1160-
int4 maxfd = 0;
1161-
1162-
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
1163-
if (handled)
1164-
p_delay = 0.0;
1165-
1166-
struct timeval timeoutval;
1167-
timeoutval.tv_sec = (long)p_delay;
1168-
timeoutval.tv_usec = (long)((p_delay - floor(p_delay)) * 1000000.0);
1169-
1170-
int n = 0;
1171-
n = select(maxfd + 1, &rmaskfd, &wmaskfd, &emaskfd, &timeoutval);
1172-
if (n <= 0)
1173-
return handled;
1174-
1175-
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
1176-
return True;
1154+
return False;
11771155
}
11781156

11791157
Boolean MCIPhoneSystem::IsInteractiveConsole(int p_fd)

engine/src/mbliphonedc.mm

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -731,16 +731,7 @@ static void MCScreenDCDoSnapshot(void *p_env)
731731
done = True;
732732
else if (!done && eventtime > curtime)
733733
t_sleep = MCMin(eventtime - curtime, exittime - curtime);
734-
735-
// MM-2015-08-11: [[ Bug 15700 ]] Poll the sockets. Code pulled over from OS X wait.
736-
extern Boolean MCS_handle_sockets();
737-
if (MCS_handle_sockets())
738-
{
739-
if (anyevent)
740-
done = True;
741-
t_sleep = 0.0;
742-
}
743-
734+
744735
// Switch to the main fiber and wait for at most t_sleep seconds. This
745736
// returns 'true' if the wait was broken rather than timed out.
746737
if (MCIPhoneWait(t_sleep) && anyevent)

engine/src/opensslsocket.cpp

Lines changed: 20 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,15 @@ extern char *osx_cfstring_to_cstring(CFStringRef p_string, bool p_release, bool
9898
#include "mcssl.h"
9999

100100
#if defined(TARGET_SUBPLATFORM_ANDROID)
101-
#include <pthread.h>
102101
#include "mblandroidjava.h"
102+
#endif
103+
104+
#if defined(_MAC_DESKTOP) || defined(_LINUX_DESKTOP) || defined(TARGET_SUBPLATFORM_IPHONE) || defined(TARGET_SUBPLATFORM_ANDROID)
105+
#define USE_AUX_THREAD
106+
#endif
107+
108+
#if defined(USE_AUX_THREAD)
109+
#include <pthread.h>
103110

104111
static pthread_t s_socket_poll_thread = NULL;
105112
static pthread_mutex_t s_socket_list_mutex;
@@ -134,89 +141,28 @@ extern HANDLE g_socket_wakeup;
134141

135142
Boolean MCSocket::sslinited = False;
136143

137-
#if defined(_MACOSX) || defined(TARGET_SUBPLATFORM_IPHONE)
138-
static void socketCallback (CFSocketRef cfsockref, CFSocketCallBackType type, CFDataRef address, const void *pData, void *pInfo)
139-
{
140-
uint2 i;
141-
int fd = CFSocketGetNative(cfsockref);
142-
for (i = 0 ; i < MCnsockets ; i++)
143-
{
144-
if ( fd == MCsockets[i]->fd && !MCsockets[i]->shared)
145-
break;
146-
}
147-
if (i < MCnsockets)
148-
{
149-
fd_set rmaskfd, wmaskfd, emaskfd;
150-
FD_ZERO(&rmaskfd);
151-
FD_ZERO(&wmaskfd);
152-
FD_ZERO(&emaskfd);
153-
FD_SET(fd, &rmaskfd);
154-
struct timeval t_time = {0,0};
155-
select(fd, &rmaskfd, &wmaskfd, &emaskfd, &t_time);
156-
switch (type)
157-
{
158-
case kCFSocketReadCallBack:
159-
if (FD_ISSET(fd, &rmaskfd))
160-
{
161-
MCsockets[i]->readsome();
162-
MCsockets[i]->setselect();
163-
}
164-
break;
165-
case kCFSocketWriteCallBack:
166-
MCsockets[i]->writesome();
167-
MCsockets[i]->setselect();
168-
break;
169-
case kCFSocketConnectCallBack:
170-
MCsockets[i]->writesome();
171-
MCsockets[i]->readsome();
172-
break;
173-
}
174-
#ifdef _MACOSX
175-
MCPlatformBreakWait();
176-
#else
177-
extern void MCIPhoneBreakWait(void);
178-
MCIPhoneBreakWait();
179-
#endif
180-
181-
}
182-
MCS_poll(0.0,0);//quick poll of other sockets
183-
}
184-
#endif
185-
186-
#if defined(_MACOSX) || defined(TARGET_SUBPLATFORM_IPHONE)
187-
Boolean MCS_handle_sockets()
188-
{
189-
return MCS_poll(0.0,0);
190-
}
191-
#else
192-
Boolean MCS_handle_sockets()
193-
{
194-
return True;
195-
}
196-
#endif
197-
198-
199144
static void MCSocketsLockSocketList(void)
200145
{
201-
#if defined(TARGET_SUBPLATFORM_ANDROID)
146+
#if defined(USE_AUX_THREAD)
202147
if (s_socket_poll_thread != NULL)
203148
pthread_mutex_lock(&s_socket_list_mutex);
204149
#endif
205150
}
206151

207152
static void MCSocketsUnlockSocketList(void)
208153
{
209-
#if defined(TARGET_SUBPLATFORM_ANDROID)
154+
#if defined(USE_AUX_THREAD)
210155
if (s_socket_poll_thread != NULL)
211156
pthread_mutex_unlock(&s_socket_list_mutex);
212157
#endif
213158
}
214159

215-
#if defined(TARGET_SUBPLATFORM_ANDROID)
160+
#if defined(USE_AUX_THREAD)
216161
// MM-2015-07-07: [[ MobileSockets ]] Since on Android we can't hook into system
217162
// calls to monitor sockets, we instead have an auxiliary thread that polls the
218163
// sockets checking for any activity. If any sockets are pending, a notification
219164
// is pushed onto the main thread which will complete the read/write.
165+
// MM-2016-01-27: [[ AuxThread ]] Updated to use the auxiliary thread on all platforms other than Windows.
220166

221167
struct MCSocketsHandleFileDescriptorsCallbackContext
222168
{
@@ -234,7 +180,9 @@ static void MCSocketsHandleFileDescriptorsCallback(void *p_context)
234180

235181
static void *MCSocketsPoll(void *p_arg)
236182
{
183+
#if defined(TARGET_SUBPLATFORM_ANDROID)
237184
MCJavaAttachCurrentThread();
185+
#endif
238186

239187
fd_set rmaskfd, wmaskfd, emaskfd;
240188
int4 maxfd;
@@ -278,7 +226,10 @@ static void *MCSocketsPoll(void *p_arg)
278226
}
279227
}
280228

229+
#if defined(TARGET_SUBPLATFORM_ANDROID)
281230
MCJavaDetachCurrentThread();
231+
#endif
232+
282233
return NULL;
283234
}
284235
#endif
@@ -288,7 +239,7 @@ static bool MCSocketsPollInterrupt(void)
288239
bool t_success;
289240
t_success = true;
290241

291-
#if defined(TARGET_SUBPLATFORM_ANDROID)
242+
#if defined(USE_AUX_THREAD)
292243
if (t_success)
293244
{
294245
if (s_socket_poll_thread == NULL)
@@ -313,7 +264,7 @@ static bool MCSocketsPollInterrupt(void)
313264

314265
bool MCSocketsInitialize(void)
315266
{
316-
#if defined(TARGET_SUBPLATFORM_ANDROID)
267+
#if defined(USE_AUX_THREAD)
317268
s_socket_poll_thread = NULL;
318269
s_socket_poll_run = false;
319270
#endif
@@ -322,7 +273,7 @@ bool MCSocketsInitialize(void)
322273

323274
void MCSocketsFinalize(void)
324275
{
325-
#if defined(TARGET_SUBPLATFORM_ANDROID)
276+
#if defined(USE_AUX_THREAD)
326277
if (s_socket_poll_thread != NULL)
327278
{
328279
s_socket_poll_run = false;
@@ -1888,32 +1839,11 @@ void MCSocket::setselect(uint2 sflags)
18881839
WSAEventSelect(fd, g_socket_wakeup, event);
18891840
}
18901841
#endif
1891-
#if defined(_MACOSX) || defined(TARGET_SUBPLATFORM_IPHONE)
1892-
if (sflags & BIONB_TESTWRITE)
1893-
CFSocketEnableCallBacks(cfsockref,kCFSocketWriteCallBack);
1894-
if (sflags & BIONB_TESTREAD)
1895-
CFSocketEnableCallBacks(cfsockref,kCFSocketReadCallBack);
1896-
#endif
18971842
}
18981843

18991844
Boolean MCSocket::init(MCSocketHandle newfd)
19001845
{
19011846
fd = newfd;
1902-
#if defined(_MACOSX) || defined(TARGET_SUBPLATFORM_IPHONE)
1903-
1904-
cfsockref = NULL;
1905-
rlref = NULL;
1906-
cfsockref = CFSocketCreateWithNative (kCFAllocatorDefault,fd, kCFSocketReadCallBack|kCFSocketWriteCallBack,
1907-
(CFSocketCallBack)&socketCallback, NULL);
1908-
if (cfsockref)
1909-
{
1910-
rlref = CFSocketCreateRunLoopSource(kCFAllocatorDefault, cfsockref, 0);
1911-
// MM-2015-06-04: [[ MobileSockets ]] Make sure we post the callbacks to the main thread (since we run a twin thread set up on iOS)
1912-
CFRunLoopAddSource((CFRunLoopRef) CFRunLoopGetMain(), rlref, kCFRunLoopCommonModes);
1913-
CFOptionFlags socketOptions = 0 ;
1914-
CFSocketSetSocketFlags( cfsockref, socketOptions );
1915-
}
1916-
#endif
19171847
return True;
19181848
}
19191849

@@ -1924,15 +1854,6 @@ void MCSocket::close()
19241854
{
19251855
if (secure)
19261856
sslclose();
1927-
#if defined(_MACOSX) || defined(TARGET_SUBPLATFORM_IPHONE)
1928-
1929-
if (rlref != NULL)
1930-
{
1931-
CFRunLoopRemoveSource (CFRunLoopGetCurrent(), rlref, kCFRunLoopDefaultMode);
1932-
CFRelease (rlref);
1933-
rlref = NULL;
1934-
}
1935-
#endif
19361857
#if defined(_WINDOWS_DESKTOP) || defined(_WINDOWS_SERVER)
19371858
closesocket(fd);
19381859
#else
@@ -1941,16 +1862,6 @@ void MCSocket::close()
19411862
#endif
19421863

19431864
fd = 0;
1944-
#if defined(_MACOSX) || defined(TARGET_SUBPLATFORM_IPHONE)
1945-
1946-
if (cfsockref != NULL)
1947-
{
1948-
CFSocketInvalidate (cfsockref);
1949-
CFRelease (cfsockref);
1950-
cfsockref = NULL;
1951-
}
1952-
#endif
1953-
19541865
}
19551866
}
19561867

engine/src/osspec.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ extern void MCS_setplayloudness(uint2 p_loudness);
189189

190190
///////////////////////////////////////////////////////////////////////////////
191191

192-
extern Boolean MCS_handle_sockets(void);
193192
extern bool MCS_init_sockets();
194193
extern bool MCS_compare_host_domain(MCStringRef p_host_a, MCStringRef p_host_b);
195194
extern MCSocket *MCS_open_socket(MCNameRef name, Boolean datagram, MCObject *o, MCNameRef m, Boolean secure, Boolean sslverify, MCStringRef sslcertfile, MCNameRef p_end_hostname);

0 commit comments

Comments
 (0)