Skip to content

Commit ff0a0ed

Browse files
[[ MobileSockets ]] Centralised the socket polling code that was common accross all platforms.
[[ MobileSockets ]] Added an auxiliary thread to Android that polls the sockets in the background.
1 parent d204899 commit ff0a0ed

16 files changed

Lines changed: 330 additions & 360 deletions

engine/src/dsklnx.cpp

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3252,27 +3252,9 @@ class MCLinuxDesktop: public MCSystemInterface
32523252
if (MCinputfd > maxfd)
32533253
maxfd = MCinputfd;
32543254
}
3255-
for (i = 0 ; i < MCnsockets ; i++)
3256-
{
3257-
if (MCsockets[i]->resolve_state != kMCSocketStateResolving &&
3258-
MCsockets[i]->resolve_state != kMCSocketStateError)
3259-
{
3260-
if (MCsockets[i]->connected && !MCsockets[i]->closing
3261-
&& !MCsockets[i]->shared || MCsockets[i]->accepting)
3262-
FD_SET(MCsockets[i]->fd, &rmaskfd);
3263-
if (!MCsockets[i]->connected || MCsockets[i]->wevents != NULL)
3264-
FD_SET(MCsockets[i]->fd, &wmaskfd);
3265-
FD_SET(MCsockets[i]->fd, &emaskfd);
3266-
if (MCsockets[i]->fd > maxfd)
3267-
maxfd = MCsockets[i]->fd;
3268-
if (MCsockets[i]->added)
3269-
{
3270-
p_delay = 0.0;
3271-
MCsockets[i]->added = False;
3272-
handled = True;
3273-
}
3274-
}
3275-
}
3255+
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
3256+
if (handled)
3257+
p_delay = 0.0;
32763258

32773259
if (g_notify_pipe[0] != -1)
32783260
{
@@ -3294,28 +3276,7 @@ class MCLinuxDesktop: public MCSystemInterface
32943276
return True;
32953277
if (MCinputfd != -1 && FD_ISSET(MCinputfd, &rmaskfd))
32963278
readinput = True;
3297-
for (i = 0 ; i < MCnsockets ; i++)
3298-
{
3299-
if (FD_ISSET(MCsockets[i]->fd, &emaskfd))
3300-
{
3301-
if (!MCsockets[i]->waiting)
3302-
{
3303-
MCsockets[i]->error = strclone("select error");
3304-
MCsockets[i]->doclose();
3305-
}
3306-
}
3307-
else
3308-
{
3309-
/* read first here, otherwise a situation can arise when select indicates
3310-
* read & write on the socket as part of the sslconnect handshaking
3311-
* and so consumed during writesome() leaving no data to read
3312-
*/
3313-
if (FD_ISSET(MCsockets[i]->fd, &rmaskfd) && !MCsockets[i]->shared)
3314-
MCsockets[i]->readsome();
3315-
if (FD_ISSET(MCsockets[i]->fd, &wmaskfd))
3316-
MCsockets[i]->writesome();
3317-
}
3318-
}
3279+
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
33193280

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

engine/src/dskmac.cpp

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7764,28 +7764,9 @@ struct MCMacDesktop: public MCSystemInterface, public MCMacSystemService
77647764
maxfd = MCshellfd;
77657765
}
77667766

7767-
uint2 i;
7768-
for (i = 0 ; i < MCnsockets ; i++)
7769-
{
7770-
int fd = MCsockets[i]->fd;
7771-
if (!fd || MCsockets[i]->resolve_state == kMCSocketStateResolving ||
7772-
MCsockets[i]->resolve_state == kMCSocketStateError)
7773-
continue;
7774-
if (MCsockets[i]->connected && !MCsockets[i]->closing
7775-
&& !MCsockets[i]->shared || MCsockets[i]->accepting)
7776-
FD_SET(fd, &rmaskfd);
7777-
if (!MCsockets[i]->connected || MCsockets[i]->wevents != NULL)
7778-
FD_SET(fd, &wmaskfd);
7779-
FD_SET(fd, &emaskfd);
7780-
if (fd > maxfd)
7781-
maxfd = fd;
7782-
if (MCsockets[i]->added)
7783-
{
7784-
p_delay = 0.0;
7785-
MCsockets[i]->added = False;
7786-
handled = True;
7787-
}
7788-
}
7767+
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
7768+
if (handled)
7769+
p_delay = 0.0;
77897770

77907771
struct timeval timeoutval;
77917772
timeoutval.tv_sec = (long)p_delay;
@@ -7800,32 +7781,7 @@ struct MCMacDesktop: public MCSystemInterface, public MCMacSystemService
78007781
if (MCshellfd != -1 && FD_ISSET(MCshellfd, &rmaskfd))
78017782
return True;
78027783

