aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library_browser.js6
-rw-r--r--system/include/emscripten/emscripten.h20
-rw-r--r--tests/emscripten_api_browser.cpp2
-rw-r--r--tests/emscripten_api_browser_infloop.cpp41
-rw-r--r--tests/emscripten_fs_api_browser.cpp2
-rw-r--r--tests/enet_client.c2
-rw-r--r--tests/enet_server.c2
-rwxr-xr-xtests/runner.py3
-rw-r--r--tests/sdl_canvas_palette_2.c2
-rw-r--r--tests/sdl_mouse.c2
-rw-r--r--tests/sdl_quit.c2
-rw-r--r--tests/websockets.c2
-rw-r--r--tests/websockets_bi.c2
-rw-r--r--tests/websockets_bi_listener.c2
-rw-r--r--tests/websockets_gethostbyname.c2
15 files changed, 78 insertions, 14 deletions
diff --git a/src/library_browser.js b/src/library_browser.js
index 6985e04a..fc8cb84c 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -402,7 +402,7 @@ mergeInto(LibraryManager.library, {
}, millis);
},
- emscripten_set_main_loop: function(func, fps) {
+ emscripten_set_main_loop: function(func, fps, simulateInfiniteLoop) {
Module['noExitRuntime'] = true;
var jsFunc = FUNCTION_TABLE[func];
@@ -462,6 +462,10 @@ mergeInto(LibraryManager.library, {
}
}
Browser.mainLoop.scheduler();
+
+ if (simulateInfiniteLoop) {
+ throw 'emscripten_set_main_loop simulating infinite loop by throwing so we get right into the JS event loop';
+ }
},
emscripten_cancel_main_loop: function() {
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index 1b1310c4..078f87d2 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -46,14 +46,30 @@ extern void emscripten_async_run_script(const char *script, int millis);
* code assumes that), so you can break the code up into
* asynchronous callbacks, but you must pause the main
* loop until they complete.
+ *
+ * @simulate_infinite_loop If true, this function will throw an
+ * exception in order to stop execution of the caller. This
+ * will lead to the main loop being entered instead of code
+ * after the call to emscripten_set_main_loop being run, which
+ * is the closest we can get to simulating an infinite loop
+ * (we do something similar in glutMainLoop in GLUT). If this
+ * parameter is false, then the behavior is the same as it
+ * was before this parameter was added to the API, which is
+ * that execution continues normally. Note that in both cases
+ * we do not run global destructors, atexit, etc., since we
+ * know the main loop will still be running, but if we do
+ * not simulate an infinite loop then the stack will be unwinded.
+ * That means that if simulate_infinite_loop is false, and
+ * you created an object on the stack, it will be cleaned up
+ * before the main loop will be called the first time.
*/
#if EMSCRIPTEN
-extern void emscripten_set_main_loop(void (*func)(), int fps);
+extern void emscripten_set_main_loop(void (*func)(), int fps, int simulate_infinite_loop);
extern void emscripten_pause_main_loop();
extern void emscripten_resume_main_loop();
extern void emscripten_cancel_main_loop();
#else
-#define emscripten_set_main_loop(func, fps) \
+#define emscripten_set_main_loop(func, fps, simulateInfiniteLoop) \
while (1) func();
#endif
diff --git a/tests/emscripten_api_browser.cpp b/tests/emscripten_api_browser.cpp
index c209550b..b35fbac2 100644
--- a/tests/emscripten_api_browser.cpp
+++ b/tests/emscripten_api_browser.cpp
@@ -53,7 +53,7 @@ void mainey() {
void four(void *arg) {
assert((int)arg == 43);
printf("four!\n");
- emscripten_set_main_loop(mainey, 0);
+ emscripten_set_main_loop(mainey, 0, 0);
}
void __attribute__((used)) third() {
diff --git a/tests/emscripten_api_browser_infloop.cpp b/tests/emscripten_api_browser_infloop.cpp
new file mode 100644
index 00000000..0fd41922
--- /dev/null
+++ b/tests/emscripten_api_browser_infloop.cpp
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <string.h>
+#include <emscripten.h>
+
+struct Class {
+ static Class *instance;
+
+ int x;
+
+ Class() : x(0) {}
+
+ void print() {
+ char buf[18];
+ memset(buf, 0, 18); // clear stack. if we did not simulate infinite loop, this clears x and is a bug!
+ x += buf[7];
+
+ printf("waka %d\n", x++);
+
+ if (x == 7) {
+ int result = x;
+ REPORT_RESULT();
+ }
+ }
+
+ static void callback() {
+ instance->print();
+ }
+
+ void start() {
+ instance = this;
+ emscripten_set_main_loop(Class::callback, 3, 1); // important if we simulate an infinite loop here or not
+ }
+};
+
+Class *Class::instance = NULL;
+
+int main() {
+ Class().start();
+ return 1;
+}
+
diff --git a/tests/emscripten_fs_api_browser.cpp b/tests/emscripten_fs_api_browser.cpp
index 7757ef8a..a2a82160 100644
--- a/tests/emscripten_fs_api_browser.cpp
+++ b/tests/emscripten_fs_api_browser.cpp
@@ -69,7 +69,7 @@ int main() {
onLoaded,
onError);
- emscripten_set_main_loop(wait_wgets, 0);
+ emscripten_set_main_loop(wait_wgets, 0, 0);
return 0;
}
diff --git a/tests/enet_client.c b/tests/enet_client.c
index 6eb088a3..461472b8 100644
--- a/tests/enet_client.c
+++ b/tests/enet_client.c
@@ -94,7 +94,7 @@ int main (int argc, char ** argv)
"console.log('added.');");
#endif
- emscripten_set_main_loop(main_loop, 1);
+ emscripten_set_main_loop(main_loop, 1, 1);
return 1;
}
diff --git a/tests/enet_server.c b/tests/enet_server.c
index f43d511d..68fe8e86 100644
--- a/tests/enet_server.c
+++ b/tests/enet_server.c
@@ -92,7 +92,7 @@ int main (int argc, char ** argv)
exit (EXIT_FAILURE);
}
- emscripten_set_main_loop(main_loop, 1);
+ emscripten_set_main_loop(main_loop, 1, 1);
return 1;
}
diff --git a/tests/runner.py b/tests/runner.py
index 1c277104..0c677b58 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -8664,6 +8664,9 @@ elif 'browser' in str(sys.argv):
def test_emscripten_api(self):
self.btest('emscripten_api_browser.cpp', '1')
+ def test_emscripten_api_infloop(self):
+ self.btest('emscripten_api_browser_infloop.cpp', '7')
+
def test_emscripten_fs_api(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) # preloaded *after* run
self.btest('emscripten_fs_api_browser.cpp', '1')
diff --git a/tests/sdl_canvas_palette_2.c b/tests/sdl_canvas_palette_2.c
index db051b2b..db9c3207 100644
--- a/tests/sdl_canvas_palette_2.c
+++ b/tests/sdl_canvas_palette_2.c
@@ -68,7 +68,7 @@ int main() {
//Animation
printf("you should see red gradient animation\n");
- emscripten_set_main_loop(animatePalette, 0);
+ emscripten_set_main_loop(animatePalette, 0, 1);
SDL_Quit();
diff --git a/tests/sdl_mouse.c b/tests/sdl_mouse.c
index f0282ab1..ff4f522b 100644
--- a/tests/sdl_mouse.c
+++ b/tests/sdl_mouse.c
@@ -64,6 +64,6 @@ void main_2(void* arg) {
emscripten_run_script("window.simulateMouseEvent(30, 77, -1)"); // move some more
emscripten_run_script("window.simulateMouseEvent(30, 77, 1)"); // trigger the end
- emscripten_set_main_loop(one, 0);
+ emscripten_set_main_loop(one, 0, 0);
}
diff --git a/tests/sdl_quit.c b/tests/sdl_quit.c
index 1a07526f..3d98c15c 100644
--- a/tests/sdl_quit.c
+++ b/tests/sdl_quit.c
@@ -26,7 +26,7 @@ int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE);
- emscripten_set_main_loop(one, 0);
+ emscripten_set_main_loop(one, 0, 0);
emscripten_run_script("setTimeout(function() { window.close() }, 2000)");
}
diff --git a/tests/websockets.c b/tests/websockets.c
index 6e81eb47..8a8a0919 100644
--- a/tests/websockets.c
+++ b/tests/websockets.c
@@ -115,7 +115,7 @@ int main(void)
}
#if EMSCRIPTEN
- emscripten_set_main_loop(iter, 0);
+ emscripten_set_main_loop(iter, 0, 0);
#else
while (!done) iter(NULL);
#endif
diff --git a/tests/websockets_bi.c b/tests/websockets_bi.c
index bea512db..73d061d2 100644
--- a/tests/websockets_bi.c
+++ b/tests/websockets_bi.c
@@ -124,7 +124,7 @@ int main(void)
"iframe.src = 'side.html';"
"document.body.appendChild(iframe);"
"console.log('added.');");
- emscripten_set_main_loop(iter, 0);
+ emscripten_set_main_loop(iter, 0, 0);
#else
while (!done) iter(NULL);
#endif
diff --git a/tests/websockets_bi_listener.c b/tests/websockets_bi_listener.c
index 21005cc5..587fbed2 100644
--- a/tests/websockets_bi_listener.c
+++ b/tests/websockets_bi_listener.c
@@ -141,7 +141,7 @@ int main(void)
"iframe.src = 'side.html';"
"document.body.appendChild(iframe);"
"console.log('added.');");
- emscripten_set_main_loop(iter, 0);
+ emscripten_set_main_loop(iter, 0, 0);
#else
while (!done) iter(NULL);
#endif
diff --git a/tests/websockets_gethostbyname.c b/tests/websockets_gethostbyname.c
index 847187c7..6b8777f1 100644
--- a/tests/websockets_gethostbyname.c
+++ b/tests/websockets_gethostbyname.c
@@ -122,7 +122,7 @@ int main(void)
}
#if EMSCRIPTEN
- emscripten_set_main_loop(iter, 0);
+ emscripten_set_main_loop(iter, 0, 0);
#else
while (!done) iter(NULL);
#endif