script: Prevent panic on multiple calls to MessagePort::close#43553
script: Prevent panic on multiple calls to MessagePort::close#43553sabbCodes wants to merge 1 commit intoservo:mainfrom
Conversation
|
@sabbCodes Is it possible to write an automated test for this? We could add a crash test to ensure the browser stays running. |
|
I actually wrote a basic test earlier, I didn't commit it because it's not included in the scope. My PC is running low on power rn - Nigeria is happening to me - I'll look into it when I get my PC charged and complete my other assigned tasks |
There was a problem hiding this comment.
Thanks for looking into this.
So the problem here is actually one of garbage collection.
Strictly speaking, you can call close as many times as you want in the same task, but after that the port is removed from the global because calling close sets the explicitly_closed flag, which is used when deciding to remove the port from the global.
So you could write two tests, and add them to https://github.com/servo/servo/blob/afa4b524ab75c28f5eb27872e6e8ba90f451c8b5/tests/wpt/tests/webmessaging/message-channels/close.any.js
One would be "close is idempotent within a task", where you just call close twice in a row, and the second one would be "close is idempotent across tasks".
For the second one, you'd have to keep a ref to the port and then queue a timer or something like that, and then call close a second time from within the subsequent task.
You can then confirm that what I say is correct, by removing the current changes(so leaving the panic), and confirming that only the second test panics.
As to the changes to be made to the code, I think we should take this one step further and do the following:
Dom<MessagePort>should be turned into an enum, with anEnabled(Dom<MessagePort>)variant and anotherDisabled(WeakRef<MessagePort>)variant.- The
explicitly_closedshould be removed, and when the port is closed, the dom should be downgraded to a weak ref. - At that point JS should not be able to call
Closeunless it holds a ref, meaning that the panic can stay, but it should be turned into a debug_assert!
@jdm please confirm that what I say about using the weakref makes sense.
|
Yes, I think.that design is sensible! |
|
Hi @gterzian I've been trying to work on your suggestion, however I think I may need some guidance if I'm going to be able to finish this, right now, I've tried converting the here's how I updated my test; below is the result I get on running |
|
Could you upload your changes to this PR so that we can provide better feedback? :) |
My PC about to shutdown, pushing as soon as I recharge |
|
🤖 Opened new upstream WPT pull request (web-platform-tests/wpt#58886) with upstreamable changes. |
|
✍ Updated existing upstream WPT pull request (web-platform-tests/wpt#58886) title and body. |
|
📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#58886). |
I prevented it from panicking when cross-task messages are sent to a port that had already been closed and garbage collected, then it passed the tests. |
My understanding of @gterzian 's comments is that just the |
These was actually part of my confusion, I thought the entire ManagedMessagePort was to be converted to a struct. Lemme try converting just the domport |
…ortDom an enum Signed-off-by: Sabb <sarafaabbas@gmail.com>
|
📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#58886). |
Converted
ManagedMessagePortfrom a struct to an enum withEnabledandDisabledvariants.Testing: ran
./mach test-wpt tests/wpt/tests/webmessaging/message-channels/close.any.jsresult: ```web-platform-test