Improve websocketd_RxPutC semaphore locking#21
Merged
terjeio merged 1 commit intogrblHAL:masterfrom May 6, 2026
Merged
Conversation
- The mutex now strictly guards the rxbuf head/tail/data update, matching the pattern already used by streamGetC, streamRxFlush, and websocketd_RxCancel. - enqueue_realtime_command is a function pointer that any plugin can override via streamSetRtHandler (e.g. MPG, keypad, macros, sender shims). rx_mux is created with xSemaphoreCreateMutex() (a non-recursive FreeRTOS mutex). If a custom handler ever calls back into websocketd_RxPutC (directly, or indirectly via stream code), the old version would attempt to take a mutex already held by the same task and block forever. The new version eliminates that hazard entirely. - websocketd_RxPutC runs from the lwIP/TCPIP task context (called from websocket_msg_parse inside websocket_recv). Holding rx_mux across an arbitrary, plugin-supplied callback meant the lwIP task could be blocked behind any work that handler did. The grbl protocol task also takes rx_mux in streamGetC to drain bytes — long handler execution under the lock would directly stall both the network RX path and grbl input. Shrinking the critical section to a few buffer-pointer updates removes that stall window and reduces the chance of a higher-priority task being held off by a lower-priority one.
Contributor
|
Did you manage to enter such a deadlock from your own custom code? |
Contributor
Author
|
Yes, I tested it using a ESP32. But that's not my custom code, the |
Contributor
Thank you. |
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.
rxbufupdate, matching the pattern already used bystreamGetC,streamRxFlush, andwebsocketd_RxCancel.enqueue_realtime_commandis a function pointer that any plugin can override viastreamSetRtHandler.rx_muxis created withxSemaphoreCreateMutex()(a non-recursive FreeRTOS mutex). If a custom handler ever calls back into websocketd_RxPutC (directly, or indirectly via stream code), the old version would attempt to take a mutex already held by the same task and block forever. The new version eliminates that hazard entirely.websocketd_RxPutCruns from the lwIP/TCPIP task context (called fromwebsocket_msg_parseinsidewebsocket_recv). Holdingrx_muxacross an arbitrary, plugin-supplied callback meant the lwIP task could be blocked behind any work that handler did. The grbl protocol task also takesrx_muxinstreamGetCto drain bytes — long handler execution under the lock would directly stall both the network RX path and grbl input. Shrinking the critical section to a few buffer-pointer updates removes that stall window and reduces the chance of a higher-priority task being held off by a lower-priority one.Behavior preservation