Skip to content

Commit

Permalink
[mdns] unreference mDNS protocol when connection is closed
Browse files Browse the repository at this point in the history
This allows cleanly shutting down the mDNS once all connections are
closed. Otherwise we hit a ResourceWarning when the event loop exits.
  • Loading branch information
jlaine committed Jan 31, 2022
1 parent 6886d8d commit 0fdbac9
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/aioice/ice.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,27 @@
_mdns = threading.local()


async def get_or_create_mdns_protocol() -> mdns.MDnsProtocol:
async def get_or_create_mdns_protocol(subscriber: object) -> mdns.MDnsProtocol:
if not hasattr(_mdns, "lock"):
_mdns.lock = asyncio.Lock()
_mdns.protocol = None
_mdns.subscribers = set()
async with _mdns.lock:
if _mdns.protocol is None:
_mdns.protocol = await mdns.create_mdns_protocol()
_mdns.subscribers.add(subscriber)
return _mdns.protocol


async def unref_mdns_protocol(subscriber: object) -> None:
if hasattr(_mdns, "lock"):
async with _mdns.lock:
_mdns.subscribers.discard(subscriber)
if _mdns.protocol and not _mdns.subscribers:
await _mdns.protocol.close()
_mdns.protocol = None


def candidate_pair_priority(
local: Candidate, remote: Candidate, ice_controlling: bool
) -> int:
Expand Down Expand Up @@ -364,7 +375,7 @@ async def add_remote_candidate(self, remote_candidate: Candidate) -> None:

# resolve mDNS candidate
if mdns.is_mdns_hostname(remote_candidate.host):
mdns_protocol = await get_or_create_mdns_protocol()
mdns_protocol = await get_or_create_mdns_protocol(self)
remote_addr = await mdns_protocol.resolve(remote_candidate.host)
if remote_addr is None:
self.__log_info(
Expand Down Expand Up @@ -498,6 +509,9 @@ async def close(self) -> None:
if self._check_list and not self._check_list_done:
await self._check_list_state.put(ICE_FAILED)

# unreference mDNS
await unref_mdns_protocol(self)

self._nominated.clear()
for protocol in self._protocols:
await protocol.close()
Expand Down
5 changes: 5 additions & 0 deletions tests/test_ice.py
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,9 @@ async def test_add_remote_candidate_mdns_bad(self):
self.assertEqual(len(conn_a.remote_candidates), 0)
self.assertEqual(conn_a._remote_candidates_end, False)

# close
await conn_a.close()

@asynctest
async def test_add_remote_candidate_mdns_good(self):
"""
Expand All @@ -1118,6 +1121,8 @@ async def test_add_remote_candidate_mdns_good(self):
self.assertEqual(conn_a.remote_candidates[0].host, "1.2.3.4")
self.assertEqual(conn_a._remote_candidates_end, False)

# close
await conn_a.close()
await publisher.close()

@asynctest
Expand Down

0 comments on commit 0fdbac9

Please sign in to comment.