Skip to content

Commit 1113704

Browse files
mrjerryjohnspull[bot]
authored andcommitted
Initial commit (#19832)
1 parent 2159931 commit 1113704

File tree

1 file changed

+47
-38
lines changed

1 file changed

+47
-38
lines changed

src/controller/python/chip/clusters/Attribute.py

+47-38
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,7 @@ def __init__(self, future: Future, eventLoop, devCtrl, returnClusterObject: bool
600600
self._changedPathSet = set()
601601
self._pReadClient = None
602602
self._pReadCallback = None
603+
self._resultError = None
603604

604605
def SetClientObjPointers(self, pReadClient, pReadCallback):
605606
self._pReadClient = pReadClient
@@ -608,7 +609,7 @@ def SetClientObjPointers(self, pReadClient, pReadCallback):
608609
def GetAllEventValues(self):
609610
return self._events
610611

611-
def _handleAttributeData(self, path: AttributePathWithListIndex, dataVersion: int, status: int, data: bytes):
612+
def handleAttributeData(self, path: AttributePathWithListIndex, dataVersion: int, status: int, data: bytes):
612613
try:
613614
imStatus = status
614615
try:
@@ -629,10 +630,7 @@ def _handleAttributeData(self, path: AttributePathWithListIndex, dataVersion: in
629630
except Exception as ex:
630631
logging.exception(ex)
631632

632-
def handleAttributeData(self, path: AttributePath, dataVersion: int, status: int, data: bytes):
633-
self._handleAttributeData(path, dataVersion, status, data)
634-
635-
def _handleEventData(self, header: EventHeader, path: EventPath, data: bytes, status: int):
633+
def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, status: int):
636634
try:
637635
eventType = _EventIndex.get(str(path), None)
638636
eventValue = None
@@ -671,19 +669,8 @@ def _handleEventData(self, header: EventHeader, path: EventPath, data: bytes, st
671669
except Exception as ex:
672670
logging.exception(ex)
673671

674-
def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, status: int):
675-
self._handleEventData(header, path, data, status)
676-
677-
def _handleError(self, chipError: int):
678-
if not self._future.done():
679-
self._future.set_exception(
680-
chip.exceptions.ChipStackError(chipError))
681-
self._subscription_handler.OnErrorCb(chipError, self._subscription_handler)
682-
683672
def handleError(self, chipError: int):
684-
self._event_loop.call_soon_threadsafe(
685-
self._handleError, chipError
686-
)
673+
self._resultError = chipError
687674

688675
def _handleSubscriptionEstablished(self, subscriptionId):
689676
if not self._future.done():
@@ -713,9 +700,28 @@ def _handleReportEnd(self):
713700
self._changedPathSet = set()
714701

715702
def _handleDone(self):
703+
#
704+
# We only set the exception/result on the future in this _handleDone call (if it hasn't
705+
# already been set yet, which can be in the case of subscriptions) since doing so earlier
706+
# would result in the callers awaiting the result to
707+
# move on, possibly invalidating the provided _event_loop.
708+
#
716709
if not self._future.done():
717-
self._future.set_result(AsyncReadTransaction.ReadResponse(
718-
attributes=self._cache.attributeCache, events=self._events))
710+
if self._resultError:
711+
if self._subscription_handler:
712+
self._subscription_handler.OnErrorCb(chipError, self._subscription_handler)
713+
else:
714+
self._future.set_exception(chip.exceptions.ChipStackError(chipError))
715+
else:
716+
self._future.set_result(AsyncReadTransaction.ReadResponse(
717+
attributes=self._cache.attributeCache, events=self._events))
718+
719+
#
720+
# Decrement the ref on ourselves to match the increment that happened at allocation.
721+
# This happens synchronously as part of handling done to ensure the object remains valid
722+
# right till the very end.
723+
#
724+
ctypes.pythonapi.Py_DecRef(ctypes.py_object(self))
719725

720726
def handleDone(self):
721727
self._event_loop.call_soon_threadsafe(self._handleDone)
@@ -732,31 +738,36 @@ class AsyncWriteTransaction:
732738
def __init__(self, future: Future, eventLoop):
733739
self._event_loop = eventLoop
734740
self._future = future
735-
self._res = []
741+
self._resultData = []
742+
self._resultError = None
736743

737-
def _handleResponse(self, path: AttributePath, status: int):
744+
def handleResponse(self, path: AttributePath, status: int):
738745
try:
739746
imStatus = chip.interaction_model.Status(status)
740-
self._res.append(AttributeWriteResult(Path=path, Status=imStatus))
747+
self._resultData.append(AttributeWriteResult(Path=path, Status=imStatus))
741748
except:
742-
self._res.append(AttributeWriteResult(Path=path, Status=status))
743-
744-
def handleResponse(self, path: AttributePath, status: int):
745-
self._event_loop.call_soon_threadsafe(
746-
self._handleResponse, path, status)
747-
748-
def _handleError(self, chipError: int):
749-
self._future.set_exception(
750-
chip.exceptions.ChipStackError(chipError))
749+
self._resultData.append(AttributeWriteResult(Path=path, Status=status))
751750

752751
def handleError(self, chipError: int):
753-
self._event_loop.call_soon_threadsafe(
754-
self._handleError, chipError
755-
)
752+
self._resultError = chipError
756753

757754
def _handleDone(self):
758-
if not self._future.done():
759-
self._future.set_result(self._res)
755+
#
756+
# We only set the exception/result on the future in this _handleDone call,
757+
# since doing so earlier would result in the callers awaiting the result to
758+
# move on, possibly invalidating the provided _event_loop.
759+
#
760+
if self._resultError is not None:
761+
self._future.set_exception(chip.exceptions.ChipStackError(self._resultError))
762+
else:
763+
self._future.set_result(self._resultData)
764+
765+
#
766+
# Decrement the ref on ourselves to match the increment that happened at allocation.
767+
# This happens synchronously as part of handling done to ensure the object remains valid
768+
# right till the very end.
769+
#
770+
ctypes.pythonapi.Py_DecRef(ctypes.py_object(self))
760771

761772
def handleDone(self):
762773
self._event_loop.call_soon_threadsafe(self._handleDone)
@@ -821,7 +832,6 @@ def _OnReportEndCallback(closure):
821832
@_OnReadDoneCallbackFunct
822833
def _OnReadDoneCallback(closure):
823834
closure.handleDone()
824-
ctypes.pythonapi.Py_DecRef(ctypes.py_object(closure))
825835

826836

827837
_OnWriteResponseCallbackFunct = CFUNCTYPE(
@@ -846,7 +856,6 @@ def _OnWriteErrorCallback(closure, chiperror: int):
846856
@_OnWriteDoneCallbackFunct
847857
def _OnWriteDoneCallback(closure):
848858
closure.handleDone()
849-
ctypes.pythonapi.Py_DecRef(ctypes.py_object(closure))
850859

851860

852861
def WriteAttributes(future: Future, eventLoop, device, attributes: List[AttributeWriteRequest], timedRequestTimeoutMs: int = None) -> int:

0 commit comments

Comments
 (0)