Skip to content

Commit 417fac2

Browse files
committed
Add patch to fix race condition especially during commissioning
This adds a patch which removes some obsolte callback handling. This especially fixes race condition when calling the Python Device Controller from multiple Threads. Commands with callbacks (e.g. commissioning or opening the commissioning window) have a high likelyhood to get released early when other functions of the Python Device Controller were called simultaniously. Note that this doesn't make the Python Device Controller fully reentrant: All calls which have callbacks still share a single event object. This fixes merly some unnecessary non-reentrancy.
1 parent ed9b9d3 commit 417fac2

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
From 20f1c72293991ad01043660b777e53be0992bae5 Mon Sep 17 00:00:00 2001
2+
Message-ID: <20f1c72293991ad01043660b777e53be0992bae5.1717003814.git.stefan@agner.ch>
3+
From: Stefan Agner <stefan@agner.ch>
4+
Date: Wed, 29 May 2024 19:05:43 +0200
5+
Subject: [PATCH] [Python] Remove obsolete callback handling
6+
7+
The Call() function currently still has some callback handling code
8+
the completeEvent and callbackRes variables. These are only used when
9+
callbacks are in play, like pychip_DeviceController_Commission or
10+
pychip_DeviceController_OpenCommissioningWindow. When calling these
11+
functions CallAsyncWithCompleteCallback() needs to be used (and is
12+
beeing used in all cases).
13+
14+
In practice, on single threaded applications this is not a problem.
15+
However, when calling the SDK from multiple threads, then another Call()
16+
Might accidentally release a call to CallAsyncWithCompleteCallback()
17+
early.
18+
---
19+
src/controller/python/chip/ChipStack.py | 19 -------------------
20+
1 file changed, 19 deletions(-)
21+
22+
diff --git a/src/controller/python/chip/ChipStack.py b/src/controller/python/chip/ChipStack.py
23+
index 6df7e41de4..a8f07941a2 100644
24+
--- a/src/controller/python/chip/ChipStack.py
25+
+++ b/src/controller/python/chip/ChipStack.py
26+
@@ -164,9 +164,6 @@ class AsyncCallableHandle:
27+
return self._res
28+
29+
30+
-_CompleteFunct = CFUNCTYPE(None, c_void_p, c_void_p)
31+
-_ErrorFunct = CFUNCTYPE(None, c_void_p, c_void_p,
32+
- c_ulong, POINTER(DeviceStatusStruct))
33+
_LogMessageFunct = CFUNCTYPE(
34+
None, c_int64, c_int64, c_char_p, c_uint8, c_char_p)
35+
_ChipThreadTaskRunnerFunct = CFUNCTYPE(None, py_object)
36+
@@ -241,21 +238,11 @@ class ChipStack(object):
37+
self.logger.addHandler(logHandler)
38+
self.logger.setLevel(logging.DEBUG)
39+
40+
- def HandleComplete(appState, reqState):
41+
- self.callbackRes = True
42+
- self.completeEvent.set()
43+
-
44+
- def HandleError(appState, reqState, err, devStatusPtr):
45+
- self.callbackRes = self.ErrorToException(err, devStatusPtr)
46+
- self.completeEvent.set()
47+
-
48+
@_ChipThreadTaskRunnerFunct
49+
def HandleChipThreadRun(callback):
50+
callback()
51+
52+
self.cbHandleChipThreadRun = HandleChipThreadRun
53+
- self.cbHandleComplete = _CompleteFunct(HandleComplete)
54+
- self.cbHandleError = _ErrorFunct(HandleError)
55+
# set by other modules(BLE) that require service by thread while thread blocks.
56+
self.blockingCB = None
57+
58+
@@ -357,14 +344,8 @@ class ChipStack(object):
59+
This function is a wrapper of PostTaskOnChipThread, which includes some handling of application specific logics.
60+
Calling this function on CHIP on CHIP mainloop thread will cause deadlock.
61+
'''
62+
- # throw error if op in progress
63+
- self.callbackRes = None
64+
- self.completeEvent.clear()
65+
with self.networkLock:
66+
res = self.PostTaskOnChipThread(callFunct).Wait(timeoutMs)
67+
- self.completeEvent.set()
68+
- if res == 0 and self.callbackRes is not None:
69+
- return self.callbackRes
70+
return res
71+
72+
def CallAsync(self, callFunct):
73+
--
74+
2.45.1
75+

0 commit comments

Comments
 (0)