GeezerVison is showing github.com — worker: handle detached `MessagePort` from a different context · nodejs/node@87be790
File tree
Expand file treeCollapse file tree
Open diff view settings
Expand file treeCollapse file tree
Open diff view settings
Collapse file
Copy file name to clipboardExpand all lines: src/node_messaging.cc +7Lines changed: 7 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -789,6 +789,13 @@ MaybeLocal<Value> MessagePort::ReceiveMessage(Local<Context> context, |
789 | 789 |
|
790 | 790 | void MessagePort::OnMessage(MessageProcessingMode mode) { |
791 | 791 | Debug(this, "Running MessagePort::OnMessage()"); |
| 792 | + // Maybe the async handle was triggered empty or more than needed. |
| 793 | + // The data_ could be freed or, the handle has been/is being closed. |
| 794 | + // A possible case for this, is transfer the MessagePort to another |
| 795 | + // context, it will call the constructor and trigger the async handle empty. |
| 796 | + // Because all data was sent from the preivous context. |
| 797 | + if (IsDetached()) return; |
| 798 | + |
792 | 799 | HandleScope handle_scope(env()->isolate()); |
793 | 800 | Local<Context> context = |
794 | 801 | object(env()->isolate())->GetCreationContext().ToLocalChecked(); |
|
Collapse file
Copy file name to clipboardExpand all lines: test/parallel/test-worker-workerdata-messageport.js +28-2Lines changed: 28 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | 3 | require('../common'); |
4 | | -const assert = require('assert'); |
| 4 | +const assert = require('node:assert'); |
5 | 5 |
|
6 | 6 | const { |
7 | 7 | Worker, MessageChannel |
8 | | -} = require('worker_threads'); |
| 8 | +} = require('node:worker_threads'); |
9 | 9 |
|
10 | 10 | const channel = new MessageChannel(); |
11 | 11 | const workerData = { mesage: channel.port1 }; |
@@ -61,3 +61,29 @@ const meowScript = () => 'meow'; |
61 | 61 | 'listed in transferList' |
62 | 62 | }); |
63 | 63 | } |
| 64 | + |
| 65 | +{ |
| 66 | + // Should not crash when MessagePort is transferred to another context. |
| 67 | + // https://github.com/nodejs/node/issues/49075 |
| 68 | + const channel = new MessageChannel(); |
| 69 | + new Worker(` |
| 70 | + const { runInContext, createContext } = require('node:vm') |
| 71 | + const { workerData } = require('worker_threads'); |
| 72 | + const context = createContext(Object.create(null)); |
| 73 | + context.messagePort = workerData.messagePort; |
| 74 | + runInContext( |
| 75 | + \`messagePort.postMessage("Meow")\`, |
| 76 | + context, |
| 77 | + { displayErrors: true } |
| 78 | + ); |
| 79 | + `, { |
| 80 | + eval: true, |
| 81 | + workerData: { messagePort: channel.port2 }, |
| 82 | + transferList: [channel.port2] |
| 83 | + }); |
| 84 | + channel.port1.on( |
| 85 | + 'message', |
| 86 | + (message) => |
| 87 | + assert.strictEqual(message, 'Meow') |
| 88 | + ); |
| 89 | +} |