Skip to content

Commit

Permalink
Add lock around handlers list
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsaxon committed Apr 10, 2020
1 parent dc570c9 commit d8f3508
Showing 1 changed file with 29 additions and 25 deletions.
54 changes: 29 additions & 25 deletions zeroconf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,7 @@ def __init__(
self.next_time = current_time_millis()
self.delay = delay
self._handlers_to_call = [] # type: List[List[Any]]
self._handler_lock = threading.Lock()

self._service_state_changed = Signal()

Expand Down Expand Up @@ -1436,42 +1437,44 @@ def update_record(self, zc: 'Zeroconf', now: float, record: DNSRecord) -> None:

def enqueue_callback(state_change: ServiceStateChange, name: str) -> None:

if state_change == ServiceStateChange.Updated:
with self._handler_lock:

if self._handlers_to_call.count([name, ServiceStateChange.Removed]) == 1:
return
if state_change == ServiceStateChange.Updated:

if self._handlers_to_call.count([name, ServiceStateChange.Added]) == 1:
warnings.warn("not adding update as adding", DeprecationWarning)
return
if self._handlers_to_call.count([name, ServiceStateChange.Removed]) == 1:
return

if self._handlers_to_call.count([name, ServiceStateChange.Updated]) == 1:
return
if self._handlers_to_call.count([name, ServiceStateChange.Added]) == 1:
warnings.warn("not adding update as adding", DeprecationWarning)
return

elif state_change == ServiceStateChange.Added:
if self._handlers_to_call.count([name, ServiceStateChange.Updated]) == 1:
return

if self._handlers_to_call.count([name, ServiceStateChange.Removed]) == 1:
self._handlers_to_call.remove([name, ServiceStateChange.Removed])
elif state_change == ServiceStateChange.Added:

if self._handlers_to_call.count([name, ServiceStateChange.Updated]) == 1:
warnings.warn("removing update as adding", DeprecationWarning)
self._handlers_to_call.remove([name, ServiceStateChange.Updated])
if self._handlers_to_call.count([name, ServiceStateChange.Removed]) == 1:
self._handlers_to_call.remove([name, ServiceStateChange.Removed])

if self._handlers_to_call.count([name, ServiceStateChange.Added]) == 1:
return
if self._handlers_to_call.count([name, ServiceStateChange.Updated]) == 1:
warnings.warn("removing update as adding", DeprecationWarning)
self._handlers_to_call.remove([name, ServiceStateChange.Updated])

elif state_change == ServiceStateChange.Removed:
if self._handlers_to_call.count([name, ServiceStateChange.Added]) == 1:
return

if self._handlers_to_call.count([name, ServiceStateChange.Added]) == 1:
self._handlers_to_call.remove([name, ServiceStateChange.Added])
elif state_change == ServiceStateChange.Removed:

if self._handlers_to_call.count([name, ServiceStateChange.Updated]) == 1:
self._handlers_to_call.remove([name, ServiceStateChange.Updated])
if self._handlers_to_call.count([name, ServiceStateChange.Added]) == 1:
self._handlers_to_call.remove([name, ServiceStateChange.Added])

if self._handlers_to_call.count([name, ServiceStateChange.Removed]) == 1:
return
if self._handlers_to_call.count([name, ServiceStateChange.Updated]) == 1:
self._handlers_to_call.remove([name, ServiceStateChange.Updated])

if self._handlers_to_call.count([name, ServiceStateChange.Removed]) == 1:
return

self._handlers_to_call.append([name, state_change])
self._handlers_to_call.append([name, state_change])

if record.type == _TYPE_PTR and record.name == self.type:
assert isinstance(record, DNSPointer)
Expand Down Expand Up @@ -1539,7 +1542,8 @@ def run(self) -> None:
self.delay = min(_BROWSER_BACKOFF_LIMIT * 1000, self.delay * 2)

if len(self._handlers_to_call) > 0 and not self.zc.done:
handler = self._handlers_to_call.pop(0)
with self._handler_lock:
handler = self._handlers_to_call.pop(0)
self._service_state_changed.fire(
zeroconf=self.zc, service_type=self.type, name=handler[0], state_change=handler[1]
)
Expand Down

0 comments on commit d8f3508

Please sign in to comment.