Skip to content

fix: prevent NPE in RetriableStream when cancel() races start() (#12964) [fj4WqyCCw3C5ShR1RfB7MoBPTpkRrBFYP1uT35g3MvT] - #12965

Open
waterWang wants to merge 1 commit into
grpc:masterfrom
waterWang:fix/retriablestream-npe-12964
Open

fix: prevent NPE in RetriableStream when cancel() races start() (#12964) [fj4WqyCCw3C5ShR1RfB7MoBPTpkRrBFYP1uT35g3MvT]#12965
waterWang wants to merge 1 commit into
grpc:masterfrom
waterWang:fix/retriablestream-npe-12964

Conversation

@waterWang

Copy link
Copy Markdown

Fix: Prevent NPE in RetriableStream when cancel() races start()

Bug: When cancel() is called through ClientCallStreamObserver (from application code in ClientResponseObserver.beforeStart()) before RetriableStream.start() completes, safeCloseMasterListener tries to dereference masterListener which is still null, causing an NPE.

Root cause: ClientCallImpl.startInternal assigns the stream at line 250 and starts it at line 285. RetriableStream.masterListener is only assigned as the first statement of start() (line 388). A cancel() arriving in that window passes the stream != null guard in cancelInternal but finds masterListener null.

Fix (two changes):

  1. safeCloseMasterListener: Null-check masterListener before dereferencing. If masterListener is null (cancel before start), the close reason is already saved in savedCloseMasterListenerReason and start() will pick it up.

  2. start(): After assigning masterListener, check if savedCloseMasterListenerReason is already set (from a prior cancel). If so, close immediately with the saved reason instead of proceeding with the normal start flow.

Fixes #12964

@linux-foundation-easycla

Copy link
Copy Markdown

CLA Not Signed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NPE in RetriableStream when ClientCallStreamObserver.cancel() races ClientCall.start()

1 participant