Repository navigation
Run sync listeners of bundled packets on the main thread - #3674
Open
rishabhvenu wants to merge 1 commit into
Open
rishabhvenu wants to merge 1 commit into
rishabhvenu wants to merge 1 commit into
Conversation
processOutbound only checked the BUNDLE packet type for main-thread listeners before the bundle was unpacked, so a synchronous listener registered for a packet inside the bundle ran on the thread the bundle was sent from. Fixes dmulloy2#3665
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3665
Cause
NettyChannelInjector.processOutbound()decides whether a packet has to be moved to the main thread by askinghasMainThreadListenerfor the packet's own type. For a bundle that isBUNDLE, butOutboundPacketListenerSetthen unpacks the bundle and invokes the listeners of every packet inside it on the same thread. A synchronous listener registered only for one of the bundled packet types was therefore called on whatever thread the bundle was being sent from.Fix
When the outbound packet is a bundle and nothing is registered for
BUNDLEitself, the check now also looks at the types of the packets inside it. If any of them has a main-thread listener, the whole bundle is rescheduled to the main thread, the same way a single packet is.The lookup only runs for bundles sent off the main thread (the thread check comes first now), and it reads the raw packet list, one registry lookup per packet, without creating containers for them.
PacketContainerfor the outer packet is created a few lines earlier than before so the check can use it.Testing
NettyChannelInjectorTestcovers the check: a bundle containing a listened type, a bundle with aBUNDLElistener, a bundle with no listened types, and a plain packet. The first case fails if the bundle lookup is taken out again../gradlew testpasses (193 tests inpaper, 16 skipped, 2 inspigot).onPacketSendinglistener forSYSTEM_CHAT, and a bundle of two system chat packets sent from an async scheduler thread while one client is connected.Craft Scheduler Thread - 3,Bukkit.isPrimaryThread()falseServer thread,Bukkit.isPrimaryThread()trueIn both runs a single unbundled packet sent the same way reached the listener on the server thread, and the client received all three messages.
On Paper 1.21.4 a bundle sent with
sendServerPacketfrom an async thread was already processed on the server thread on master, so that route does not show the problem there. The test plugin therefore calls the server'sConnection#sendPacketfrom the async thread by reflection, which is the step vanilla'sConnection#sendtakes for a connected player.Not covered
PacketFilterManager.runMonitorListeners(monitor listeners for packets sent withfilters = false) makes the same per-type decision for bundles. I left it alone to keep this to the reported path.