The reason for the yield list is more conceptual than solving a practical
problem. Consider this code
int x = 10;
int func() {
printf("%d\n", x);
emscripten_sleep(5);
printf("%d\n", x);
}
Normally, we would expect the same value to be printed twice :) But if code
runs during the sleep, it is breaking how C and C++ code normally runs,
someone could modify that global variable. It isn't "normal" for an event
to run in the middle there, and it might not even be valid if the function
on the stack has taken a lock, for example. The yieldlist is meant to warn
about this type of situation. But yes, as you said, the emterpreter is able
to make things work, from its perspective, it is just that the program
might have not expected this and have bugs.
Perhaps this is too paranoid, though. This isn't a new problem compared to
having multiple threads.
One option is for us to make emscripten_sleep_with_yield automatically
allow all code to run during the sleep, without needing a yield list, while
emscripten_sleep (and other sync operations) would still warn. Thoughts?
- Alon
On Fri, Jun 5, 2015 at 10:00 AM, awt <[email protected]> wrote:
> Unfortunately, just a simple mouse over the SDL2 window would require the
> following functions to be added to the yield list at least:
>
> -s NO_EXIT_RUNTIME=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 *-s
> EMTERPRETIFY_YIELDLIST=\"['_Emscripten_HandleMouseMove',
> '_Emscripten_HandleMouseFocus', '_SDL_SendMouseMotion',
> '_SDL_UpdateMouseFocus', '_SDL_PrivateSendMouseMotion',
> '_SDL_GetWindowSize', '_SDL_EventState', '_Emscripten_HandleFocus',
> '_SDL_PushEvent', '_SDL_GetTicks', '_SDL_RendererEventWatch',
> '_SDL_PeepEvents']\"* -s ASSERTIONS=1 --preload-file image.png -O3
> --profiling
>
> That will be 12 functions minimally and I gave up halfway thru. When you
> suggest that we queue the events for after the yield, are you saying that
> we can run each event handler after the code resumes from the sleep?
>
> Perhaps I don't really understand the yield assertions, why do we need
> them when all the SDL2 functions are already interpreted? Wouldn't the
> interpreter be able to push and pop the interpreted functions off the stack
> without the need to check if the functions are inside a yield list?
>
> On Saturday, June 6, 2015 at 12:30:44 AM UTC+8, Alon Zakai wrote:
>>
>> I think it would be just the mouse handler function, and a key handling
>> function, basically one for each event you need? Hopefully no other methods
>> would need to be added. Unless the handlers immediately call other code
>> instead of queuing.
>>
>> The only other approach is to not run compiled code while yielding, for
>> example to handle the events in JS and queue them for after the yield.
>> Perhaps we could add an option for that, but I worry it could be confusing.
>>
>> Maybe another option is to let people disable the yield assertions.
>> Again, though I worry this could be confusing.
>>
>> - Alon
>>
>>
>> On Fri, Jun 5, 2015 at 2:19 AM, awt <[email protected]> wrote:
>>
>>> Thanks for your reply Alon. You are right, I am using
>>> emscripten_sleep_with_yield in the following manner:
>>>
>>> for (;;)
>>> {
>>> SDL_Event event;
>>> while (SDL_PollEvent(&event)) {
>>> EventHandler(0, &event);
>>> }
>>> emscripten_sleep_with_yield(100);
>>> }
>>>
>>> The aim is to simulate a message loop in my application while still
>>> consuming mouse and keyboard events from the user. Going by the YIELDLIST
>>> method, I will end up with a large number of internal SDL functions in my
>>> list which is hard to maintain. There will also be other proprietary
>>> functions that I will need to add as well.
>>>
>>> In SDL1, we had emscripten_SDL_SetEventHandler that could abstract away
>>> the SDL internal functions but that function seems to be missing from the
>>> Emscripten SDL2 port.
>>>
>>> Do you have any suggestions on how we can reduce the number of functions
>>> in the YIELDLIST or another method to get around this?
>>>
>>> On Friday, June 5, 2015 at 12:55:59 AM UTC+8, Alon Zakai wrote:
>>>>
>>>> Based on the stack trace, that method is called from a JavaScript event
>>>> handler, I guess during a sleep. To enable that, you need to add the method
>>>> to the YIELDLIST, which is a list of methods that are ok to call during
>>>> sleep.
>>>>
>>>> The only other option is for emscripten to automatically delay the
>>>> event until after the sleep, I'm not sure if we considered doing that or
>>>> not, but in general it seems like it would make events show up later than
>>>> expected.
>>>>
>>>> - Alon
>>>>
>>>>
>>>> On Thu, Jun 4, 2015 at 3:54 AM, awt <[email protected]> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> I created a simple SDL2 application with the following pseudo code:
>>>>>
>>>>> 1. SDL_Init with SDL_INIT_VIDEO
>>>>> 2. SDL_CreateWindow
>>>>> 3. SDL_CreateRenderer
>>>>> 4. IMG_LoadTexture
>>>>> 5. SDL_QueryTexture
>>>>>
>>>>> After this, I try to start up my own message loop in the following
>>>>> manner:
>>>>>
>>>>> for (;;)
>>>>> {
>>>>> while ((1<=SDL_PeepEvents(&e, 1, SDL_GETEVENT, SDL_QUIT,
>>>>> SDL_LASTEVENT)))
>>>>> {
>>>>> //If user closes the window
>>>>> switch (e.type)
>>>>> {
>>>>> case SDL_QUIT:
>>>>> {
>>>>> cout << " SDL_QUIT received!!!";
>>>>> quitApp();
>>>>> return;
>>>>> }
>>>>> default:
>>>>> break;
>>>>> }
>>>>> }
>>>>> emscripten_sleep(10);
>>>>> }
>>>>>
>>>>> But when I click on the window, I get the following assert:
>>>>>
>>>>> Uncaught abort(-12) at Error
>>>>> at jsStackTrace
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:1325:13)
>>>>> at stackTrace
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:1342:22)
>>>>> at abort
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:33928:44)
>>>>> at Array._Emscripten_HandleMouseFocus
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:22365:54)
>>>>> at dynCall_iiii
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:31705:40)
>>>>> at Object.Runtime.dynCall
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:426:39)
>>>>> at Object.handlerFunc
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:1943:38)
>>>>> at HTMLCanvasElement.jsEventHandler
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:1846:24)
>>>>> This error happened during an emterpreter-async save or load of the
>>>>> stack. Was there non-emterpreted code on the stack during save (which is
>>>>> unallowed)? You may want to adjust EMTERPRETIFY_BLACKLIST,
>>>>> EMTERPRETIFY_WHITELIST, or EMTERPRETIFY_YIELDLIST (to consider certain
>>>>> functions ok to run during an emscripten_sleep_with_yield).
>>>>> This is what the stack looked like when we tried to save it: 1,Error
>>>>> at jsStackTrace
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:1325:13)
>>>>> at stackTrace
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:1342:22)
>>>>> at Object.EmterpreterAsync.handle
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:8744:40)
>>>>> at _emscripten_sleep
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:8767:24)
>>>>> at emterpret
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:13021:6)
>>>>> at Object.emterpret
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:12504:4)
>>>>> at resume
>>>>> (file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:8737:17)
>>>>> at
>>>>> file:///C:/work/git/SDLPrototypes/EventHandling/src/build/EventHandling.js:8770:11
>>>>>
>>>>> I find this strange because I am compiling with the following linker
>>>>> flags:
>>>>> -s NO_EXIT_RUNTIME=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s
>>>>> ASSERTIONS=1 --preload-file image.png -O3 -g3
>>>>>
>>>>> These are my compiler flags:
>>>>> -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s ASSERTIONS=1 -O3 -g3 -D_DEBUG_
>>>>> -D_DEBUG
>>>>>
>>>>> Since I did not specify any whitelist, I presume that all the code in
>>>>> my generated javascript should already be emterpreted. But somehow,
>>>>> _Emscripten_HandleMouseFocus isn't able to handle async states properly as
>>>>> this leads to a -12 abort.
>>>>>
>>>>> Does this mean that I have to manually add all "handle mouse"
>>>>> functions into the white or yield list? Or is there a better way around
>>>>> it?
>>>>> I am on emsdk 1.30.0.
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "emscripten-discuss" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to [email protected].
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "emscripten-discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.