Open Bug 758004 Opened 12 years ago Updated 2 years ago

WebSocket callbacks can trigger while alert() is displayed, breaking execution order of my code and causing corruption.

Categories

(Core :: DOM: Core & HTML, defect, P5)

12 Branch
x86
macOS
defect

Tracking

()

UNCONFIRMED

People

(Reporter: mikelehen, Unassigned)

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0
Build ID: 20120420145725

Steps to reproduce:

http://jsfiddle.net/N4Wcd/ has a minimal repro.


Actual results:

Between the first and second alert() statements, the websocket callback runs, changing the value of x.


Expected results:

All JavaScript operations should be serialized and run on the same thread.

As-is, this is really bad.  I work on Firebase (a complex networking / data storage API) which talks to our servers through WebSockets and runs user code through callbacks.  If the user code does an alert(), it can completely corrupt our library's state, since it's built assuming that the javascript VM is single-threaded.
Summary: WebSocket callbacks occur on separate javascript thread. → WebSocket callbacks occur on separate javascript thread (causing state corruption in my app).
Component: Untriaged → DOM
Product: Firefox → Core
QA Contact: untriaged → general
JS runs in one thread (unless workers are used). Alert spins event loop (it is bad yes).
showModalDialog has similar behavior (and even per spec)
Olli is right: there are various primitives in the web platform defined as spinning the event loop (and more things that do it in practice in browsers).  So while web code is always single-threaded it _can_ be reentered off event handlers if you call something that spins the event loop...

If you're calling arbitrary user code you simply can't rely on it not spinning the event loop, unfortunately.  Which means you need to assume that any event handler can always be reentered if you call arbitrary user code from it.
[Updated title]

Would be nice if somebody could clarify whether there's any intention to fix this.  It sounds to me like this is a case of Firefox implementation details leaking through in an undesirable way.

I don't know what spec Olli is mentioning, but as an HTML / JavaScript developer, I've never needed to be aware of the event loop's behavior before.  Every other browser I tested (Chrome, Safari, IE, etc.) seems to behave as I would expect (not calling other JS code reentrantly from my own JS code).

It certainly seems like this /could/ be fixed (e.g. never run JS code except from the outermost event loop or whatever).  So I still think it's a bug in Firefox, and a pretty nasty one as it conflicts with my core expectations about how my code is going to be executed.

I could be missing something though.
Summary: WebSocket callbacks occur on separate javascript thread (causing state corruption in my app). → WebSocket callbacks can trigger while alert() is displayed, breaking execution order of my code and causing corruption.
This is a bug in Firefox.  We intend to fix it eventually.  There is currently no timeframe for fixing it.  It will probably be months or years before this is fixed.
Great, thanks for clarifying!
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046

Move all DOM bugs that haven’t been updated in more than 3 years and has no one currently assigned to P5.

If you have questions, please contact :mdaly.
Priority: -- → P5
Component: DOM → DOM: Core & HTML

This also happens when JavaScript code is stopped at a breakpoint, e.g.:

var x;
var ws = new WebSocket('ws://localhost:12345');
ws.onerror = function() {
  x = 2;
};

x = 1;
debugger;
if (x === 2) {
  alert("This can't happen!");
}

I guess it's not that different from an alert, but it is very much counter-intuitive that JavaScript can run in the background while the "main thread" is paused.

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.