On linux, using mdns, there's a race that can make ServiceWatcher not report devices in some situations when the desired entry is already cached. The basic scenario is this:
Attempt to list devices under the service name "_ipp._tcp.local" using ServiceDiscoveryDeviceLister (which is mostly a thin wrapper around ServiceWatcher
Start() calls ReadCachedServices(), which immediately resolves the PTR record for _ipp._tcp.local from the cache which contains a printer named 'yourPrinter._ipp._tcp.local'
This bubbles up to ServiceWatcherImpl::OnTransactionResponse, which calls AddService for 'yourPrinter._ipp._tcp.local', which creates a ServiceListener entry in services_, and also schedules a call do DeliverDeferredUpdate with the appropriate record.
So far, so good.
At this point ServiceWatcher::Start() is done and we jump straight into ServiceWatcher::DiscoverNewServices(true).
in ServiceWatcherImpl::DiscoverNewServices, if force_update is true, the first thing we do is clear services_, and then we go on and create the mdns network transactions to look for new services.
At this point DiscoverNewServices() finishes, and we pretty much immediately execute the DeliverDeferredUpdate callback thatt was acheduled earlier.
However, since services_ was cleared, and the _ipp._tcp.local dns transaction (which is going out to the network) hasn't finished yet, there's no longer an entry in services_ for 'yourPrinter._ipp._tcp.local', which means we never propogate the callback.
Then, when the *network* transactions scheduled by DiscoverNewServices() complete, they find that their contents match what's already in the cache, so the also decline to propagate a callback upwards.
Comment 1 by justincarlson@chromium.org
, Jun 27 2017