7803-
for (i = 0 ; i < MCnsockets ; i++)
7804-
{
7805-
int fd = MCsockets[i]->fd;
7806-
if (FD_ISSET(fd, &emaskfd) && fd != 0)
7807-
{
7808-
7809-
if (!MCsockets[i]->waiting)
7810-
{
7811-
MCsockets[i]->error = strclone("select error");
7812-
MCsockets[i]->doclose();
7813-
}
7814-
7815-
}
7816-
else
7817-
{
7818-
if (FD_ISSET(fd, &rmaskfd) && !MCsockets[i]->shared)
7819-
{
7820-
MCsockets[i]->readsome();
7821-
}
7822-
if (FD_ISSET(fd, &wmaskfd))
7823-
{
7824-
MCsockets[i]->writesome();
7825-
}
7826-
}
7827-
MCsockets[i]->setselect();
7828-
}
7784+
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
78297785

78307786
return True;
78317787
}

engine/src/dskw32.cpp

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4925,47 +4925,16 @@ struct MCWindowsDesktop: public MCSystemInterface, public MCWindowsSystemService
49254925
i = 0;
49264926
}
49274927
}
4928-
for (i = 0 ; i < MCnsockets ; i++)
4929-
{
4930-
if (MCsockets[i]->connected && !MCsockets[i]->closing
4931-
&& !MCsockets[i]->shared || MCsockets[i]->accepting)
4932-
FD_SET(MCsockets[i]->fd, &rmaskfd);
4933-
if (!MCsockets[i]->connected || MCsockets[i]->wevents != NULL)
4934-
FD_SET(MCsockets[i]->fd, &wmaskfd);
4935-
FD_SET(MCsockets[i]->fd, &emaskfd);
4936-
if (MCsockets[i]->fd > maxfd)
4937-
maxfd = MCsockets[i]->fd;
4938-
if (MCsockets[i]->added)
4939-
{
4940-
p_delay = 0.0;
4941-
MCsockets[i]->added = False;
4942-
handled = True;
4943-
}
4944-
}
4928+
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
4929+
if (handled)
4930+
p_delay = 0.0;
49454931
struct timeval timeoutval;
49464932
timeoutval.tv_sec = (long)p_delay;
49474933
timeoutval.tv_usec = (long)((p_delay - floor(p_delay)) * 1000000.0);
49484934
n = select(maxfd + 1, &rmaskfd, &wmaskfd, &emaskfd, &timeoutval);
49494935
if (n <= 0)
49504936
return handled;
4951-
for (i = 0 ; i < MCnsockets ; i++)
4952-
{
4953-
if (FD_ISSET(MCsockets[i]->fd, &emaskfd))
4954-
{
4955-
if (!MCsockets[i]->waiting)
4956-
{
4957-
MCsockets[i]->error = strclone("select error");
4958-
MCsockets[i]->doclose();
4959-
}
4960-
}
4961-
else
4962-
{
4963-
if (FD_ISSET(MCsockets[i]->fd, &wmaskfd))
4964-
MCsockets[i]->writesome();
4965-
if (FD_ISSET(MCsockets[i]->fd, &rmaskfd) && !MCsockets[i]->shared)
4966-
MCsockets[i]->readsome();
4967-
}
4968-
}
4937+
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
49694938
return n != 0;
49704939
}
49714940

engine/src/exec-network.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -566,10 +566,7 @@ void MCNetworkExecPerformOpenSocket(MCExecContext& ctxt, MCNameRef p_name, MCNam
566566
// MM-2014-06-13: [[ Bug 12567 ]] Added support for specifying an end host name to verify against.
567567
MCSocket *s = MCS_open_socket(p_name, p_datagram, ctxt . GetObject(), p_message, p_secure, p_ssl, kMCEmptyString, p_end_hostname);
568568
if (s != NULL)
569-
{
570-
MCU_realloc((char **)&MCsockets, MCnsockets, MCnsockets + 1, sizeof(MCSocket *));
571-
MCsockets[MCnsockets++] = s;
572-
}
569+
MCSocketsAppendToSocketList(s);
573570
}
574571

