Conversation
CoreBluetooth rediscovers a peripheral's services on its own, for
instance when the peripheral indicates Service Changed. The descriptor
callbacks for that rediscovery reach check_discovered after the reply to
the original discover_services request has gone out. No future is
waiting, and the panic ("We should still have a future at this point!")
kills the CoreBluetooth thread along with every later central operation.
Seen connecting from macOS to a BlueZ peripheral that registers its GATT
application after the connection. The first discovery succeeded, and
the rediscovery that followed panicked.
The service map is already up to date when check_discovered runs, so a
rediscovery with no pending request now logs at trace level and
returns. The regression test completes descriptor discovery with no
pending request, then checks that a later request still gets its reply.
grmrgecko
force-pushed
the
fix/corebluetooth-late-rediscovery
branch
from
September 22, 2026 03:03
f79a356 to
3a9da4b
Compare
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.
On macOS, CoreBluetooth rediscovers a peripheral's services on its own, for instance when the peripheral indicates Service Changed. The descriptor callbacks for that rediscovery reach
PeripheralInternal::check_discoveredafter the reply to the originaldiscover_servicesrequest has gone out.services_discovered_future_stateisNone, and this panics:The panic kills the CoreBluetooth thread, so every later central operation in the process fails until it restarts.
I ran into it on 0.13.2, connecting from macOS to a Linux machine acting as a BLE MIDI peripheral through BlueZ. BlueZ registers the peripheral's GATT application after the connection is up. The first discovery succeeded, and the rediscovery that followed panicked. #223 reported the same message in 2022 from a different trigger.
By the time
check_discoveredruns,set_characteristicsandset_characteristic_descriptorshave already updated the service map, so a rediscovery with no pending request has nothing to reply to. It now logs at trace level and returns. Theis_none()check and the latertake().unwrap()become onelet Some(..) = take() else.rediscovery_without_a_pending_request_is_ignoreduses the same setup asdescriptor_discovery_error_completes_service_discovery_without_descriptors. It completes descriptor discovery with no pending request, which panicked before this change, then checks that a request made afterwards still gets its reply. With the change applied, the macOS central connected to the BlueZ peripheral and exchanged MIDI in both directions.