From 91d47227745ee86eb546daa3da4f51b4953e94d0 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 1 Aug 2023 10:57:43 -0400 Subject: [PATCH 1/6] Add python main loop work method --- src/controller/python/BUILD.gn | 8 ++ .../python/chip/native/ChipMainLoopWork.h | 39 ++++++++ .../native/ChipMainLoopWork_StackLock.cpp | 43 +++++++++ .../native/ChipMainLoopWork_WorkSchedule.cpp | 83 +++++++++++++++++ .../python/chip/tracing/TracingSetup.cpp | 92 +++++++++---------- 5 files changed, 215 insertions(+), 50 deletions(-) create mode 100644 src/controller/python/chip/native/ChipMainLoopWork.h create mode 100644 src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp create mode 100644 src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index 375a65cf7becbc..edac2d776358d1 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -33,6 +33,7 @@ config("controller_wno_deprecate") { declare_args() { chip_python_version = "0.0" chip_python_package_prefix = "chip" + chip_python_supports_stack_locking = (current_os != "mac") || (current_os != "ios") } shared_library("ChipDeviceCtrl") { @@ -78,11 +79,18 @@ shared_library("ChipDeviceCtrl") { "chip/internal/CommissionerImpl.cpp", "chip/logging/LoggingRedirect.cpp", "chip/native/PyChipError.cpp", + "chip/native/ChipMainLoopWork.h", "chip/tracing/TracingSetup.cpp", "chip/utils/DeviceProxyUtils.cpp", ] defines += [ "CHIP_CONFIG_MAX_GROUPS_PER_FABRIC=50" ] defines += [ "CHIP_CONFIG_MAX_GROUP_KEYS_PER_FABRIC=50" ] + + if (chip_python_supports_stack_locking) { + sources += [ "chip/native/ChipMainLoopWork_StackLock.cpp" ] + } else { + sources += [ "chip/native/ChipMainLoopWork_WorkSchedule.cpp" ] + } } else { sources += [ "chip/server/Options.cpp", diff --git a/src/controller/python/chip/native/ChipMainLoopWork.h b/src/controller/python/chip/native/ChipMainLoopWork.h new file mode 100644 index 00000000000000..d0b562e0464ece --- /dev/null +++ b/src/controller/python/chip/native/ChipMainLoopWork.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +namespace chip { +namespace MainLoopWork { + +/** + * Executes the given function in the CHIP main loop if one exists. + * + * If chip stack locking is available, this will lock the chip stack + * and execute `f`. + * + * If chip stack locking is not available: + * - if already in the chip main loop, this will execute `f` right away + * - if main loop running, this will schedule and WAIT for `f` to execute + * - if main loop is stopped, this will execute `f` right away + */ +void ExecuteInMainLoop(std::function f); + +} // namespace MainLoopWork +} // namespace chip diff --git a/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp b/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp new file mode 100644 index 00000000000000..843f3e7a555a6c --- /dev/null +++ b/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ChipMainLoopWork.h" + +#include + +namespace chip { +namespace MainLoopWork { +namespace { + +using chip::DeviceLayer::PlatformMgr; + +class ScopedStackLock +{ + public: + ScopedStackLock() { PlatformMgr().LockChipStack(); } + ~ScopedStackLock() { PlatformMgr().UnlockChipStack(); } +}; + +} // namespace + +void ExecuteInMainLoop(std::function f) { + ScopedStackLock lock; + f(); +} + +} // namespace MainLoopWork +} // namespace chip diff --git a/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp new file mode 100644 index 00000000000000..61f3b94b75b98a --- /dev/null +++ b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp @@ -0,0 +1,83 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ChipMainLoopWork.h" + +#include +#include + +namespace chip { +namespace MainLoopWork { +namespace { + +struct WorkData +{ + std::function callback; + sem_t done; + + WorkData() { sem_init(&done, 0 /* shared */, 0); } + ~WorkData() { sem_destroy(&done); } + void Post() { sem_post(&done); } + void Wait() { sem_wait(&done); } +}; + +void PerformWork(intptr_t arg) +{ + WorkData * work = reinterpret_cast(arg); + + work->callback(); + work->Post(); +} + + +} // namespace + +void ExecuteInMainLoop(std::function f) { + +#if CHIP_STACK_LOCK_TRACKING_ENABLED + if (chip::DeviceLayer::PlatformMgr().IsChipStackLockedByCurrentThread()) { + f(); + return; + } +#endif + +#if defined(__APPLE__) + if (chip::DeviceLayer::PlatformManagerImpl()::IsWorkQueueCurrentQueue()) { + f(); + return; + } +#endif + + + // NOTE: the code below assumes that chip main loop is running. + // if it does not, this will deadlock. + // + // When CHIP_STACK_LOCK_TRACKING_ENABLED, stack locking will detect + // main event loop not running, so this will not run when chip event + // loop is stopped + // + // The cases when this will deadlock is: + // - chip stack lock tracking is disabled + // - main chip loop is not started (or stopped already) + WorkData workdata; + workdata.callback = f; + chip::DeviceLayer::PlatformMgr().ScheduleWork(PerformWork, reinterpret_cast(&workdata)); + workdata.Wait(); +} + +} // namespace MainLoopWork +} // namespace chip diff --git a/src/controller/python/chip/tracing/TracingSetup.cpp b/src/controller/python/chip/tracing/TracingSetup.cpp index d09a655b74c633..73e0633b3bf373 100644 --- a/src/controller/python/chip/tracing/TracingSetup.cpp +++ b/src/controller/python/chip/tracing/TracingSetup.cpp @@ -16,8 +16,8 @@ * limitations under the License. */ +#include #include -#include #include #include @@ -27,17 +27,6 @@ #include namespace { - -using chip::DeviceLayer::PlatformMgr; - -class ScopedStackLock -{ -public: - ScopedStackLock() { PlatformMgr().LockChipStack(); } - - ~ScopedStackLock() { PlatformMgr().UnlockChipStack(); } -}; - chip::Tracing::Json::JsonBackend gJsonBackend; chip::Tracing::Perfetto::FileTraceOutput gPerfettoFileOutput; @@ -47,58 +36,61 @@ chip::Tracing::Perfetto::PerfettoBackend gPerfettoBackend; extern "C" void pychip_tracing_start_json_log(const char * file_name) { - - ScopedStackLock lock; - - gJsonBackend.CloseFile(); // just in case, ensure no file output - chip::Tracing::Register(gJsonBackend); + chip::MainLoopWork::ExecuteInMainLoop([] { + gJsonBackend.CloseFile(); // just in case, ensure no file output + chip::Tracing::Register(gJsonBackend); + }); } extern "C" PyChipError pychip_tracing_start_json_file(const char * file_name) { - ScopedStackLock lock; - - CHIP_ERROR err = gJsonBackend.OpenFile(file_name); - if (err != CHIP_NO_ERROR) - { - return ToPyChipError(err); - } - chip::Tracing::Register(gJsonBackend); - return ToPyChipError(CHIP_NO_ERROR); + CHIP_ERROR err = CHIP_NO_ERROR; + + chip::MainLoopWork::ExecuteInMainLoop([&err, file_name] { + err = gJsonBackend.OpenFile(file_name); + if (err != CHIP_NO_ERROR) + { + return; + } + chip::Tracing::Register(gJsonBackend); + }); + + return ToPyChipError(err); } extern "C" void pychip_tracing_start_perfetto_system() { - ScopedStackLock lock; - - chip::Tracing::Perfetto::Initialize(perfetto::kSystemBackend); - chip::Tracing::Perfetto::RegisterEventTrackingStorage(); - chip::Tracing::Register(gPerfettoBackend); + chip::MainLoopWork::ExecuteInMainLoop([] { + chip::Tracing::Perfetto::Initialize(perfetto::kSystemBackend); + chip::Tracing::Perfetto::RegisterEventTrackingStorage(); + chip::Tracing::Register(gPerfettoBackend); + }); } extern "C" PyChipError pychip_tracing_start_perfetto_file(const char * file_name) { - ScopedStackLock lock; - - chip::Tracing::Perfetto::Initialize(perfetto::kInProcessBackend); - chip::Tracing::Perfetto::RegisterEventTrackingStorage(); - - CHIP_ERROR err = gPerfettoFileOutput.Open(file_name); - if (err != CHIP_NO_ERROR) - { - return ToPyChipError(err); - } - chip::Tracing::Register(gPerfettoBackend); - - return ToPyChipError(CHIP_NO_ERROR); + CHIP_ERROR err = CHIP_NO_ERROR; + chip::MainLoopWork::ExecuteInMainLoop([&err, file_name] { + chip::Tracing::Perfetto::Initialize(perfetto::kInProcessBackend); + chip::Tracing::Perfetto::RegisterEventTrackingStorage(); + + err = gPerfettoFileOutput.Open(file_name); + if (err != CHIP_NO_ERROR) + { + return; + } + chip::Tracing::Register(gPerfettoBackend); + }); + + return ToPyChipError(err); } extern "C" void pychip_tracing_stop() { - ScopedStackLock lock; - - chip::Tracing::Perfetto::FlushEventTrackingStorage(); - gPerfettoFileOutput.Close(); - chip::Tracing::Unregister(gPerfettoBackend); - chip::Tracing::Unregister(gJsonBackend); + chip::MainLoopWork::ExecuteInMainLoop([] { + chip::Tracing::Perfetto::FlushEventTrackingStorage(); + gPerfettoFileOutput.Close(); + chip::Tracing::Unregister(gPerfettoBackend); + chip::Tracing::Unregister(gJsonBackend); + }); } From 0c1a1ea3baeda93c2d7b3b3b249d8ea72d150819 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 1 Aug 2023 10:58:35 -0400 Subject: [PATCH 2/6] Fix typo and restyle --- src/controller/python/BUILD.gn | 5 +++-- .../chip/native/ChipMainLoopWork_StackLock.cpp | 9 +++++---- .../chip/native/ChipMainLoopWork_WorkSchedule.cpp | 13 +++++++------ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index edac2d776358d1..289009cca0aef0 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -33,7 +33,8 @@ config("controller_wno_deprecate") { declare_args() { chip_python_version = "0.0" chip_python_package_prefix = "chip" - chip_python_supports_stack_locking = (current_os != "mac") || (current_os != "ios") + chip_python_supports_stack_locking = + current_os != "mac" && current_os != "ios" } shared_library("ChipDeviceCtrl") { @@ -78,8 +79,8 @@ shared_library("ChipDeviceCtrl") { "chip/internal/ChipThreadWork.h", "chip/internal/CommissionerImpl.cpp", "chip/logging/LoggingRedirect.cpp", - "chip/native/PyChipError.cpp", "chip/native/ChipMainLoopWork.h", + "chip/native/PyChipError.cpp", "chip/tracing/TracingSetup.cpp", "chip/utils/DeviceProxyUtils.cpp", ] diff --git a/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp b/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp index 843f3e7a555a6c..c13580a3e0ac58 100644 --- a/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp +++ b/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp @@ -17,7 +17,7 @@ */ #include "ChipMainLoopWork.h" -#include +#include namespace chip { namespace MainLoopWork { @@ -27,14 +27,15 @@ using chip::DeviceLayer::PlatformMgr; class ScopedStackLock { - public: +public: ScopedStackLock() { PlatformMgr().LockChipStack(); } ~ScopedStackLock() { PlatformMgr().UnlockChipStack(); } }; -} // namespace +} // namespace -void ExecuteInMainLoop(std::function f) { +void ExecuteInMainLoop(std::function f) +{ ScopedStackLock lock; f(); } diff --git a/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp index 61f3b94b75b98a..a42c9fde3233bd 100644 --- a/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp +++ b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp @@ -43,26 +43,27 @@ void PerformWork(intptr_t arg) work->Post(); } +} // namespace -} // namespace - -void ExecuteInMainLoop(std::function f) { +void ExecuteInMainLoop(std::function f) +{ #if CHIP_STACK_LOCK_TRACKING_ENABLED - if (chip::DeviceLayer::PlatformMgr().IsChipStackLockedByCurrentThread()) { + if (chip::DeviceLayer::PlatformMgr().IsChipStackLockedByCurrentThread()) + { f(); return; } #endif #if defined(__APPLE__) - if (chip::DeviceLayer::PlatformManagerImpl()::IsWorkQueueCurrentQueue()) { + if (chip::DeviceLayer::PlatformManagerImpl()::IsWorkQueueCurrentQueue()) + { f(); return; } #endif - // NOTE: the code below assumes that chip main loop is running. // if it does not, this will deadlock. // From 1ae4348979ffab7a5aff1373af1cdebe44ae3bb1 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 1 Aug 2023 13:37:47 -0400 Subject: [PATCH 3/6] Fix typo --- .../python/chip/native/ChipMainLoopWork_WorkSchedule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp index a42c9fde3233bd..f74fa994e9f9d7 100644 --- a/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp +++ b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp @@ -57,7 +57,7 @@ void ExecuteInMainLoop(std::function f) #endif #if defined(__APPLE__) - if (chip::DeviceLayer::PlatformManagerImpl()::IsWorkQueueCurrentQueue()) + if (chip::DeviceLayer::PlatformManagerImpl().IsWorkQueueCurrentQueue()) { f(); return; From 1cffc7edd88a298350753e9f69a1edd4c6cd4ccb Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 2 Aug 2023 14:09:01 -0400 Subject: [PATCH 4/6] Code review updates --- src/controller/python/BUILD.gn | 4 +-- .../python/chip/native/ChipMainLoopWork.h | 13 +++++----- .../native/ChipMainLoopWork_StackLock.cpp | 26 +++++++++---------- .../native/ChipMainLoopWork_WorkSchedule.cpp | 25 ++++++------------ 4 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index 289009cca0aef0..56ea3de2977863 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -20,6 +20,7 @@ import("$dir_pw_build/python.gni") import("${chip_root}/build/chip/tools.gni") import("${chip_root}/src/platform/python.gni") +import("${chip_root}/src/system/system.gni") import("${dir_pw_unit_test}/test.gni") if (current_os == "mac") { @@ -33,8 +34,7 @@ config("controller_wno_deprecate") { declare_args() { chip_python_version = "0.0" chip_python_package_prefix = "chip" - chip_python_supports_stack_locking = - current_os != "mac" && current_os != "ios" + chip_python_supports_stack_locking = (chip_system_config_locking != "none") } shared_library("ChipDeviceCtrl") { diff --git a/src/controller/python/chip/native/ChipMainLoopWork.h b/src/controller/python/chip/native/ChipMainLoopWork.h index d0b562e0464ece..2005bc93503951 100644 --- a/src/controller/python/chip/native/ChipMainLoopWork.h +++ b/src/controller/python/chip/native/ChipMainLoopWork.h @@ -25,13 +25,14 @@ namespace MainLoopWork { /** * Executes the given function in the CHIP main loop if one exists. * - * If chip stack locking is available, this will lock the chip stack - * and execute `f`. + * Several implementations exist, however generally: * - * If chip stack locking is not available: - * - if already in the chip main loop, this will execute `f` right away - * - if main loop running, this will schedule and WAIT for `f` to execute - * - if main loop is stopped, this will execute `f` right away + * - if already in the chip main loop, `f` gets executed right away + * - otherwise: + * - if chip stack locking is available, `f` is executed within the lock + * - if chip stack locking not available: + * - if main loop running, this will schedule and WAIT for `f` to execute + * - if main loop is stopped, this will execute `f` right away */ void ExecuteInMainLoop(std::function f); diff --git a/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp b/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp index c13580a3e0ac58..f848a3bc2c32dc 100644 --- a/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp +++ b/src/controller/python/chip/native/ChipMainLoopWork_StackLock.cpp @@ -21,22 +21,22 @@ namespace chip { namespace MainLoopWork { -namespace { - -using chip::DeviceLayer::PlatformMgr; - -class ScopedStackLock -{ -public: - ScopedStackLock() { PlatformMgr().LockChipStack(); } - ~ScopedStackLock() { PlatformMgr().UnlockChipStack(); } -}; - -} // namespace void ExecuteInMainLoop(std::function f) { - ScopedStackLock lock; + // NOTE: requires CHIP_STACK_LOCK_TRACKING_ENABLED to be available (which python builds + // generally have) to ensure chip stack locks are not deadlocking, since these + // functions do not know the actual state of the chip main loop. + // + // TODO: it may be a good assumption that python code asking for this will NOT run in + // chip main loop, however we try to be generic + if (chip::DeviceLayer::PlatformMgr().IsChipStackLockedByCurrentThread()) + { + f(); + return; + } + + chip::DeviceLayer::StackLock lock; f(); } diff --git a/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp index f74fa994e9f9d7..fec65a150c9396 100644 --- a/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp +++ b/src/controller/python/chip/native/ChipMainLoopWork_WorkSchedule.cpp @@ -48,32 +48,23 @@ void PerformWork(intptr_t arg) void ExecuteInMainLoop(std::function f) { -#if CHIP_STACK_LOCK_TRACKING_ENABLED + // NOTE: requires CHIP_STACK_LOCK_TRACKING_ENABLED to be available (which python builds + // generally have) to ensure chip stack locks are not deadlocking, since these + // functions do not know the actual state of the chip main loop. + // + // TODO: it may be a good assumption that python code asking for this will NOT run in + // chip main loop, however we try to be generic if (chip::DeviceLayer::PlatformMgr().IsChipStackLockedByCurrentThread()) { f(); return; } -#endif - -#if defined(__APPLE__) - if (chip::DeviceLayer::PlatformManagerImpl().IsWorkQueueCurrentQueue()) - { - f(); - return; - } -#endif // NOTE: the code below assumes that chip main loop is running. // if it does not, this will deadlock. // - // When CHIP_STACK_LOCK_TRACKING_ENABLED, stack locking will detect - // main event loop not running, so this will not run when chip event - // loop is stopped - // - // The cases when this will deadlock is: - // - chip stack lock tracking is disabled - // - main chip loop is not started (or stopped already) + // IsChipStackLockedByCurrentThread is expected to be aware of main loop + // not running. WorkData workdata; workdata.callback = f; chip::DeviceLayer::PlatformMgr().ScheduleWork(PerformWork, reinterpret_cast(&workdata)); From 9586e50c436e1cef731944d8d985475316ceae07 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 2 Aug 2023 14:11:05 -0400 Subject: [PATCH 5/6] Comment update --- src/controller/python/chip/native/ChipMainLoopWork.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controller/python/chip/native/ChipMainLoopWork.h b/src/controller/python/chip/native/ChipMainLoopWork.h index 2005bc93503951..831badefd8855b 100644 --- a/src/controller/python/chip/native/ChipMainLoopWork.h +++ b/src/controller/python/chip/native/ChipMainLoopWork.h @@ -27,12 +27,12 @@ namespace MainLoopWork { * * Several implementations exist, however generally: * - * - if already in the chip main loop, `f` gets executed right away + * - if already in the chip main loop (or main loop is not running), + * `f` gets executed right away * - otherwise: * - if chip stack locking is available, `f` is executed within the lock - * - if chip stack locking not available: - * - if main loop running, this will schedule and WAIT for `f` to execute - * - if main loop is stopped, this will execute `f` right away + * - if chip stack locking not available, this will schedule and WAIT + * for `f` to execute */ void ExecuteInMainLoop(std::function f); From 8ff398409f7ae4e4e81e1cd56fcb569ac8f7f772 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 2 Aug 2023 14:13:45 -0400 Subject: [PATCH 6/6] Restyle --- src/controller/python/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index 56ea3de2977863..4b84c63d5ff30d 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -34,7 +34,7 @@ config("controller_wno_deprecate") { declare_args() { chip_python_version = "0.0" chip_python_package_prefix = "chip" - chip_python_supports_stack_locking = (chip_system_config_locking != "none") + chip_python_supports_stack_locking = chip_system_config_locking != "none" } shared_library("ChipDeviceCtrl") {