CNA-BUG-160: Two open HttpNotificationChannel objects with the same name leave Find unable to locate one that is still open

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

Open assigns the registry entry for the name without checking for an existing channel, and when the later channel closes first it erases the name while the earlier one is still listening, so Find returns null for a live channel.

Identifier
CNA-BUG-160
Category
Bug
Subsystem
Networking & gamer services
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
Microsoft::Phone::Notification::HttpNotificationChannel constructor, Open(), Close() and static Find(const std::string&)

Expected behaviour

Find is documented to return “The channel, or null when no channel of that name is open”. The constructor documents the name as “unique within the application”, and Close erases the registry entry only when it still points at the closing channel, which shows the registry is meant to survive a replaced entry. Either a duplicate Open should be refused, or Find should keep answering while any channel of that name is open.

Actual behaviour at TARGET

Open does Registry()[channelName_] = this under the registry mutex, silently replacing an earlier channel. With channels A and B of one name both open, Find returns B. If B closes first, its Close finds the entry pointing at itself and erases the name although A is still listening, so Find returns null for a live channel. Nothing refuses or logs the duplicate.

Source locations

Evidence

Checked by reading HttpNotificationChannel.cpp at 009d40f5; the file is unchanged since the earlier recorded pin. Not executed.

Focused reproduction

Illustrative (not compiled for this entry):

using Microsoft::Phone::Notification::HttpNotificationChannel;
HttpNotificationChannel a("scores", "svc");
HttpNotificationChannel b("scores", "svc");
a.Open();
b.Open();
b.Close();
// a is still listening, but Find no longer sees it:
assert(HttpNotificationChannel::Find("scores") == nullptr);

Current tests

HttpNotificationChannelTest.AnOpenChannelCanBeFoundByName uses a single channel; no test opens two channels with one name.

Regression test

Open two channels with one name, close the second, and require Find to return the first; or require the second Open to throw.

Blast radius

Ports that keep an old channel object alive while opening a new one of the same name. The Windows Phone pattern of calling Find first and creating a channel only when none is found avoids the case.

Workaround

Keep the names of open channels unique: close or destroy the old channel before opening a new one with the same name.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Known issues
Bug index