575572
void MCNetworkExecOpenSocket(MCExecContext& ctxt, MCNameRef p_name, MCNameRef p_message, MCNameRef p_end_hostname)
@@ -613,11 +610,7 @@ void MCNetworkExecPerformAcceptConnections(MCExecContext& ctxt, uint2 p_port, MC
613610

614611
MCSocket *s = MCS_accept(p_port, ctxt . GetObject(), p_message, p_datagram ? True : False, p_secure ? True : False, p_with_verification ? True : False, kMCEmptyString);
615612
if (s != NULL)
616-
{
617-
MCU_realloc((char **)&MCsockets, MCnsockets,
618-
MCnsockets + 1, sizeof(MCSocket *));
619-
MCsockets[MCnsockets++] = s;
620-
}
613+
MCSocketsAppendToSocketList(s);
621614
}
622615

623616
void MCNetworkExecAcceptConnectionsOnPort(MCExecContext& ctxt, uint2 p_port, MCNameRef p_message)

engine/src/globals.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,8 @@ void X_clear_globals(void)
828828
// MW-2013-03-20: [[ MainStacksChanged ]]
829829
MCmainstackschanged = False;
830830

831+
MCSocketsInitialize();
832+
831833
#ifdef _ANDROID_MOBILE
832834
extern void MCAndroidMediaPickInitialize();
833835
// MM-2012-02-22: Initialize up any static variables as Android static vars are preserved between sessions
@@ -1277,6 +1279,8 @@ int X_close(void)
12771279
// MM-2013-09-03: [[ RefactorGraphics ]] Initialize graphics library.
12781280
MCGraphicsFinalize();
12791281

1282+
MCSocketsFinalize();
1283+
12801284
#ifdef _ANDROID_MOBILE
12811285
// MM-2012-02-22: Clean up any static variables as Android static vars are preserved between sessions
12821286
MCAdFinalize();

engine/src/lnxspec.cpp

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,27 +1712,9 @@ Boolean MCS_poll(real8 delay, int fd)
17121712
if (MCinputfd > maxfd)
17131713
maxfd = MCinputfd;
17141714
}
1715-
for (i = 0 ; i < MCnsockets ; i++)
1716-
{
1717-
if (MCsockets[i]->resolve_state != kMCSocketStateResolving &&
1718-
MCsockets[i]->resolve_state != kMCSocketStateError)
1719-
{
1720-
if (MCsockets[i]->connected && !MCsockets[i]->closing
1721-
&& !MCsockets[i]->shared || MCsockets[i]->accepting)
1722-
FD_SET(MCsockets[i]->fd, &rmaskfd);
1723-
if (!MCsockets[i]->connected || MCsockets[i]->wevents != NULL)
1724-
FD_SET(MCsockets[i]->fd, &wmaskfd);
1725-
FD_SET(MCsockets[i]->fd, &emaskfd);
1726-
if (MCsockets[i]->fd > maxfd)
1727-
maxfd = MCsockets[i]->fd;
1728-
if (MCsockets[i]->added)
1729-
{
1730-
delay = 0.0;
1731-
MCsockets[i]->added = False;
1732-
handled = True;
1733-
}
1734-
}
1735-
}
1715+
handled = MCSocketsAddToFileDescriptorSets(maxfd, rmaskfd, wmaskfd, emaskfd);
1716+
if (handled)
1717+
delay = 0.0;
17361718

