Bug 184285 - MessagePorts created in WebWorker thread stops working
Summary: MessagePorts created in WebWorker thread stops working
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: Safari 11
Hardware: Mac macOS 10.13
: P2 Normal
Assignee: Tadeu Zagallo
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-04-03 19:19 PDT by Yann Cabon
Modified: 2018-04-17 15:57 PDT (History)
13 users (show)

See Also:


Attachments
Patch (4.20 KB, patch)
2018-04-13 18:07 PDT, Tadeu Zagallo
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews104 for mac-sierra-wk2 (2.64 MB, application/zip)
2018-04-13 19:17 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews122 for ios-simulator-wk2 (2.24 MB, application/zip)
2018-04-13 19:40 PDT, EWS Watchlist
no flags Details
Patch (4.23 KB, patch)
2018-04-16 13:18 PDT, Tadeu Zagallo
no flags Details | Formatted Diff | Diff
Patch (4.30 KB, patch)
2018-04-17 11:24 PDT, Tadeu Zagallo
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yann Cabon 2018-04-03 19:19:04 PDT
Communication between MessagePort instances created in a WebWorker thread stops after time.
I suspect GC happening.
The following test case is in 2 parts. An html page and a worker script.
The worker creates a message channel and transfer one of the ports back to the main thread.
The ports start communicating then after some 18 exchanges, the communication stops.
I finally figured that if I kept the reference of the MessageChannel that create the ports around the problem disappeared.
I looks like this shouldn't happen.
The test cases creates some arraybuffers and discard them to trigger some GC.


Test case:

//---------------------------------------------------------------------------
// messagechannel_garbagecollected.html
//---------------------------------------------------------------------------

<html>

<body>
  <script>
    var worker = new Worker("./messagechannel_garbagecollected_worker.js");
    var arrays = [];

    worker.addEventListener("message", (event) => {
      var port = event.data.port;

      port.addEventListener("message", (event) => {
        document.body.innerHTML += event.data + "<br />";
        if (arrays.length === 10) {
          arrays = [];
        }
        arrays.push(new ArrayBuffer(500000));
        setTimeout(function() {
          port.postMessage("ping");
        }, 50);
      });

      port.start();
      port.postMessage("ping");
    });

  </script>
</body>

</html>

//---------------------------------------------------------------------------
// messagechannel_garbagecollected_worker.js
//---------------------------------------------------------------------------


var arrays = [];

function startup() {
  var channel = new MessageChannel();
  var port = channel.port1;
  var id = 0;

  port.addEventListener("message", (event) => {
    if (arrays.length === 10) {
      arrays = [];
    }
    arrays.push(new ArrayBuffer(50000));
    setTimeout(function() {
      port.postMessage("pong " + id++);
    }, 50);
  });
  port.start();

  // keeping a dummy reference to the channel keeps it working
  // port["channel"] = channel;

  self.postMessage({
    port: channel.port2
  }, [channel.port2]);
}

startup();
Comment 1 Radar WebKit Bug Importer 2018-04-06 21:02:41 PDT
<rdar://problem/39256714>
Comment 2 Tadeu Zagallo 2018-04-13 18:07:50 PDT
Created attachment 337935 [details]
Patch
Comment 3 EWS Watchlist 2018-04-13 19:17:20 PDT
Comment on attachment 337935 [details]
Patch

Attachment 337935 [details] did not pass mac-wk2-ews (mac-wk2):
Output: http://webkit-queues.webkit.org/results/7311332

New failing tests:
fast/events/message-channel-gc-4.html
Comment 4 EWS Watchlist 2018-04-13 19:17:22 PDT
Created attachment 337945 [details]
Archive of layout-test-results from ews104 for mac-sierra-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: ews104  Port: mac-sierra-wk2  Platform: Mac OS X 10.12.6
Comment 5 EWS Watchlist 2018-04-13 19:40:08 PDT
Comment on attachment 337935 [details]
Patch

Attachment 337935 [details] did not pass ios-sim-ews (ios-simulator-wk2):
Output: http://webkit-queues.webkit.org/results/7311418

New failing tests:
fast/events/message-channel-gc-4.html
Comment 6 EWS Watchlist 2018-04-13 19:40:09 PDT
Created attachment 337948 [details]
Archive of layout-test-results from ews122 for ios-simulator-wk2

The attached test failures were seen while running run-webkit-tests on the ios-sim-ews.
Bot: ews122  Port: ios-simulator-wk2  Platform: Mac OS X 10.13.4
Comment 7 Tadeu Zagallo 2018-04-16 13:18:24 PDT
Created attachment 338028 [details]
Patch
Comment 8 Darin Adler 2018-04-16 18:03:26 PDT
Comment on attachment 338028 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=338028&action=review

> Source/WebCore/dom/MessagePort.cpp:70
> -        allMessagePorts().remove(m_identifier);
> +        if (allMessagePorts().get(m_identifier) == this)
> +            allMessagePorts().remove(m_identifier);

The correct way to implement this without double hashing is:

    auto iterator = allMessagePorts().find(m_identifier);
    if (iterator != allMessagePorts().end() && iterator->value == this)
        allMessagePorts().remove(iterator);

Messier than the above, but avoids a second hash table lookup.
Comment 9 Tadeu Zagallo 2018-04-17 11:24:44 PDT
Created attachment 338133 [details]
Patch
Comment 10 WebKit Commit Bot 2018-04-17 15:57:34 PDT
Comment on attachment 338133 [details]
Patch

Clearing flags on attachment: 338133

Committed r230735: <https://trac.webkit.org/changeset/230735>
Comment 11 WebKit Commit Bot 2018-04-17 15:57:36 PDT
All reviewed patches have been landed.  Closing bug.