diff options
-rw-r--r-- | src/library_browser.js | 6 | ||||
-rw-r--r-- | system/include/emscripten/emscripten.h | 20 | ||||
-rw-r--r-- | tests/emscripten_api_browser.cpp | 2 | ||||
-rw-r--r-- | tests/emscripten_api_browser_infloop.cpp | 41 | ||||
-rw-r--r-- | tests/emscripten_fs_api_browser.cpp | 2 | ||||
-rw-r--r-- | tests/enet_client.c | 2 | ||||
-rw-r--r-- | tests/enet_server.c | 2 | ||||
-rwxr-xr-x | tests/runner.py | 3 | ||||
-rw-r--r-- | tests/sdl_canvas_palette_2.c | 2 | ||||
-rw-r--r-- | tests/sdl_mouse.c | 2 | ||||
-rw-r--r-- | tests/sdl_quit.c | 2 | ||||
-rw-r--r-- | tests/websockets.c | 2 | ||||
-rw-r--r-- | tests/websockets_bi.c | 2 | ||||
-rw-r--r-- | tests/websockets_bi_listener.c | 2 | ||||
-rw-r--r-- | tests/websockets_gethostbyname.c | 2 |
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 |