17371719
if (g_notify_pipe[0] != -1)
17381720
{
@@ -1754,29 +1736,8 @@ Boolean MCS_poll(real8 delay, int fd)
17541736
return True;
17551737
if (MCinputfd != -1 && FD_ISSET(MCinputfd, &rmaskfd))
17561738
readinput = True;
1757-
for (i = 0 ; i < MCnsockets ; i++)
1758-
{
1759-
if (FD_ISSET(MCsockets[i]->fd, &emaskfd))
1760-
{
1761-
if (!MCsockets[i]->waiting)
1762-
{
1763-
MCsockets[i]->error = strclone("select error");
1764-
MCsockets[i]->doclose();
1765-
}
1766-
}
1767-
else
1768-
{
1769-
/* read first here, otherwise a situation can arise when select indicates
1770-
* read & write on the socket as part of the sslconnect handshaking
1771-
* and so consumed during writesome() leaving no data to read
1772-
*/
1773-
if (FD_ISSET(MCsockets[i]->fd, &rmaskfd) && !MCsockets[i]->shared)
1774-
MCsockets[i]->readsome();
1775-
if (FD_ISSET(MCsockets[i]->fd, &wmaskfd))
1776-
MCsockets[i]->writesome();
1777-
}
1778-
}
1779-
1739+
MCSocketsHandleFileDescriptorSets(rmaskfd, wmaskfd, emaskfd);
1740+
17801741
if (g_notify_pipe[0] != -1 && FD_ISSET(g_notify_pipe[0], &rmaskfd))
17811742
{
17821743
char t_notify_char;

engine/src/mblandroid.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,9 @@ void MCAndroidSystem::KillAll(void)
149149
return;
150150
}
151151

152-
// MM-2015-06-08: [[ MobileSockets ]] Poll sockets.
153152
Boolean MCAndroidSystem::Poll(real8 p_delay, int p_fd)
154153
{
155-
return MCS_handle_sockets();
154+
return False;
156155
}
157156

158157
Boolean MCAndroidSystem::IsInteractiveConsole(int p_fd)

engine/src/mblandroiddc.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -523,14 +523,6 @@ Boolean MCScreenDC::wait(real8 duration, Boolean dispatch, Boolean anyevent)
523523
else if (!done && eventtime > curtime)
524524
t_sleep = MCMin(eventtime - curtime, exittime - curtime);
525525

526-
// MM-2015-06-05: [[ MobileSockets ]] Poll sockets.
527-
if (MCS_poll(0.0, 0.0))
528-
{
529-
if (anyevent)
530-
done = True;
531-
t_sleep = 0.0;
532-
}
533-
534526
// At this point we yield to android, requesting that we get control back
535527
// within the specified time.
536528
bool t_broken;
@@ -1415,8 +1407,7 @@ static void co_yield_to_android(void)
14151407
static bool co_yield_to_android_and_wait(double p_sleep, bool p_wake_on_event)
14161408
{
14171409
s_schedule_wakeup = true;
1418-
// MM-2015-06-08: [[ MobileSockets ]] The duration is passed in in milliseconds, not seconds.
1419-
s_schedule_wakeup_timeout = (uint32_t)(p_sleep);
1410+
s_schedule_wakeup_timeout = (uint32_t)(p_sleep * 1000.0);
14201411
s_schedule_wakeup_breakable = p_wake_on_event;
14211412
co_yield_to_android();
14221413
s_schedule_wakeup = false;
@@ -1438,7 +1429,13 @@ void MCAndroidBreakWait(void)
14381429
{
14391430
// MM-2015-06-08: [[ MobileSockets ]] Make sure we execute on the UI thread.
14401431
// Calling scheduleWakeUp indirectly has this effect.
1441-
s_android_ui_env -> CallVoidMethod(s_android_view, s_schedule_wakeup_method, 0, s_schedule_wakeup_breakable);
1432+
s_schedule_wakeup_was_broken = true;
1433+
JNIEnv *t_env;
1434+
t_env = MCJavaGetThreadEnv();
1435+
if (t_env != nil)
1436+
t_env -> CallVoidMethod(s_android_view, s_schedule_wakeup_method, 0, s_schedule_wakeup_breakable);
1437+
else
1438+
s_android_ui_env -> CallVoidMethod(s_android_view, s_schedule_wakeup_method, 0, s_schedule_wakeup_breakable);
14421439
}
14431440

14441441
struct MCAndroidEngineCallThreadContext
@@ -1977,7 +1974,7 @@ JNIEXPORT void JNICALL Java_com_runrev_android_Engine_doProcess(JNIEnv *env, job
19771974
if (!s_engine_running)
19781975
return;
19791976

1980-
s_schedule_wakeup_was_broken = !timedout;
1977+
s_schedule_wakeup_was_broken = !timedout || s_schedule_wakeup_was_broken;
19811978
co_yield_to_engine();
19821979
}
19831980

@@ -2848,5 +2845,20 @@ JNIEnv *MCJavaGetThreadEnv()
28482845
return t_env;
28492846
}
28502847

2848+
JNIEnv *MCJavaAttachCurrentThread()
2849+
{
2850+
JNIEnv *t_env;
2851+
t_env = nil;
2852+
if (s_java_vm -> AttachCurrentThread(&t_env, nil) < 0)
2853+
return nil;
2854+
return t_env;
2855+
}
2856+
2857+
void MCJavaDetachCurrentThread()
2858+
{
2859+
s_java_vm -> DetachCurrentThread();
2860+
}
2861+
2862+
28512863
////////////////////////////////////////////////////////////////////////////////
28522864

engine/src/mblandroidjava.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ typedef struct
6767
} MCJavaMethodParams;
6868

6969
JNIEnv *MCJavaGetThreadEnv();
70+
JNIEnv *MCJavaAttachCurrentThread();
71+
void MCJavaDetachCurrentThread();
7072

7173
bool MCJavaStringFromNative(JNIEnv *env, const MCString *p_string, jstring &r_java_string);
7274
bool MCJavaStringFromUnicode(JNIEnv *env, const MCString *p_string, jstring &r_java_string);

0 commit comments

Comments
 (0)