From 2fe3f89f84823e66ac513438247c079118b1dcca Mon Sep 17 00:00:00 2001 From: Kevin Schoedel Date: Tue, 27 Jul 2021 11:31:09 -0400 Subject: [PATCH] WIP 202107291213 #### Problem XXX #### Change overview XXX socket events in #6561 Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. `System::Timer` remains as an optional `Object`-pool implementation tool for the XXX The intent is that the public `WatchableEventManager` interface will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will be its implementations. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not? --- .../esp32/main/DeviceCallbacks.cpp | 4 +- .../chip-tool/commands/common/Command.cpp | 12 +- .../chip-tool/commands/common/Commands.cpp | 2 +- examples/lighting-app/qpg/src/AppTask.cpp | 2 +- examples/lock-app/qpg/src/AppTask.cpp | 2 +- examples/minimal-mdns/client.cpp | 12 +- examples/shell/shell_common/cmd_ping.cpp | 2 +- .../operational-credentials-server.cpp | 2 +- src/app/reporting/Engine.cpp | 2 +- src/app/tests/integration/MockEvents.cpp | 6 +- .../tests/integration/chip_im_initiator.cpp | 14 +- src/app/util/af-event.cpp | 4 +- src/ble/BLEEndPoint.cpp | 11 +- src/ble/BleLayer.h | 5 - src/channel/ChannelContext.cpp | 2 +- src/controller/CHIPDeviceController.cpp | 2 +- .../ChipDeviceController-ScriptBinding.cpp | 2 +- .../python/chip/internal/ChipThreadWork.cpp | 2 +- .../Framework/CHIP.xcodeproj/project.pbxproj | 4 + src/include/platform/PlatformManager.h | 15 +- .../internal/GenericPlatformManagerImpl.cpp | 2 +- .../GenericPlatformManagerImpl_FreeRTOS.cpp | 2 +- .../GenericSoftwareUpdateManagerImpl.cpp | 6 +- src/inet/AsyncDNSResolverSockets.cpp | 2 +- src/inet/IPEndPointBasis.cpp | 2 +- src/inet/InetLayer.cpp | 6 +- src/inet/InetLayer.h | 2 +- src/inet/RawEndPoint.cpp | 2 +- src/inet/TCPEndPoint.cpp | 20 +- src/inet/UDPEndPoint.cpp | 2 +- src/inet/tests/TestInetCommonPosix.cpp | 4 +- src/inet/tests/TestInetEndPoint.cpp | 6 +- src/inet/tests/TestInetLayer.cpp | 4 +- src/inet/tests/TestInetLayerMulticast.cpp | 2 +- src/lib/shell/MainLoopDefault.cpp | 2 +- src/lib/shell/MainLoopESP32.cpp | 2 +- src/messaging/ExchangeContext.cpp | 2 +- src/messaging/ReliableMessageMgr.cpp | 2 +- src/messaging/tests/echo/echo_requester.cpp | 4 +- src/platform/BUILD.gn | 1 - src/platform/Darwin/PlatformManagerImpl.cpp | 2 +- src/platform/DeviceControlServer.cpp | 2 +- src/platform/EFR32/BLEManagerImpl.cpp | 14 +- .../EFR32/ConfigurationManagerImpl.cpp | 2 +- .../ESP32/ConfigurationManagerImpl.cpp | 2 +- .../ESP32/ConnectivityManagerImpl.cpp | 26 +- .../ESP32/bluedroid/BLEManagerImpl.cpp | 26 +- src/platform/ESP32/nimble/BLEManagerImpl.cpp | 22 +- src/platform/K32W/BLEManagerImpl.cpp | 12 +- .../K32W/ConfigurationManagerImpl.cpp | 2 +- src/platform/Linux/BLEManagerImpl.cpp | 12 +- .../Linux/ConfigurationManagerImpl.cpp | 2 +- .../Linux/ConnectivityManagerImpl.cpp | 10 +- src/platform/Linux/SystemPlatformConfig.h | 4 +- .../Linux/bluez/ChipDeviceScanner.cpp | 2 +- src/platform/SystemEventSupport.cpp | 15 +- src/platform/SystemTimerSupport.cpp | 45 -- src/platform/Zephyr/BLEManagerImpl.cpp | 20 +- .../Zephyr/ConfigurationManagerImpl.cpp | 2 +- .../cc13x2_26x2/ConfigurationManagerImpl.cpp | 2 +- src/platform/mbed/BLEManagerImpl.cpp | 20 +- .../mbed/ConfigurationManagerImpl.cpp | 2 +- src/platform/mbed/ConnectivityManagerImpl.cpp | 4 +- src/platform/qpg/BLEManagerImpl.cpp | 12 +- src/platform/qpg/ConfigurationManagerImpl.cpp | 2 +- src/platform/tests/TestPlatformMgr.cpp | 8 +- src/system/BUILD.gn | 16 +- src/system/SystemClock.cpp | 66 ++- src/system/SystemClock.h | 25 + src/system/SystemLayer.cpp | 472 +----------------- src/system/SystemLayer.h | 135 +---- src/system/SystemMutex.h | 20 +- src/system/SystemObject.cpp | 2 +- src/system/SystemTimer.cpp | 398 +++++---------- src/system/SystemTimer.h | 75 +-- src/system/WatchableEventManager.h | 97 +++- src/system/WatchableEventManagerLibevent.cpp | 95 +++- src/system/WatchableEventManagerLibevent.h | 20 + src/system/WatchableEventManagerLwIP.cpp | 341 +++++++++++++ src/system/WatchableEventManagerLwIP.h | 89 ++++ src/system/WatchableEventManagerSelect.cpp | 156 +++++- src/system/WatchableEventManagerSelect.h | 45 +- src/system/WatchableSocketSelect.cpp | 12 +- src/system/system.gni | 12 +- src/system/tests/TestSystemTimer.cpp | 10 +- src/transport/SecureSessionMgr.cpp | 2 +- 86 files changed, 1321 insertions(+), 1221 deletions(-) delete mode 100644 src/platform/SystemTimerSupport.cpp create mode 100644 src/system/WatchableEventManagerLwIP.cpp create mode 100644 src/system/WatchableEventManagerLwIP.h diff --git a/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp b/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp index 1f549bca131380..6984a6da9e27c0 100644 --- a/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp @@ -204,7 +204,7 @@ void IdentifyTimerHandler(Layer * systemLayer, void * appState, CHIP_ERROR error if (identifyTimerCount) { - SystemLayer.StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, appState); + SystemLayer.StartFunctTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, appState); // Decrement the timer count. identifyTimerCount--; } @@ -223,7 +223,7 @@ void DeviceCallbacks::OnIdentifyPostAttributeChangeCallback(EndpointId endpointI identifyTimerCount = (*value) * 4; SystemLayer.CancelTimer(IdentifyTimerHandler, this); - SystemLayer.StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, this); + SystemLayer.StartFunctTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, this); exit: return; diff --git a/examples/chip-tool/commands/common/Command.cpp b/examples/chip-tool/commands/common/Command.cpp index a0b3d5a6380a3a..bdc0bdc05848b9 100644 --- a/examples/chip-tool/commands/common/Command.cpp +++ b/examples/chip-tool/commands/common/Command.cpp @@ -422,16 +422,10 @@ static void OnResponseTimeout(chip::System::Layer *, void *, CHIP_ERROR) CHIP_ERROR Command::ScheduleWaitForResponse(uint16_t seconds) { - chip::System::Timer * timer = nullptr; - - CHIP_ERROR err = chip::DeviceLayer::SystemLayer.NewTimer(timer); - if (err == CHIP_NO_ERROR) - { - timer->Start(seconds * 1000, OnResponseTimeout, this); - } - else + CHIP_ERROR err = chip::DeviceLayer::SystemLayer.StartFunctTimer(seconds * 1000, OnResponseTimeout, this); + if (err != CHIP_NO_ERROR) { - ChipLogError(chipTool, "Failed to allocate timer"); + ChipLogError(chipTool, "Failed to allocate timer %" CHIP_ERROR_FORMAT, chip::ChipError::FormatError(err)); } return err; } diff --git a/examples/chip-tool/commands/common/Commands.cpp b/examples/chip-tool/commands/common/Commands.cpp index 8623587935c666..6b67cc3f3e27f4 100644 --- a/examples/chip-tool/commands/common/Commands.cpp +++ b/examples/chip-tool/commands/common/Commands.cpp @@ -202,7 +202,7 @@ CHIP_ERROR Commands::RunCommand(NodeId localId, NodeId remoteId, int argc, char // command->UpdateWaitForResponse(true); #if CONFIG_USE_SEPARATE_EVENTLOOP - chip::DeviceLayer::PlatformMgr().ScheduleWork(RunQueuedCommand, reinterpret_cast(command)); + chip::DeviceLayer::PlatformMgr().PlatformScheduleWork(RunQueuedCommand, reinterpret_cast(command)); command->WaitForResponse(command->GetWaitDurationInSeconds()); #else // CONFIG_USE_SEPARATE_EVENTLOOP err = command->Run(); diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 1386b172e5b357..c93451e5e08a1a 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -375,7 +375,7 @@ void AppTask::StartTimer(uint32_t aTimeoutInMs) CHIP_ERROR err; SystemLayer.CancelTimer(TimerEventHandler, this); - err = SystemLayer.StartTimer(aTimeoutInMs, TimerEventHandler, this); + err = SystemLayer.StartFunctTimer(aTimeoutInMs, TimerEventHandler, this); SuccessOrExit(err); mFunctionTimerActive = true; diff --git a/examples/lock-app/qpg/src/AppTask.cpp b/examples/lock-app/qpg/src/AppTask.cpp index 8676b9c89fd453..99000b16aea4f7 100644 --- a/examples/lock-app/qpg/src/AppTask.cpp +++ b/examples/lock-app/qpg/src/AppTask.cpp @@ -390,7 +390,7 @@ void AppTask::StartTimer(uint32_t aTimeoutInMs) CHIP_ERROR err; SystemLayer.CancelTimer(TimerEventHandler, this); - err = SystemLayer.StartTimer(aTimeoutInMs, TimerEventHandler, this); + err = SystemLayer.StartFunctTimer(aTimeoutInMs, TimerEventHandler, this); SuccessOrExit(err); mFunctionTimerActive = true; diff --git a/examples/minimal-mdns/client.cpp b/examples/minimal-mdns/client.cpp index b1ad74d45ed3bd..b54dd9cc8db4b2 100644 --- a/examples/minimal-mdns/client.cpp +++ b/examples/minimal-mdns/client.cpp @@ -327,22 +327,16 @@ int main(int argc, char ** args) BroadcastPacket(&mdnsServer); - System::Timer * timer = nullptr; - - if (DeviceLayer::SystemLayer.NewTimer(timer) == CHIP_NO_ERROR) - { - timer->Start( + CHIP_ERROR err = DeviceLayer::SystemLayer.StartFunctTimer( gOptions.runtimeMs, [](System::Layer *, void *, CHIP_ERROR err) { DeviceLayer::PlatformMgr().StopEventLoopTask(); DeviceLayer::PlatformMgr().Shutdown(); }, nullptr); - } - else + if (err != CHIP_NO_ERROR) { - - printf("Failed to create the shutdown timer. Kill with ^C.\n"); + printf("Failed to create the shutdown timer. Kill with ^C. %" CHIP_ERROR_FORMAT "\n", ChipError::FormatError(err)); } DeviceLayer::PlatformMgr().RunEventLoop(); diff --git a/examples/shell/shell_common/cmd_ping.cpp b/examples/shell/shell_common/cmd_ping.cpp index 8626fe338435c5..64a2acf9328b11 100644 --- a/examples/shell/shell_common/cmd_ping.cpp +++ b/examples/shell/shell_common/cmd_ping.cpp @@ -212,7 +212,7 @@ CHIP_ERROR SendEchoRequest(streamer_t * stream) } gPingArguments.SetLastEchoTime(System::Clock::GetMonotonicMilliseconds()); - SuccessOrExit(chip::DeviceLayer::SystemLayer.StartTimer(gPingArguments.GetEchoInterval(), EchoTimerHandler, NULL)); + SuccessOrExit(chip::DeviceLayer::SystemLayer.StartFunctTimer(gPingArguments.GetEchoInterval(), EchoTimerHandler, NULL)); streamer_printf(stream, "\nSend echo request message with payload size: %d bytes to Node: %" PRIu64 "\n", payloadSize, kTestDeviceNodeId); diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index 71bb97e599bf06..ee5fc75343d371 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -394,7 +394,7 @@ EmberAfNodeOperationalCertStatus ConvertToNOCResponseStatus(CHIP_ERROR err) bool emberAfOperationalCredentialsClusterRemoveAllFabricsCallback(chip::EndpointId endpoint, chip::app::CommandHandler * commandObj) { emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Remove all Fabrics"); - PlatformMgr().ScheduleWork(DoRemoveAllFabrics, 0); + PlatformMgr().PlatformScheduleWork(DoRemoveAllFabrics, 0); emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS); return true; } diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index e7a1a287f42b98..9de7e009ec313e 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -309,7 +309,7 @@ CHIP_ERROR Engine::ScheduleRun() { if (InteractionModelEngine::GetInstance()->GetExchangeManager() != nullptr) { - return InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionMgr()->SystemLayer()->ScheduleWork(Run, this); + return InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionMgr()->SystemLayer()->SystemScheduleWork(Run, this); } else { diff --git a/src/app/tests/integration/MockEvents.cpp b/src/app/tests/integration/MockEvents.cpp index 7b526d589263da..c00c640b1428e6 100644 --- a/src/app/tests/integration/MockEvents.cpp +++ b/src/app/tests/integration/MockEvents.cpp @@ -155,7 +155,7 @@ CHIP_ERROR MockEventGeneratorImpl::Init(chip::Messaging::ExchangeManager * apExc mEventsLeft = mpEventGenerator->GetNumStates(); if (mTimeBetweenEvents != 0) - mpExchangeMgr->GetSessionMgr()->SystemLayer()->StartTimer(mTimeBetweenEvents, HandleNextEvent, this); + mpExchangeMgr->GetSessionMgr()->SystemLayer()->StartFunctTimer(mTimeBetweenEvents, HandleNextEvent, this); return err; } @@ -174,7 +174,7 @@ void MockEventGeneratorImpl::HandleNextEvent(chip::System::Layer * apSystemLayer generator->mEventsLeft--; if ((generator->mEventWraparound) || (generator->mEventsLeft > 0)) { - apSystemLayer->StartTimer(generator->mTimeBetweenEvents, HandleNextEvent, generator); + apSystemLayer->StartFunctTimer(generator->mTimeBetweenEvents, HandleNextEvent, generator); } } } @@ -187,7 +187,7 @@ void MockEventGeneratorImpl::SetEventGeneratorStop() // This helps quit the standalone app in an orderly way without // spurious leaked timers. if (mTimeBetweenEvents != 0) - mpExchangeMgr->GetSessionMgr()->SystemLayer()->StartTimer(0, HandleNextEvent, this); + mpExchangeMgr->GetSessionMgr()->SystemLayer()->StartFunctTimer(0, HandleNextEvent, this); } bool MockEventGeneratorImpl::IsEventGeneratorStopped() diff --git a/src/app/tests/integration/chip_im_initiator.cpp b/src/app/tests/integration/chip_im_initiator.cpp index 9e3a8d544f5ea0..f226d828461af7 100644 --- a/src/app/tests/integration/chip_im_initiator.cpp +++ b/src/app/tests/integration/chip_im_initiator.cpp @@ -317,12 +317,12 @@ void CommandRequestTimerHandler(chip::System::Layer * systemLayer, void * appSta err = SendCommandRequest(commandSender); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send command request with error: %s\n", chip::ErrorStr(err))); - err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalSeconds * 1000, CommandRequestTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(gMessageIntervalSeconds * 1000, CommandRequestTimerHandler, NULL); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); } else { - err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalSeconds * 1000, BadCommandRequestTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(gMessageIntervalSeconds * 1000, BadCommandRequestTimerHandler, NULL); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); } @@ -343,7 +343,7 @@ void BadCommandRequestTimerHandler(chip::System::Layer * systemLayer, void * app err = SendBadCommandRequest(commandSender); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send bad command request with error: %s\n", chip::ErrorStr(err))); - err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalSeconds * 1000, ReadRequestTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(gMessageIntervalSeconds * 1000, ReadRequestTimerHandler, NULL); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); exit: @@ -370,12 +370,12 @@ void ReadRequestTimerHandler(chip::System::Layer * systemLayer, void * appState, err = SendReadRequest(); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send read request with error: %s\n", chip::ErrorStr(err))); - err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalSeconds * 1000, ReadRequestTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(gMessageIntervalSeconds * 1000, ReadRequestTimerHandler, NULL); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); } else { - err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalSeconds * 1000, WriteRequestTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(gMessageIntervalSeconds * 1000, WriteRequestTimerHandler, NULL); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); } @@ -407,7 +407,7 @@ void WriteRequestTimerHandler(chip::System::Layer * systemLayer, void * appState err = SendWriteRequest(writeClient); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send write request with error: %s\n", chip::ErrorStr(err))); - err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalSeconds * 1000, WriteRequestTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(gMessageIntervalSeconds * 1000, WriteRequestTimerHandler, NULL); VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); } else @@ -590,7 +590,7 @@ int main(int argc, char * argv[]) err = EstablishSecureSession(); SuccessOrExit(err); - err = chip::DeviceLayer::SystemLayer.StartTimer(0, CommandRequestTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(0, CommandRequestTimerHandler, NULL); SuccessOrExit(err); chip::DeviceLayer::PlatformMgr().RunEventLoop(); diff --git a/src/app/util/af-event.cpp b/src/app/util/af-event.cpp index 263a155a619025..98e25f36862faf 100644 --- a/src/app/util/af-event.cpp +++ b/src/app/util/af-event.cpp @@ -149,7 +149,7 @@ EmberStatus emberEventControlSetDelayMS(EmberEventControl * control, uint32_t de { control->status = EMBER_EVENT_MS_TIME; #if !CHIP_DEVICE_LAYER_NONE - chip::DeviceLayer::SystemLayer.StartTimer(delayMs, EventControlHandler, control); + chip::DeviceLayer::SystemLayer.StartFunctTimer(delayMs, EventControlHandler, control); #endif } else @@ -179,7 +179,7 @@ void emberEventControlSetActive(EmberEventControl * control) { control->status = EMBER_EVENT_ZERO_DELAY; #if !CHIP_DEVICE_LAYER_NONE - chip::DeviceLayer::SystemLayer.ScheduleWork(EventControlHandler, control); + chip::DeviceLayer::SystemLayer.SystemScheduleWork(EventControlHandler, control); #endif } diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp index 137c1ddf4e2ac1..4f2189fbe2c7f9 100644 --- a/src/ble/BLEEndPoint.cpp +++ b/src/ble/BLEEndPoint.cpp @@ -1427,7 +1427,7 @@ bool BLEEndPoint::SendIndication(PacketBufferHandle && buf) CHIP_ERROR BLEEndPoint::StartConnectTimer() { - const CHIP_ERROR timerErr = mBle->mSystemLayer->StartTimer(BLE_CONNECT_TIMEOUT_MS, HandleConnectTimeout, this); + const CHIP_ERROR timerErr = mBle->mSystemLayer->StartFunctTimer(BLE_CONNECT_TIMEOUT_MS, HandleConnectTimeout, this); ReturnErrorOnFailure(timerErr); mTimerStateFlags.Set(TimerStateFlag::kConnectTimerRunning); @@ -1436,7 +1436,7 @@ CHIP_ERROR BLEEndPoint::StartConnectTimer() CHIP_ERROR BLEEndPoint::StartReceiveConnectionTimer() { - const CHIP_ERROR timerErr = mBle->mSystemLayer->StartTimer(BLE_CONNECT_TIMEOUT_MS, HandleReceiveConnectionTimeout, this); + const CHIP_ERROR timerErr = mBle->mSystemLayer->StartFunctTimer(BLE_CONNECT_TIMEOUT_MS, HandleReceiveConnectionTimeout, this); ReturnErrorOnFailure(timerErr); mTimerStateFlags.Set(TimerStateFlag::kReceiveConnectionTimerRunning); @@ -1447,7 +1447,8 @@ CHIP_ERROR BLEEndPoint::StartAckReceivedTimer() { if (!mTimerStateFlags.Has(TimerStateFlag::kAckReceivedTimerRunning)) { - const CHIP_ERROR timerErr = mBle->mSystemLayer->StartTimer(BTP_ACK_RECEIVED_TIMEOUT_MS, HandleAckReceivedTimeout, this); + const CHIP_ERROR timerErr = + mBle->mSystemLayer->StartFunctTimer(BTP_ACK_RECEIVED_TIMEOUT_MS, HandleAckReceivedTimeout, this); ReturnErrorOnFailure(timerErr); mTimerStateFlags.Set(TimerStateFlag::kAckReceivedTimerRunning); @@ -1472,7 +1473,7 @@ CHIP_ERROR BLEEndPoint::StartSendAckTimer() if (!mTimerStateFlags.Has(TimerStateFlag::kSendAckTimerRunning)) { ChipLogDebugBleEndPoint(Ble, "starting new SendAckTimer"); - const CHIP_ERROR timerErr = mBle->mSystemLayer->StartTimer(BTP_ACK_SEND_TIMEOUT_MS, HandleSendAckTimeout, this); + const CHIP_ERROR timerErr = mBle->mSystemLayer->StartFunctTimer(BTP_ACK_SEND_TIMEOUT_MS, HandleSendAckTimeout, this); ReturnErrorOnFailure(timerErr); mTimerStateFlags.Set(TimerStateFlag::kSendAckTimerRunning); @@ -1483,7 +1484,7 @@ CHIP_ERROR BLEEndPoint::StartSendAckTimer() CHIP_ERROR BLEEndPoint::StartUnsubscribeTimer() { - const CHIP_ERROR timerErr = mBle->mSystemLayer->StartTimer(BLE_UNSUBSCRIBE_TIMEOUT_MS, HandleUnsubscribeTimeout, this); + const CHIP_ERROR timerErr = mBle->mSystemLayer->StartFunctTimer(BLE_UNSUBSCRIBE_TIMEOUT_MS, HandleUnsubscribeTimeout, this); ReturnErrorOnFailure(timerErr); mTimerStateFlags.Set(TimerStateFlag::kUnsubscribeTimerRunning); diff --git a/src/ble/BleLayer.h b/src/ble/BleLayer.h index e506ca04919691..12ef0445c3dce6 100644 --- a/src/ble/BleLayer.h +++ b/src/ble/BleLayer.h @@ -254,11 +254,6 @@ class DLL_EXPORT BleLayer CHIP_ERROR CloseAllBleConnections(); CHIP_ERROR CloseBleConnection(BLE_CONNECTION_OBJECT connObj); - CHIP_ERROR ScheduleWork(chip::System::Layer::TimerCompleteFunct aComplete, void * aAppState) - { - return mSystemLayer->ScheduleWork(aComplete, aAppState); - } - /**< Platform interface functions: * Calling conventions: diff --git a/src/channel/ChannelContext.cpp b/src/channel/ChannelContext.cpp index 17367f42e319c1..f7e8fd262c5c9d 100644 --- a/src/channel/ChannelContext.cpp +++ b/src/channel/ChannelContext.cpp @@ -182,7 +182,7 @@ void ChannelContext::EnterAddressResolve() if (mState == ChannelState::kPreparing && GetPrepareVars().mState == PrepareState::kAddressResolving) { System::Layer * layer = mExchangeManager->GetSessionMgr()->SystemLayer(); - layer->StartTimer(CHIP_CONFIG_NODE_ADDRESS_RESOLVE_TIMEOUT_MSECS, AddressResolveTimeout, this); + layer->StartFunctTimer(CHIP_CONFIG_NODE_ADDRESS_RESOLVE_TIMEOUT_MSECS, AddressResolveTimeout, this); Retain(); // Keep the pointer in the timer } } diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index b55a927cc025a1..e00b44b0141f23 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -946,7 +946,7 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam device->Init(GetControllerDeviceInitParams(), mListenPort, remoteDeviceId, peerAddress, fabric->GetFabricIndex()); - mSystemLayer->StartTimer(kSessionEstablishmentTimeout, OnSessionEstablishmentTimeoutCallback, this); + mSystemLayer->StartFunctTimer(kSessionEstablishmentTimeout, OnSessionEstablishmentTimeoutCallback, this); if (params.GetPeerAddress().GetTransportType() != Transport::Type::kBle) { device->SetAddress(params.GetPeerAddress().GetIPAddress()); diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index 114757e22de55f..0637b1c8794b66 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -521,6 +521,6 @@ ChipError::StorageType pychip_DeviceController_PostTaskOnChipThread(ChipThreadTa } // This function is not called and should not be called on CHIP thread, thus we need to acquire a lock for posting tasks. StackLock lock; - PlatformMgr().ScheduleWork(callback, reinterpret_cast(pythonContext)); + PlatformMgr().PlatformScheduleWork(callback, reinterpret_cast(pythonContext)); return ChipError::AsInteger(CHIP_NO_ERROR); } diff --git a/src/controller/python/chip/internal/ChipThreadWork.cpp b/src/controller/python/chip/internal/ChipThreadWork.cpp index 794bf8e72691dc..86faa94c030f14 100644 --- a/src/controller/python/chip/internal/ChipThreadWork.cpp +++ b/src/controller/python/chip/internal/ChipThreadWork.cpp @@ -64,7 +64,7 @@ void ChipMainThreadScheduleAndWait(WorkCallback callback) WorkData workdata; workdata.callback = callback; - chip::DeviceLayer::PlatformMgr().ScheduleWork(PerformWork, reinterpret_cast(&workdata)); + chip::DeviceLayer::PlatformMgr().PlatformScheduleWork(PerformWork, reinterpret_cast(&workdata)); workdata.Wait(); } diff --git a/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj b/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj index 4aa1e2121c19a3..386bc49ef02a6c 100644 --- a/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj @@ -598,6 +598,8 @@ "CHIP_DEVICE_LAYER_TARGET_NRF5=0", "CHIP_DEVICE_LAYER_TARGET_EFR32=0", "CHIP_SYSTEM_CONFIG_USE_SOCKETS=1", + "CHIP_SYSTEM_CONFIG_POSIX_LOCKING=0", + "CHIP_SYSTEM_CONFIG_NO_LOCKING=1", "$(inherited)", ); HEADER_SEARCH_PATHS = ( @@ -738,6 +740,8 @@ "CHIP_DEVICE_LAYER_TARGET_NRF5=0", "CHIP_DEVICE_LAYER_TARGET_EFR32=0", "CHIP_SYSTEM_CONFIG_USE_SOCKETS=1", + "CHIP_SYSTEM_CONFIG_POSIX_LOCKING=0", + "CHIP_SYSTEM_CONFIG_NO_LOCKING=1", "$(inherited)", ); HEADER_SEARCH_PATHS = ( diff --git a/src/include/platform/PlatformManager.h b/src/include/platform/PlatformManager.h index 0d9ce771cceef8..bad8a50970a672 100644 --- a/src/include/platform/PlatformManager.h +++ b/src/include/platform/PlatformManager.h @@ -28,6 +28,7 @@ #include namespace chip { + namespace DeviceLayer { class PlatformManagerImpl; @@ -36,6 +37,7 @@ class ConfigurationManagerImpl; class TraitManager; class ThreadStackManagerImpl; class TimeSyncManager; + namespace Internal { class DeviceControlServer; class FabricProvisioningServer; @@ -87,7 +89,7 @@ class PlatformManager * the work up but that work will NOT run until one of those functions is * called. */ - void ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg = 0); + void PlatformScheduleWork(AsyncWorkFunct workFunct, intptr_t arg = 0); /** * Process work items until StopEventLoopTask is called. RunEventLoop will * not return until work item processing is stopped. Once it returns it @@ -169,14 +171,7 @@ class PlatformManager friend class Internal::GenericThreadStackManagerImpl_OpenThread_LwIP; template friend class Internal::GenericConfigurationManagerImpl; - // Parentheses used to fix clang parsing issue with these declarations - friend ::CHIP_ERROR(::chip::System::Platform::Eventing::PostEvent)(::chip::System::Layer & aLayer, - ::chip::System::Object & aTarget, - ::chip::System::EventType aType, uintptr_t aArgument); - friend ::CHIP_ERROR(::chip::System::Platform::Eventing::DispatchEvents)(::chip::System::Layer & aLayer); - friend ::CHIP_ERROR(::chip::System::Platform::Eventing::DispatchEvent)(::chip::System::Layer & aLayer, - ::chip::System::Event aEvent); - friend ::CHIP_ERROR(::chip::System::Platform::Eventing::StartTimer)(::chip::System::Layer & aLayer, uint32_t aMilliseconds); + friend class System::PlatformEventing; void PostEvent(const ChipDeviceEvent * event); void DispatchEvent(const ChipDeviceEvent * event); @@ -274,7 +269,7 @@ inline void PlatformManager::RemoveEventHandler(EventHandlerFunct handler, intpt static_cast(this)->_RemoveEventHandler(handler, arg); } -inline void PlatformManager::ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg) +inline void PlatformManager::PlatformScheduleWork(AsyncWorkFunct workFunct, intptr_t arg) { static_cast(this)->_ScheduleWork(workFunct, arg); } diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp index 60f758bf6d3b5c..ff12daa328af14 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp @@ -254,7 +254,7 @@ void GenericPlatformManagerImpl::DispatchEventToSystemLayer(const Chi CHIP_ERROR err = CHIP_NO_ERROR; // Invoke the System Layer's event handler function. - err = SystemLayer.HandleEvent(*event->ChipSystemLayerEvent.Target, event->ChipSystemLayerEvent.Type, + err = SystemLayer.WatchableEvents().LayerLwIPHandleEvent(*event->ChipSystemLayerEvent.Target, event->ChipSystemLayerEvent.Type, event->ChipSystemLayerEvent.Argument); if (err != CHIP_NO_ERROR) { diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp index a83b6c34fef570..6fb36fe206e3c0 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp @@ -138,7 +138,7 @@ void GenericPlatformManagerImpl_FreeRTOS::_RunEventLoop(void) // Call into the system layer to dispatch the callback functions for all timers // that have expired. - err = SystemLayer.HandlePlatformTimer(); + err = SystemLayer.WatchableEvents().LayerLwIPHandlePlatformTimer(); if (err != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "Error handling CHIP timers: %s", ErrorStr(err)); diff --git a/src/include/platform/internal/GenericSoftwareUpdateManagerImpl.cpp b/src/include/platform/internal/GenericSoftwareUpdateManagerImpl.cpp index 91e3a93797263e..9b3476d93e705d 100644 --- a/src/include/platform/internal/GenericSoftwareUpdateManagerImpl.cpp +++ b/src/include/platform/internal/GenericSoftwareUpdateManagerImpl.cpp @@ -633,14 +633,14 @@ void GenericSoftwareUpdateManagerImpl::DriveState(SoftwareUpdateManag if (timeToNextQueryMS) { mState = SoftwareUpdateManager::kState_ScheduledHoldoff; - SystemLayer.StartTimer(timeToNextQueryMS, HandleHoldOffTimerExpired, NULL); + SystemLayer.StartFunctTimer(timeToNextQueryMS, HandleHoldOffTimerExpired, NULL); } } } break; case SoftwareUpdateManager::kState_PrepareQuery: { - PlatformMgr().ScheduleWork(PrepareBinding); + PlatformMgr().PlatformScheduleWork(PrepareBinding); } break; @@ -655,7 +655,7 @@ void GenericSoftwareUpdateManagerImpl::DriveState(SoftwareUpdateManag break; case SoftwareUpdateManager::kState_Download: { - PlatformMgr().ScheduleWork(StartDownload); + PlatformMgr().PlatformScheduleWork(StartDownload); } break; diff --git a/src/inet/AsyncDNSResolverSockets.cpp b/src/inet/AsyncDNSResolverSockets.cpp index 7a5f2574f8dc9b..1bf19cdda419b9 100644 --- a/src/inet/AsyncDNSResolverSockets.cpp +++ b/src/inet/AsyncDNSResolverSockets.cpp @@ -313,7 +313,7 @@ void AsyncDNSResolverSockets::NotifyChipThread(DNSResolver * resolver) chip::System::Layer & lSystemLayer = resolver->SystemLayer(); ChipLogDetail(Inet, "Posting DNS completion event to CHIP thread."); - lSystemLayer.ScheduleWork(AsyncDNSResolverSockets::DNSResultEventHandler, resolver); + lSystemLayer.SystemScheduleWork(AsyncDNSResolverSockets::DNSResultEventHandler, resolver); } void * AsyncDNSResolverSockets::AsyncDNSThreadRun(void * args) diff --git a/src/inet/IPEndPointBasis.cpp b/src/inet/IPEndPointBasis.cpp index 63c8c084560697..5c8aa9408e38d4 100644 --- a/src/inet/IPEndPointBasis.cpp +++ b/src/inet/IPEndPointBasis.cpp @@ -662,7 +662,7 @@ CHIP_ERROR IPEndPointBasis::PostPacketBufferEvent(chip::System::Layer & aLayer, System::EventType aEventType, System::PacketBufferHandle && aBuffer) { const CHIP_ERROR error = - aLayer.PostEvent(aTarget, aEventType, (uintptr_t) System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(aBuffer)); + aLayer.WatchableEvents().LayerLwIPPostEvent(aTarget, aEventType, (uintptr_t) System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(aBuffer)); if (error == CHIP_NO_ERROR) { // If PostEvent() succeeded, it has ownership of the buffer, so we need to release it (without freeing it). diff --git a/src/inet/InetLayer.cpp b/src/inet/InetLayer.cpp index 43854f5029e8e4..f7b4582e3c2ffa 100644 --- a/src/inet/InetLayer.cpp +++ b/src/inet/InetLayer.cpp @@ -120,7 +120,7 @@ InetLayer::InetLayer() } #if CHIP_SYSTEM_CONFIG_USE_LWIP -chip::System::LwIPEventHandlerDelegate InetLayer::sInetEventHandlerDelegate; +chip::System::LayerLwIPEventHandlerDelegate InetLayer::sInetEventHandlerDelegate; #endif // CHIP_SYSTEM_CONFIG_USE_LWIP #if INET_CONFIG_MAX_DROPPABLE_EVENTS && CHIP_SYSTEM_CONFIG_USE_LWIP @@ -276,7 +276,7 @@ CHIP_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext) err = InitQueueLimiter(); SuccessOrExit(err); - mSystemLayer->AddEventHandlerDelegate(sInetEventHandlerDelegate); + mSystemLayer->WatchableEvents().AddEventHandlerDelegate(sInetEventHandlerDelegate); #endif // CHIP_SYSTEM_CONFIG_USE_LWIP State = kState_Initialized; @@ -1016,7 +1016,7 @@ void InetLayer::HandleTCPInactivityTimer(chip::System::Layer * aSystemLayer, voi if (lTimerRequired) { - aSystemLayer->StartTimer(INET_TCP_IDLE_CHECK_INTERVAL, HandleTCPInactivityTimer, &lInetLayer); + aSystemLayer->StartFunctTimer(INET_TCP_IDLE_CHECK_INTERVAL, HandleTCPInactivityTimer, &lInetLayer); } } #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0 diff --git a/src/inet/InetLayer.h b/src/inet/InetLayer.h index 18f61efad10bf2..a7b39cffd98ed6 100644 --- a/src/inet/InetLayer.h +++ b/src/inet/InetLayer.h @@ -230,7 +230,7 @@ class DLL_EXPORT InetLayer #if CHIP_SYSTEM_CONFIG_USE_LWIP static CHIP_ERROR HandleInetLayerEvent(chip::System::Object & aTarget, chip::System::EventType aEventType, uintptr_t aArgument); - static chip::System::LwIPEventHandlerDelegate sInetEventHandlerDelegate; + static chip::System::LayerLwIPEventHandlerDelegate sInetEventHandlerDelegate; // In some implementations, there may be a shared event / message // queue for the InetLayer used by other system events / messages. diff --git a/src/inet/RawEndPoint.cpp b/src/inet/RawEndPoint.cpp index c5580ee86e4be6..a311a10c9e8eca 100644 --- a/src/inet/RawEndPoint.cpp +++ b/src/inet/RawEndPoint.cpp @@ -216,7 +216,7 @@ CHIP_ERROR RawEndPoint::Bind(IPAddressType addrType, const IPAddress & addr, Int ReturnErrorOnFailure(IPEndPointBasis::Bind(addrType, addr, 0, intfId)); #if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t dispatchQueue = SystemLayer().GetDispatchQueue(); + dispatch_queue_t dispatchQueue = SystemLayer().WatchableEvents().GetDispatchQueue(); if (dispatchQueue != nullptr) { unsigned long fd = static_cast(mSocket.GetFD()); diff --git a/src/inet/TCPEndPoint.cpp b/src/inet/TCPEndPoint.cpp index 661ab523dc474d..8e09c57b3fcefe 100644 --- a/src/inet/TCPEndPoint.cpp +++ b/src/inet/TCPEndPoint.cpp @@ -243,7 +243,7 @@ CHIP_ERROR TCPEndPoint::Bind(IPAddressType addrType, const IPAddress & addr, uin } #if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t dispatchQueue = SystemLayer().GetDispatchQueue(); + dispatch_queue_t dispatchQueue = SystemLayer().WatchableEvents().GetDispatchQueue(); if (dispatchQueue != nullptr) { unsigned long fd = static_cast(mSocket.GetFD()); @@ -566,7 +566,7 @@ void TCPEndPoint::StartConnectTimerIfSet() { chip::System::Layer & lSystemLayer = SystemLayer(); - lSystemLayer.StartTimer(mConnectTimeoutMsecs, TCPConnectTimeoutHandler, this); + lSystemLayer.StartFunctTimer(mConnectTimeoutMsecs, TCPConnectTimeoutHandler, this); } } @@ -1222,7 +1222,7 @@ void TCPEndPoint::SetIdleTimeout(uint32_t timeoutMS) if (!isIdleTimerRunning && mIdleTimeout) { - SystemLayer().StartTimer(INET_TCP_IDLE_CHECK_INTERVAL, InetLayer::HandleTCPInactivityTimer, &lInetLayer); + SystemLayer().StartFunctTimer(INET_TCP_IDLE_CHECK_INTERVAL, InetLayer::HandleTCPInactivityTimer, &lInetLayer); } } #endif // INET_TCP_IDLE_CHECK_INTERVAL > 0 @@ -1825,7 +1825,7 @@ void TCPEndPoint::ScheduleNextTCPUserTimeoutPoll(uint32_t aTimeOut) { chip::System::Layer & lSystemLayer = SystemLayer(); - lSystemLayer.StartTimer(aTimeOut, TCPUserTimeoutHandler, this); + lSystemLayer.StartFunctTimer(aTimeOut, TCPUserTimeoutHandler, this); } #if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS @@ -2204,7 +2204,7 @@ err_t TCPEndPoint::LwIPHandleConnectComplete(void * arg, struct tcp_pcb * tpcb, // Post callback to HandleConnectComplete. conErr = chip::System::MapErrorLwIP(lwipErr); - if (lSystemLayer.PostEvent(*ep, kInetEvent_TCPConnectComplete, static_cast(ChipError::AsInteger(conErr))) != + if (lSystemLayer.WatchableEvents().LayerLwIPPostEvent(*ep, kInetEvent_TCPConnectComplete, static_cast(ChipError::AsInteger(conErr))) != CHIP_NO_ERROR) res = ERR_ABRT; } @@ -2270,7 +2270,7 @@ err_t TCPEndPoint::LwIPHandleIncomingConnection(void * arg, struct tcp_pcb * tpc tcp_err(tpcb, LwIPHandleError); // Post a callback to the HandleConnectionReceived() function, passing it the new end point. - if (lSystemLayer.PostEvent(*listenEP, kInetEvent_TCPConnectionReceived, (uintptr_t) conEP) != CHIP_NO_ERROR) + if (lSystemLayer.WatchableEvents().LayerLwIPPostEvent(*listenEP, kInetEvent_TCPConnectionReceived, (uintptr_t) conEP) != CHIP_NO_ERROR) { err = CHIP_ERROR_CONNECTION_ABORTED; conEP->Release(); // for the Retain() above @@ -2280,7 +2280,7 @@ err_t TCPEndPoint::LwIPHandleIncomingConnection(void * arg, struct tcp_pcb * tpc // Otherwise, there was an error accepting the connection, so post a callback to the HandleError function. else - lSystemLayer.PostEvent(*listenEP, kInetEvent_TCPError, static_cast(ChipError::AsInteger(err))); + lSystemLayer.WatchableEvents().LayerLwIPPostEvent(*listenEP, kInetEvent_TCPError, static_cast(ChipError::AsInteger(err))); } else err = CHIP_ERROR_CONNECTION_ABORTED; @@ -2306,7 +2306,7 @@ err_t TCPEndPoint::LwIPHandleDataReceived(void * arg, struct tcp_pcb * tpcb, str chip::System::Layer & lSystemLayer = ep->SystemLayer(); // Post callback to HandleDataReceived. - if (lSystemLayer.PostEvent(*ep, kInetEvent_TCPDataReceived, (uintptr_t) p) != CHIP_NO_ERROR) + if (lSystemLayer.WatchableEvents().LayerLwIPPostEvent(*ep, kInetEvent_TCPDataReceived, (uintptr_t) p) != CHIP_NO_ERROR) res = ERR_ABRT; } else @@ -2328,7 +2328,7 @@ err_t TCPEndPoint::LwIPHandleDataSent(void * arg, struct tcp_pcb * tpcb, u16_t l chip::System::Layer & lSystemLayer = ep->SystemLayer(); // Post callback to HandleDataReceived. - if (lSystemLayer.PostEvent(*ep, kInetEvent_TCPDataSent, (uintptr_t) len) != CHIP_NO_ERROR) + if (lSystemLayer.WatchableEvents().LayerLwIPPostEvent(*ep, kInetEvent_TCPDataSent, (uintptr_t) len) != CHIP_NO_ERROR) res = ERR_ABRT; } else @@ -2357,7 +2357,7 @@ void TCPEndPoint::LwIPHandleError(void * arg, err_t lwipErr) // Post callback to HandleError. CHIP_ERROR err = chip::System::MapErrorLwIP(lwipErr); - lSystemLayer.PostEvent(*ep, kInetEvent_TCPError, static_cast(ChipError::AsInteger(err))); + lSystemLayer.WatchableEvents().LayerLwIPPostEvent(*ep, kInetEvent_TCPError, static_cast(ChipError::AsInteger(err))); } } diff --git a/src/inet/UDPEndPoint.cpp b/src/inet/UDPEndPoint.cpp index aebc4281c68657..00f9842f43b4ff 100644 --- a/src/inet/UDPEndPoint.cpp +++ b/src/inet/UDPEndPoint.cpp @@ -246,7 +246,7 @@ CHIP_ERROR UDPEndPoint::Bind(IPAddressType addrType, const IPAddress & addr, uin } #if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t dispatchQueue = SystemLayer().GetDispatchQueue(); + dispatch_queue_t dispatchQueue = SystemLayer().WatchableEvents().GetDispatchQueue(); if (dispatchQueue != nullptr) { unsigned long fd = static_cast(mSocket.GetFD()); diff --git a/src/inet/tests/TestInetCommonPosix.cpp b/src/inet/tests/TestInetCommonPosix.cpp index 3a09d6c5341bf9..8f43f13f5b6c49 100644 --- a/src/inet/tests/TestInetCommonPosix.cpp +++ b/src/inet/tests/TestInetCommonPosix.cpp @@ -469,7 +469,7 @@ void ServiceEvents(struct ::timeval & aSleepTime) { if (sRemainingSystemLayerEventDelay == 0) { - gSystemLayer.DispatchEvents(); + gSystemLayer.WatchableEvents().LayerLwIPDispatchEvents(); sRemainingSystemLayerEventDelay = gNetworkOptions.EventDelay; } else @@ -478,7 +478,7 @@ void ServiceEvents(struct ::timeval & aSleepTime) // TODO: Currently timers are delayed by aSleepTime above. A improved solution would have a mechanism to reduce // aSleepTime according to the next timer. - gSystemLayer.HandlePlatformTimer(); + gSystemLayer.WatchableEvents().LayerLwIPHandlePlatformTimer(); } } #if CHIP_TARGET_STYLE_UNIX diff --git a/src/inet/tests/TestInetEndPoint.cpp b/src/inet/tests/TestInetEndPoint.cpp index 820bdfdd504cea..20b7d0f4adeafd 100644 --- a/src/inet/tests/TestInetEndPoint.cpp +++ b/src/inet/tests/TestInetEndPoint.cpp @@ -111,7 +111,7 @@ static void TestInetPre(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE); #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT - err = gSystemLayer.StartTimer(10, HandleTimer, nullptr); + err = gSystemLayer.StartFunctTimer(10, HandleTimer, nullptr); NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE); #if INET_CONFIG_ENABLE_DNS_RESOLVER @@ -519,12 +519,12 @@ static void TestInetEndPointLimit(nlTestSuite * inSuite, void * inContext) // Verify same aComplete and aAppState args do not exhaust timer pool for (int i = 0; i < CHIP_SYSTEM_CONFIG_NUM_TIMERS + 1; i++) { - err = gSystemLayer.StartTimer(10, HandleTimer, nullptr); + err = gSystemLayer.StartFunctTimer(10, HandleTimer, nullptr); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); } for (int i = 0; i < CHIP_SYSTEM_CONFIG_NUM_TIMERS + 1; i++) - err = gSystemLayer.StartTimer(10, HandleTimer, &numTimersTest[i]); + err = gSystemLayer.StartFunctTimer(10, HandleTimer, &numTimersTest[i]); NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_NO_MEMORY); ShutdownNetwork(); diff --git a/src/inet/tests/TestInetLayer.cpp b/src/inet/tests/TestInetLayer.cpp index 42b68ba2b9a766..2090241f8da6cf 100644 --- a/src/inet/tests/TestInetLayer.cpp +++ b/src/inet/tests/TestInetLayer.cpp @@ -558,7 +558,7 @@ void HandleTCPConnectionComplete(TCPEndPoint * aEndPoint, CHIP_ERROR aError) gSendIntervalExpired = false; gSystemLayer.CancelTimer(Common::HandleSendTimerComplete, nullptr); - gSystemLayer.StartTimer(gSendIntervalMs, Common::HandleSendTimerComplete, nullptr); + gSystemLayer.StartFunctTimer(gSendIntervalMs, Common::HandleSendTimerComplete, nullptr); SetStatusFailed(sTestState.mStatus); } @@ -876,7 +876,7 @@ void DriveSend() else { gSendIntervalExpired = false; - gSystemLayer.StartTimer(gSendIntervalMs, Common::HandleSendTimerComplete, nullptr); + gSystemLayer.StartFunctTimer(gSendIntervalMs, Common::HandleSendTimerComplete, nullptr); if (sTestState.mStats.mTransmit.mActual < sTestState.mStats.mTransmit.mExpected) { diff --git a/src/inet/tests/TestInetLayerMulticast.cpp b/src/inet/tests/TestInetLayerMulticast.cpp index ef458af4b42879..398d8547cf57c2 100644 --- a/src/inet/tests/TestInetLayerMulticast.cpp +++ b/src/inet/tests/TestInetLayerMulticast.cpp @@ -813,7 +813,7 @@ void DriveSend() else { gSendIntervalExpired = false; - gSystemLayer.StartTimer(gSendIntervalMs, Common::HandleSendTimerComplete, nullptr); + gSystemLayer.StartFunctTimer(gSendIntervalMs, Common::HandleSendTimerComplete, nullptr); lStatus = DriveSendForGroups(sGroupAddresses); SuccessOrExit(lStatus); diff --git a/src/lib/shell/MainLoopDefault.cpp b/src/lib/shell/MainLoopDefault.cpp index 34e393c1c741f0..e39ef731a20bec 100644 --- a/src/lib/shell/MainLoopDefault.cpp +++ b/src/lib/shell/MainLoopDefault.cpp @@ -189,7 +189,7 @@ void Engine::RunMainLoop() char * line = static_cast(Platform::MemoryAlloc(CHIP_SHELL_MAX_LINE_SIZE)); ReadLine(line, CHIP_SHELL_MAX_LINE_SIZE); #if CONFIG_DEVICE_LAYER - DeviceLayer::PlatformMgr().ScheduleWork(ProcessShellLine, reinterpret_cast(line)); + DeviceLayer::PlatformMgr().PlatformScheduleWork(ProcessShellLine, reinterpret_cast(line)); #else ProcessShellLine(reinterpret_cast(line)); #endif diff --git a/src/lib/shell/MainLoopESP32.cpp b/src/lib/shell/MainLoopESP32.cpp index 8351c62721bc16..90b70d737adc3d 100644 --- a/src/lib/shell/MainLoopESP32.cpp +++ b/src/lib/shell/MainLoopESP32.cpp @@ -89,7 +89,7 @@ void Engine::RunMainLoop() } ShellLineArgs shellArgs(line, xTaskGetCurrentTaskHandle()); linenoiseHistoryAdd(line); - PlatformMgr().ScheduleWork(ProcessShellLine, reinterpret_cast(&shellArgs)); + PlatformMgr().PlatformScheduleWork(ProcessShellLine, reinterpret_cast(&shellArgs)); shellArgs.WaitShellProcessDone(); linenoiseFree(line); } diff --git a/src/messaging/ExchangeContext.cpp b/src/messaging/ExchangeContext.cpp index 2c1dcc3c5c223c..d509bce4c988d3 100644 --- a/src/messaging/ExchangeContext.cpp +++ b/src/messaging/ExchangeContext.cpp @@ -351,7 +351,7 @@ CHIP_ERROR ExchangeContext::StartResponseTimer() return CHIP_ERROR_INTERNAL; } - return lSystemLayer->StartTimer(mResponseTimeout, HandleResponseTimeout, this); + return lSystemLayer->StartFunctTimer(mResponseTimeout, HandleResponseTimeout, this); } void ExchangeContext::CancelResponseTimer() diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index d776dae3d46129..df5a4cbf1165f4 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -487,7 +487,7 @@ void ReliableMessageMgr::StartTimer() ChipLogDetail(ExchangeManager, "ReliableMessageMgr::StartTimer set timer for %" PRIu64, timerArmValue); #endif StopTimer(); - res = mSystemLayer->StartTimer((uint32_t) timerArmValue, Timeout, this); + res = mSystemLayer->StartFunctTimer((uint32_t) timerArmValue, Timeout, this); VerifyOrDieWithMsg(res == CHIP_NO_ERROR, ExchangeManager, "Cannot start ReliableMessageMgr::Timeout\n"); mCurrentTimerExpiry = timerExpiry; diff --git a/src/messaging/tests/echo/echo_requester.cpp b/src/messaging/tests/echo/echo_requester.cpp index 38ffe990d99591..f979603691e0e2 100644 --- a/src/messaging/tests/echo/echo_requester.cpp +++ b/src/messaging/tests/echo/echo_requester.cpp @@ -123,7 +123,7 @@ CHIP_ERROR SendEchoRequest() gLastEchoTime = chip::System::Clock::GetMonotonicMilliseconds(); - err = chip::DeviceLayer::SystemLayer.StartTimer(gEchoInterval, EchoTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(gEchoInterval, EchoTimerHandler, NULL); if (err != CHIP_NO_ERROR) { printf("Unable to schedule timer\n"); @@ -269,7 +269,7 @@ int main(int argc, char * argv[]) // Arrange to get a callback whenever an Echo Response is received. gEchoClient.SetEchoResponseReceived(HandleEchoResponseReceived); - err = chip::DeviceLayer::SystemLayer.StartTimer(0, EchoTimerHandler, NULL); + err = chip::DeviceLayer::SystemLayer.StartFunctTimer(0, EchoTimerHandler, NULL); SuccessOrExit(err); chip::DeviceLayer::PlatformMgr().RunEventLoop(); diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 4ca7023edaf40c..dbed52c95f0527 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -254,7 +254,6 @@ if (chip_device_platform != "none") { "LockTracker.cpp", "PersistedStorage.cpp", "SystemEventSupport.cpp", - "SystemTimerSupport.cpp", "TestIdentity.cpp", ] diff --git a/src/platform/Darwin/PlatformManagerImpl.cpp b/src/platform/Darwin/PlatformManagerImpl.cpp index cce976da2e8211..75b0bb9006ed5a 100644 --- a/src/platform/Darwin/PlatformManagerImpl.cpp +++ b/src/platform/Darwin/PlatformManagerImpl.cpp @@ -51,7 +51,7 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack() err = Internal::GenericPlatformManagerImpl::_InitChipStack(); SuccessOrExit(err); - SystemLayer.SetDispatchQueue(GetWorkQueue()); + SystemLayer.WatchableEvents().SetDispatchQueue(GetWorkQueue()); exit: return err; diff --git a/src/platform/DeviceControlServer.cpp b/src/platform/DeviceControlServer.cpp index 41b4df2738dc0a..5b14e052f2d7d8 100644 --- a/src/platform/DeviceControlServer.cpp +++ b/src/platform/DeviceControlServer.cpp @@ -52,7 +52,7 @@ void DeviceControlServer::CommissioningFailedTimerComplete(CHIP_ERROR aError) CHIP_ERROR DeviceControlServer::ArmFailSafe(uint16_t expiryLengthSeconds) { uint32_t timerMs = expiryLengthSeconds * 1000; - SystemLayer.StartTimer(timerMs, CommissioningTimerFunction, this); + SystemLayer.StartFunctTimer(timerMs, CommissioningTimerFunction, this); return CHIP_NO_ERROR; } diff --git a/src/platform/EFR32/BLEManagerImpl.cpp b/src/platform/EFR32/BLEManagerImpl.cpp index 59deff77e5d2f5..552e3106df04e6 100644 --- a/src/platform/EFR32/BLEManagerImpl.cpp +++ b/src/platform/EFR32/BLEManagerImpl.cpp @@ -194,7 +194,7 @@ CHIP_ERROR BLEManagerImpl::_Init() mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); mFlags.Set(Flags::kFastAdvertisingEnabled, true); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); exit: return err; @@ -329,7 +329,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -345,7 +345,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) if (mFlags.Has(Flags::kAdvertisingEnabled) != val) { mFlags.Set(Flags::kAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -366,7 +366,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kRestartAdvertising); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -829,7 +829,7 @@ void BLEManagerImpl::UpdateMtu(volatile sl_bt_msg_t * evt) void BLEManagerImpl::HandleBootEvent(void) { mFlags.Set(Flags::kEFRBLEStackInitialized); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } void BLEManagerImpl::HandleConnectEvent(volatile sl_bt_msg_t * evt) @@ -842,7 +842,7 @@ void BLEManagerImpl::HandleConnectEvent(volatile sl_bt_msg_t * evt) AddConnection(connHandle, bondingHandle); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } void BLEManagerImpl::HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt) @@ -883,7 +883,7 @@ void BLEManagerImpl::HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt) // maximum connection limit being reached. mFlags.Set(Flags::kRestartAdvertising); mFlags.Set(Flags::kFastAdvertisingEnabled); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } diff --git a/src/platform/EFR32/ConfigurationManagerImpl.cpp b/src/platform/EFR32/ConfigurationManagerImpl.cpp index 8b26e715877273..46983e8c9ffa45 100644 --- a/src/platform/EFR32/ConfigurationManagerImpl.cpp +++ b/src/platform/EFR32/ConfigurationManagerImpl.cpp @@ -69,7 +69,7 @@ bool ConfigurationManagerImpl::_CanFactoryReset() void ConfigurationManagerImpl::_InitiateFactoryReset() { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key persistedStorageKey, diff --git a/src/platform/ESP32/ConfigurationManagerImpl.cpp b/src/platform/ESP32/ConfigurationManagerImpl.cpp index 9b6b1462f66b05..f4970a83e70284 100644 --- a/src/platform/ESP32/ConfigurationManagerImpl.cpp +++ b/src/platform/ESP32/ConfigurationManagerImpl.cpp @@ -134,7 +134,7 @@ bool ConfigurationManagerImpl::_CanFactoryReset() void ConfigurationManagerImpl::_InitiateFactoryReset() { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) diff --git a/src/platform/ESP32/ConnectivityManagerImpl.cpp b/src/platform/ESP32/ConnectivityManagerImpl.cpp index 32ebf9a9862362..c28907ddfaef9a 100644 --- a/src/platform/ESP32/ConnectivityManagerImpl.cpp +++ b/src/platform/ESP32/ConnectivityManagerImpl.cpp @@ -90,7 +90,7 @@ CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(WiFiStationMode val) err = Internal::ESP32Utils::SetAPMode(autoConnect); SuccessOrExit(err); - SystemLayer.ScheduleWork(DriveStationState, NULL); + SystemLayer.SystemScheduleWork(DriveStationState, NULL); } if (mWiFiStationMode != val) @@ -119,8 +119,8 @@ void ConnectivityManagerImpl::_ClearWiFiStationProvision(void) memset(&stationConfig, 0, sizeof(stationConfig)); esp_wifi_set_config(WIFI_IF_STA, &stationConfig); - SystemLayer.ScheduleWork(DriveStationState, NULL); - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveStationState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } } @@ -137,7 +137,7 @@ CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val) mWiFiAPMode = val; - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); exit: return err; @@ -148,7 +148,7 @@ void ConnectivityManagerImpl::_DemandStartWiFiAP(void) if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) { mLastAPDemandTime = System::Clock::GetMonotonicMilliseconds(); - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } } @@ -157,7 +157,7 @@ void ConnectivityManagerImpl::_StopOnDemandWiFiAP(void) if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) { mLastAPDemandTime = 0; - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } } @@ -175,7 +175,7 @@ void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP(void) void ConnectivityManagerImpl::_SetWiFiAPIdleTimeoutMS(uint32_t val) { mWiFiAPIdleTimeoutMS = val; - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } #define WIFI_BAND_2_4GHZ 2400 @@ -442,8 +442,8 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() ReturnErrorOnFailure(Internal::ESP32Utils::SetAPMode(false)); // Queue work items to bootstrap the AP and station state machines once the Chip event loop is running. - ReturnErrorOnFailure(SystemLayer.ScheduleWork(DriveStationState, NULL)); - ReturnErrorOnFailure(SystemLayer.ScheduleWork(DriveAPState, NULL)); + ReturnErrorOnFailure(SystemLayer.SystemScheduleWork(DriveStationState, NULL)); + ReturnErrorOnFailure(SystemLayer.SystemScheduleWork(DriveAPState, NULL)); return CHIP_NO_ERROR; } @@ -527,13 +527,13 @@ void ConnectivityManagerImpl::_OnWiFiScanDone() { // Schedule a call to DriveStationState method in case a station connect attempt was // deferred because the scan was in progress. - SystemLayer.ScheduleWork(DriveStationState, NULL); + SystemLayer.SystemScheduleWork(DriveStationState, NULL); } void ConnectivityManagerImpl::_OnWiFiStationProvisionChange() { // Schedule a call to the DriveStationState method to adjust the station state as needed. - SystemLayer.ScheduleWork(DriveStationState, NULL); + SystemLayer.SystemScheduleWork(DriveStationState, NULL); } // ==================== ConnectivityManager Private Methods ==================== @@ -642,7 +642,7 @@ void ConnectivityManagerImpl::DriveStationState() ChipLogProgress(DeviceLayer, "Next WiFi station reconnect in %" PRIu32 " ms", timeToNextConnect); - ReturnOnFailure(SystemLayer.StartTimer(timeToNextConnect, DriveStationState, NULL)); + ReturnOnFailure(SystemLayer.StartFunctTimer(timeToNextConnect, DriveStationState, NULL)); } } } @@ -765,7 +765,7 @@ void ConnectivityManagerImpl::DriveAPState() // Compute the amount of idle time before the AP should be deactivated and // arm a timer to fire at that time. apTimeout = (uint32_t)((mLastAPDemandTime + mWiFiAPIdleTimeoutMS) - now); - err = SystemLayer.StartTimer(apTimeout, DriveAPState, NULL); + err = SystemLayer.StartFunctTimer(apTimeout, DriveAPState, NULL); SuccessOrExit(err); ChipLogProgress(DeviceLayer, "Next WiFi AP timeout in %" PRIu32 " ms", apTimeout); } diff --git a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp index 47833499ecccd9..be9bf147a4163d 100644 --- a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp +++ b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp @@ -145,7 +145,7 @@ CHIP_ERROR BLEManagerImpl::_Init() mFlags.Set(Flags::kFastAdvertisingEnabled, true); memset(mDeviceName, 0, sizeof(mDeviceName)); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); exit: return err; @@ -161,7 +161,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -177,13 +177,13 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) if (val) { mAdvertiseStartTime = System::Clock::GetMonotonicMilliseconds(); - ReturnErrorOnFailure(SystemLayer.StartTimer(kAdvertiseTimeout, HandleAdvertisementTimer, this)); - ReturnErrorOnFailure(SystemLayer.StartTimer(kFastAdvertiseTimeout, HandleFastAdvertisementTimer, this)); + ReturnErrorOnFailure(SystemLayer.StartFunctTimer(kAdvertiseTimeout, HandleAdvertisementTimer, this)); + ReturnErrorOnFailure(SystemLayer.StartFunctTimer(kFastAdvertiseTimeout, HandleFastAdvertisementTimer, this)); } mFlags.Set(Flags::kFastAdvertisingEnabled, val); mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); mFlags.Set(Flags::kAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); exit: return err; } @@ -200,7 +200,7 @@ void BLEManagerImpl::HandleAdvertisementTimer() if (currentTimestamp - mAdvertiseStartTime >= kAdvertiseTimeout) { mFlags.Clear(Flags::kAdvertisingEnabled); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } @@ -217,7 +217,7 @@ void BLEManagerImpl::HandleFastAdvertisementTimer() { mFlags.Clear(Flags::kFastAdvertisingEnabled); mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } @@ -235,7 +235,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -360,7 +360,7 @@ bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) // Force a refresh of the advertising state. mFlags.Set(Flags::kAdvertisingRefreshNeeded); mFlags.Clear(Flags::kAdvertisingConfigured); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return (err == CHIP_NO_ERROR); } @@ -889,7 +889,7 @@ void BLEManagerImpl::HandleGATTControlEvent(esp_gatts_cb_event_t event, esp_gatt if (controlOpComplete) { mFlags.Clear(Flags::kControlOpInProgress); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } @@ -914,7 +914,7 @@ void BLEManagerImpl::HandleGATTCommEvent(esp_gatts_cb_event_t event, esp_gatt_if // state. mFlags.Set(Flags::kAdvertisingRefreshNeeded); mFlags.Clear(Flags::kAdvertisingConfigured); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); break; @@ -1174,7 +1174,7 @@ void BLEManagerImpl::HandleDisconnect(esp_ble_gatts_cb_param_t * param) // Force a refresh of the advertising state. mFlags.Set(Flags::kAdvertisingRefreshNeeded); mFlags.Clear(Flags::kAdvertisingConfigured); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } @@ -1353,7 +1353,7 @@ void BLEManagerImpl::HandleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); sInstance.mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; } - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); PlatformMgr().UnlockChipStack(); } diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index 87bf856a29e823..1a04ccc105476b 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -138,7 +138,7 @@ CHIP_ERROR BLEManagerImpl::_Init() mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; memset(mDeviceName, 0, sizeof(mDeviceName)); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); exit: return err; @@ -154,7 +154,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -170,14 +170,14 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) if (val) { mAdvertiseStartTime = System::Clock::GetMonotonicMilliseconds(); - ReturnErrorOnFailure(SystemLayer.StartTimer(kAdvertiseTimeout, HandleAdvertisementTimer, this)); - ReturnErrorOnFailure(SystemLayer.StartTimer(kFastAdvertiseTimeout, HandleFastAdvertisementTimer, this)); + ReturnErrorOnFailure(SystemLayer.StartFunctTimer(kAdvertiseTimeout, HandleAdvertisementTimer, this)); + ReturnErrorOnFailure(SystemLayer.StartFunctTimer(kFastAdvertiseTimeout, HandleFastAdvertisementTimer, this)); } mFlags.Set(Flags::kFastAdvertisingEnabled, val); mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); mFlags.Set(Flags::kAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); exit: return err; @@ -195,7 +195,7 @@ void BLEManagerImpl::HandleAdvertisementTimer() if (currentTimestamp - mAdvertiseStartTime >= kAdvertiseTimeout) { mFlags.Set(Flags::kAdvertisingEnabled, 0); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } @@ -212,7 +212,7 @@ void BLEManagerImpl::HandleFastAdvertisementTimer() { mFlags.Set(Flags::kFastAdvertisingEnabled, 0); mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } @@ -230,7 +230,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -355,7 +355,7 @@ bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) // Force a refresh of the advertising state. mFlags.Set(Flags::kAdvertisingRefreshNeeded); mFlags.Clear(Flags::kAdvertisingConfigured); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return (err == CHIP_NO_ERROR); } @@ -1019,7 +1019,7 @@ int BLEManagerImpl::ble_svr_gap_event(struct ble_gap_event * event, void * arg) } // Schedule DriveBLEState() to run. - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return ChipError::AsInteger(err); } @@ -1064,7 +1064,7 @@ int BLEManagerImpl::gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_hand break; } - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return err; } diff --git a/src/platform/K32W/BLEManagerImpl.cpp b/src/platform/K32W/BLEManagerImpl.cpp index 92a700bebda816..971f2129c82276 100644 --- a/src/platform/K32W/BLEManagerImpl.cpp +++ b/src/platform/K32W/BLEManagerImpl.cpp @@ -306,7 +306,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -322,7 +322,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) if (mFlags.Has(Flags::kAdvertisingEnabled) != val) { mFlags.Set(Flags::kAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -343,7 +343,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kRestartAdvertising); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -417,7 +417,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) ChipLogProgress(DeviceLayer, "_OnPlatformEvent kServiceProvisioningChange"); mFlags.Clear(Flags::kAdvertisingEnabled); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); break; #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED @@ -1041,7 +1041,7 @@ void BLEManagerImpl::HandleConnectEvent(blekw_msg_t * msg) blekw_start_connection_timeout(); sInstance.AddConnection(device_id_loc); mFlags.Set(Flags::kRestartAdvertising); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } void BLEManagerImpl::HandleConnectionCloseEvent(blekw_msg_t * msg) @@ -1059,7 +1059,7 @@ void BLEManagerImpl::HandleConnectionCloseEvent(blekw_msg_t * msg) PlatformMgr().PostEvent(&event); mFlags.Set(Flags::kRestartAdvertising); mFlags.Set(Flags::kFastAdvertisingEnabled); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } diff --git a/src/platform/K32W/ConfigurationManagerImpl.cpp b/src/platform/K32W/ConfigurationManagerImpl.cpp index c50a40759d5645..742634f3c802f1 100644 --- a/src/platform/K32W/ConfigurationManagerImpl.cpp +++ b/src/platform/K32W/ConfigurationManagerImpl.cpp @@ -74,7 +74,7 @@ bool ConfigurationManagerImpl::_CanFactoryReset() void ConfigurationManagerImpl::_InitiateFactoryReset() { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key persistedStorageKey, diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 74658c666d72b7..d9022ca0662138 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -86,7 +86,7 @@ CHIP_ERROR BLEManagerImpl::_Init() OnChipBleConnectReceived = HandleIncomingBleConnection; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); exit: return err; @@ -102,7 +102,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -118,7 +118,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) mFlags.Set(Flags::kAdvertisingEnabled, val); } - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return err; } @@ -137,7 +137,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -731,7 +731,7 @@ void BLEManagerImpl::NewConnection(BleLayer * bleLayer, void * appState, const u mBLEScanConfig.mAppState = appState; // Scan initiation performed async, to ensure that the BLE subsystem is initialized. - PlatformMgr().ScheduleWork(InitiateScan, static_cast(BleScanState::kScanForDiscriminator)); + PlatformMgr().PlatformScheduleWork(InitiateScan, static_cast(BleScanState::kScanForDiscriminator)); } CHIP_ERROR BLEManagerImpl::CancelConnection() @@ -803,7 +803,7 @@ void BLEManagerImpl::OnDeviceScanned(BluezDevice1 * device, const chip::Ble::Chi } mBLEScanConfig.mBleScanState = BleScanState::kConnecting; - DeviceLayer::SystemLayer.StartTimer(kConnectTimeoutMs, HandleConnectTimeout, mpEndpoint); + DeviceLayer::SystemLayer.StartFunctTimer(kConnectTimeoutMs, HandleConnectTimeout, mpEndpoint); mDeviceScanner->StopScan(); ConnectDevice(device, mpEndpoint); diff --git a/src/platform/Linux/ConfigurationManagerImpl.cpp b/src/platform/Linux/ConfigurationManagerImpl.cpp index edd040353308bf..3c5e8f2df0752e 100644 --- a/src/platform/Linux/ConfigurationManagerImpl.cpp +++ b/src/platform/Linux/ConfigurationManagerImpl.cpp @@ -109,7 +109,7 @@ bool ConfigurationManagerImpl::_CanFactoryReset() void ConfigurationManagerImpl::_InitiateFactoryReset() { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index 1f6be7b5388bae..f962c243e35049 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -400,7 +400,7 @@ CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val) ChipLogProgress(DeviceLayer, "WiFi AP mode change: %s -> %s", WiFiAPModeToStr(mWiFiAPMode), WiFiAPModeToStr(val)); mWiFiAPMode = val; - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } exit: @@ -413,7 +413,7 @@ void ConnectivityManagerImpl::_DemandStartWiFiAP() { ChipLogProgress(DeviceLayer, "wpa_supplicant: Demand start WiFi AP"); mLastAPDemandTime = System::Clock::GetMonotonicMilliseconds(); - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } else { @@ -427,7 +427,7 @@ void ConnectivityManagerImpl::_StopOnDemandWiFiAP() { ChipLogProgress(DeviceLayer, "wpa_supplicant: Demand stop WiFi AP"); mLastAPDemandTime = 0; - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } else { @@ -449,7 +449,7 @@ void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP() void ConnectivityManagerImpl::_SetWiFiAPIdleTimeoutMS(uint32_t val) { mWiFiAPIdleTimeoutMS = val; - SystemLayer.ScheduleWork(DriveAPState, NULL); + SystemLayer.SystemScheduleWork(DriveAPState, NULL); } void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) @@ -679,7 +679,7 @@ void ConnectivityManagerImpl::DriveAPState() // Compute the amount of idle time before the AP should be deactivated and // arm a timer to fire at that time. apTimeout = (uint32_t)((mLastAPDemandTime + mWiFiAPIdleTimeoutMS) - now); - err = SystemLayer.StartTimer(apTimeout, DriveAPState, NULL); + err = SystemLayer.StartFunctTimer(apTimeout, DriveAPState, NULL); SuccessOrExit(err); ChipLogProgress(DeviceLayer, "Next WiFi AP timeout in %" PRIu32 " s", apTimeout / 1000); } diff --git a/src/platform/Linux/SystemPlatformConfig.h b/src/platform/Linux/SystemPlatformConfig.h index fb8cbda00dc0fc..296e778c019d8a 100644 --- a/src/platform/Linux/SystemPlatformConfig.h +++ b/src/platform/Linux/SystemPlatformConfig.h @@ -37,9 +37,7 @@ struct ChipDeviceEvent; #define CHIP_SYSTEM_CONFIG_POSIX_LOCKING 1 #define CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING 0 #define CHIP_SYSTEM_CONFIG_NO_LOCKING 0 -#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 0 - -#define CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS 1 +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1 // ========== Platform-specific Configuration Overrides ========= diff --git a/src/platform/Linux/bluez/ChipDeviceScanner.cpp b/src/platform/Linux/bluez/ChipDeviceScanner.cpp index 339a8488f55eaa..423798d1813b7e 100644 --- a/src/platform/Linux/bluez/ChipDeviceScanner.cpp +++ b/src/platform/Linux/bluez/ChipDeviceScanner.cpp @@ -131,7 +131,7 @@ CHIP_ERROR ChipDeviceScanner::StartScan(unsigned timeoutMs) return CHIP_ERROR_INTERNAL; } - CHIP_ERROR err = chip::DeviceLayer::SystemLayer.StartTimer(timeoutMs, TimerExpiredCallback, static_cast(this)); + CHIP_ERROR err = chip::DeviceLayer::SystemLayer.StartFunctTimer(timeoutMs, TimerExpiredCallback, static_cast(this)); if (err != CHIP_NO_ERROR) { diff --git a/src/platform/SystemEventSupport.cpp b/src/platform/SystemEventSupport.cpp index d376c8b21a867a..cc1fb7f78aa4fb 100644 --- a/src/platform/SystemEventSupport.cpp +++ b/src/platform/SystemEventSupport.cpp @@ -29,12 +29,10 @@ namespace chip { namespace System { -namespace Platform { -namespace Eventing { using namespace ::chip::DeviceLayer; -CHIP_ERROR PostEvent(System::Layer & aLayer, System::Object & aTarget, System::EventType aType, uintptr_t aArgument) +CHIP_ERROR PlatformEventing::EventingPostEvent(System::Layer & aLayer, System::Object & aTarget, System::EventType aType, uintptr_t aArgument) { ChipDeviceEvent event; event.Type = DeviceEventType::kChipSystemLayerEvent; @@ -47,21 +45,24 @@ CHIP_ERROR PostEvent(System::Layer & aLayer, System::Object & aTarget, System::E return CHIP_NO_ERROR; } -CHIP_ERROR DispatchEvents(System::Layer & aLayer) +CHIP_ERROR PlatformEventing::EventingDispatchEvents(System::Layer & aLayer) { PlatformMgr().RunEventLoop(); return CHIP_NO_ERROR; } -CHIP_ERROR DispatchEvent(System::Layer & aLayer, const ChipDeviceEvent * aEvent) +CHIP_ERROR PlatformEventing::EventingDispatchEvent(System::Layer & aLayer, const ChipDeviceEvent * aEvent) { PlatformMgr().DispatchEvent(aEvent); return CHIP_NO_ERROR; } -} // namespace Eventing -} // namespace Platform +CHIP_ERROR PlatformEventing::EventingStartTimer(System::Layer & aLayer, uint32_t aMilliseconds) +{ + return PlatformMgr().StartChipTimer(aMilliseconds); +} + } // namespace System } // namespace chip diff --git a/src/platform/SystemTimerSupport.cpp b/src/platform/SystemTimerSupport.cpp deleted file mode 100644 index 6c797054146a43..00000000000000 --- a/src/platform/SystemTimerSupport.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2018 Nest Labs, Inc. - * 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. - */ - -/** - * @file - * Provides implementations of the CHIP System Layer platform - * timer functions that are suitable for use on all platforms. - */ -/* this file behaves like a config.h, comes first */ -#include - -#include - -namespace chip { -namespace System { -namespace Platform { -namespace Eventing { - -using namespace ::chip::DeviceLayer; - -CHIP_ERROR StartTimer(System::Layer & aLayer, uint32_t aMilliseconds) -{ - return PlatformMgr().StartChipTimer(aMilliseconds); -} - -} // namespace Eventing -} // namespace Platform -} // namespace System -} // namespace chip diff --git a/src/platform/Zephyr/BLEManagerImpl.cpp b/src/platform/Zephyr/BLEManagerImpl.cpp index 8dcad3a2ba6dc0..ccc562be49eb76 100644 --- a/src/platform/Zephyr/BLEManagerImpl.cpp +++ b/src/platform/Zephyr/BLEManagerImpl.cpp @@ -128,7 +128,7 @@ CHIP_ERROR BLEManagerImpl::_Init() // Initialize the CHIP BleLayer. ReturnErrorOnFailure(BleLayer::Init(this, this, &SystemLayer)); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -263,15 +263,15 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) if (mFlags.Has(Flags::kFastAdvertisingEnabled)) { // Start timer to change advertising interval. - SystemLayer.StartTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME, HandleBLEAdvertisementIntervalChange, - this); + SystemLayer.StartFunctTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME, + HandleBLEAdvertisementIntervalChange, this); } // Start timer to disable CHIPoBLE advertisement after timeout expiration only if it isn't advertising rerun (in that case // timer is already running). if (!isAdvertisingRerun) { - SystemLayer.StartTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT, HandleBLEAdvertisementTimeout, this); + SystemLayer.StartFunctTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT, HandleBLEAdvertisementTimeout, this); } } @@ -318,7 +318,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } return CHIP_NO_ERROR; @@ -334,7 +334,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) ChipLogDetail(DeviceLayer, "SetAdvertisingEnabled(%s)", val ? "true" : "false"); mFlags.Set(Flags::kAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } return CHIP_NO_ERROR; @@ -354,7 +354,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -396,7 +396,7 @@ CHIP_ERROR BLEManagerImpl::HandleGAPConnect(const ChipDeviceEvent * event) ChipLogProgress(DeviceLayer, "Current number of connections: %" PRIu16 "/%" PRIu16, NumConnections(), CONFIG_BT_MAX_CONN); mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); bt_conn_unref(connEvent->BtConn); @@ -442,7 +442,7 @@ CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event) // Force a reconfiguration of advertising in case we switched to non-connectable mode when // the BLE connection was established. mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -578,7 +578,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } diff --git a/src/platform/Zephyr/ConfigurationManagerImpl.cpp b/src/platform/Zephyr/ConfigurationManagerImpl.cpp index c0a0a85ae9d5c7..f06d4595ebb662 100644 --- a/src/platform/Zephyr/ConfigurationManagerImpl.cpp +++ b/src/platform/Zephyr/ConfigurationManagerImpl.cpp @@ -84,7 +84,7 @@ CHIP_ERROR ConfigurationManagerImpl::_Init() void ConfigurationManagerImpl::_InitiateFactoryReset() { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) diff --git a/src/platform/cc13x2_26x2/ConfigurationManagerImpl.cpp b/src/platform/cc13x2_26x2/ConfigurationManagerImpl.cpp index c630c1f4bbcf3a..5f2b5ae385c703 100644 --- a/src/platform/cc13x2_26x2/ConfigurationManagerImpl.cpp +++ b/src/platform/cc13x2_26x2/ConfigurationManagerImpl.cpp @@ -82,7 +82,7 @@ bool ConfigurationManagerImpl::_CanFactoryReset() void ConfigurationManagerImpl::_InitiateFactoryReset() { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) diff --git a/src/platform/mbed/BLEManagerImpl.cpp b/src/platform/mbed/BLEManagerImpl.cpp index 8cdbeb3ab1e539..47d5e261c3c9c7 100644 --- a/src/platform/mbed/BLEManagerImpl.cpp +++ b/src/platform/mbed/BLEManagerImpl.cpp @@ -186,7 +186,7 @@ class GapEventHandler : private mbed::NonCopyable, public ble:: chip_event.CHIPoBLEAdvertisingChange.Result = kActivity_Started; PlatformMgrImpl().PostEvent(&chip_event); - PlatformMgr().ScheduleWork(ble_manager.DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(ble_manager.DriveBLEState, 0); } /* Called when advertising ends. @@ -215,7 +215,7 @@ class GapEventHandler : private mbed::NonCopyable, public ble:: ble_manager.mFlags.Set(ble_manager.kFlag_AdvertisingRefreshNeeded); ChipLogDetail(DeviceLayer, "Restarting advertising to allow more connections."); } - PlatformMgr().ScheduleWork(ble_manager.DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(ble_manager.DriveBLEState, 0); } /* Called when connection attempt ends or an advertising device has been @@ -314,7 +314,7 @@ class GapEventHandler : private mbed::NonCopyable, public ble:: // Force a reconfiguration of advertising in case we switched to non-connectable mode when // the BLE connection was established. ble_manager.mFlags.Set(ble_manager.kFlag_AdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(ble_manager.DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(ble_manager.DriveBLEState, 0); } void onDataLengthChange(ble::connection_handle_t connectionHandle, uint16_t txSize, uint16_t rxSize) @@ -575,7 +575,7 @@ CHIP_ERROR BLEManagerImpl::_Init() ReturnErrorOnFailure(sCHIPService.init(ble_interface)); ble_interface.onEventsToProcess(FunctionPointerWithContext{ - [](ble::BLE::OnEventsToProcessCallbackContext * context) { PlatformMgr().ScheduleWork(DoBLEProcessing, 0); } }); + [](ble::BLE::OnEventsToProcessCallbackContext * context) { PlatformMgr().PlatformScheduleWork(DoBLEProcessing, 0); } }); mbed_err = ble_interface.init([](ble::BLE::InitializationCompleteCallbackContext * context) { BLEMgrImpl().HandleInitComplete(context->error == BLE_ERROR_NONE); @@ -629,7 +629,7 @@ void BLEManagerImpl::HandleInitComplete(bool no_error) err = BleLayer::Init(this, this, &SystemLayer); SuccessOrExit(err); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); #if _BLEMGRIMPL_USE_LEDS led2 = 0; #endif @@ -640,7 +640,7 @@ void BLEManagerImpl::HandleInitComplete(bool no_error) ChipLogError(DeviceLayer, "BLEManager init error: %s ", ErrorStr(err)); ChipLogError(DeviceLayer, "Disabling CHIPoBLE service."); mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } } @@ -717,7 +717,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kFlag_AdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -834,7 +834,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -852,7 +852,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) ChipLogDetail(DeviceLayer, "SetAdvertisingEnabled(%s)", val ? "true" : "false"); mFlags.Set(kFlag_AdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -870,7 +870,7 @@ CHIP_ERROR BLEManagerImpl::_SetFastAdvertisingEnabled(bool val) ChipLogDetail(DeviceLayer, "SetFastAdvertisingEnabled(%s)", val ? "true" : "false"); mFlags.Set(kFlag_FastAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: diff --git a/src/platform/mbed/ConfigurationManagerImpl.cpp b/src/platform/mbed/ConfigurationManagerImpl.cpp index b81657523bb70a..d7b20a302d78e5 100644 --- a/src/platform/mbed/ConfigurationManagerImpl.cpp +++ b/src/platform/mbed/ConfigurationManagerImpl.cpp @@ -93,7 +93,7 @@ bool ConfigurationManagerImpl::_CanFactoryReset() void ConfigurationManagerImpl::_InitiateFactoryReset(void) { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) diff --git a/src/platform/mbed/ConnectivityManagerImpl.cpp b/src/platform/mbed/ConnectivityManagerImpl.cpp index 9062fcf168eaa8..d66ef3a149bfc5 100644 --- a/src/platform/mbed/ConnectivityManagerImpl.cpp +++ b/src/platform/mbed/ConnectivityManagerImpl.cpp @@ -210,7 +210,7 @@ CHIP_ERROR ConnectivityManagerImpl::ProvisionWiFiNetwork(const char * ssid, cons mIsProvisioned = true; - PlatformMgr().ScheduleWork(OnWifiStationChange, 0); + PlatformMgr().PlatformScheduleWork(OnWifiStationChange, 0); return CHIP_NO_ERROR; } @@ -234,7 +234,7 @@ void ConnectivityManagerImpl::_ClearWiFiStationProvision(void) mIsProvisioned = false; - PlatformMgr().ScheduleWork(OnWifiStationChange, 0); + PlatformMgr().PlatformScheduleWork(OnWifiStationChange, 0); } CHIP_ERROR ConnectivityManagerImpl::OnStationConnected() diff --git a/src/platform/qpg/BLEManagerImpl.cpp b/src/platform/qpg/BLEManagerImpl.cpp index 5b449e35ba5675..1d2f90c1bd1479 100644 --- a/src/platform/qpg/BLEManagerImpl.cpp +++ b/src/platform/qpg/BLEManagerImpl.cpp @@ -102,7 +102,7 @@ CHIP_ERROR BLEManagerImpl::_Init() ); VerifyOrExit(sbleAdvTimeoutTimer != NULL, err = CHIP_ERROR_INCORRECT_STATE); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); exit: ChipLogProgress(DeviceLayer, "BLEManagerImpl::Init() complete"); @@ -120,7 +120,7 @@ CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) if (val != mServiceMode) { mServiceMode = val; - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -136,7 +136,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) if (mFlags.Has(Flags::kAdvertisingEnabled) != val) { mFlags.Set(Flags::kAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); } exit: @@ -157,7 +157,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) return CHIP_ERROR_INVALID_ARGUMENT; } mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); return CHIP_NO_ERROR; } @@ -732,7 +732,7 @@ void BLEManagerImpl::HandleDmMsg(qvCHIP_Ble_DmEvt_t * pDmEvt) // Receiving a connection stops the advertising processes. So force a refresh of the advertising // state. mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); break; } case QVCHIP_DM_CONN_CLOSE_IND: { @@ -768,7 +768,7 @@ void BLEManagerImpl::HandleDmMsg(qvCHIP_Ble_DmEvt_t * pDmEvt) } mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + PlatformMgr().PlatformScheduleWork(DriveBLEState, 0); break; } case QVCHIP_DM_CONN_UPDATE_IND: { diff --git a/src/platform/qpg/ConfigurationManagerImpl.cpp b/src/platform/qpg/ConfigurationManagerImpl.cpp index f6af8fc81bcb1c..1578df3082cb90 100644 --- a/src/platform/qpg/ConfigurationManagerImpl.cpp +++ b/src/platform/qpg/ConfigurationManagerImpl.cpp @@ -74,7 +74,7 @@ bool ConfigurationManagerImpl::_CanFactoryReset() void ConfigurationManagerImpl::_InitiateFactoryReset() { - PlatformMgr().ScheduleWork(DoFactoryReset); + PlatformMgr().PlatformScheduleWork(DoFactoryReset); } CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key persistedStorageKey, diff --git a/src/platform/tests/TestPlatformMgr.cpp b/src/platform/tests/TestPlatformMgr.cpp index c825964d9bec9f..1cfda3fc753d4c 100644 --- a/src/platform/tests/TestPlatformMgr.cpp +++ b/src/platform/tests/TestPlatformMgr.cpp @@ -85,7 +85,7 @@ static void TestPlatformMgr_BasicRunEventLoop(nlTestSuite * inSuite, void * inCo CHIP_ERROR err = PlatformMgr().InitChipStack(); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - PlatformMgr().ScheduleWork(StopTheLoop); + PlatformMgr().PlatformScheduleWork(StopTheLoop); PlatformMgr().RunEventLoop(); NL_TEST_ASSERT(inSuite, stopRan); @@ -110,8 +110,8 @@ static void TestPlatformMgr_RunEventLoopTwoTasks(nlTestSuite * inSuite, void * i CHIP_ERROR err = PlatformMgr().InitChipStack(); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - PlatformMgr().ScheduleWork(SleepSome); - PlatformMgr().ScheduleWork(StopTheLoop); + PlatformMgr().PlatformScheduleWork(SleepSome); + PlatformMgr().PlatformScheduleWork(StopTheLoop); PlatformMgr().RunEventLoop(); NL_TEST_ASSERT(inSuite, stopRan); @@ -136,7 +136,7 @@ static void TestPlatformMgr_RunEventLoopStopBeforeSleep(nlTestSuite * inSuite, v CHIP_ERROR err = PlatformMgr().InitChipStack(); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - PlatformMgr().ScheduleWork(StopAndSleep); + PlatformMgr().PlatformScheduleWork(StopAndSleep); PlatformMgr().RunEventLoop(); NL_TEST_ASSERT(inSuite, stopRan); diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index 387ea3c89465aa..a9e5e8bccd6a62 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -95,9 +95,9 @@ buildconfig_header("system_buildconfig") { ] } + defines += [ "CHIP_SYSTEM_WATCHABLE_EVENT_MANAGER_CONFIG_FILE=" ] if (chip_system_config_use_sockets) { - defines += [ "CHIP_SYSTEM_WATCHABLE_EVENT_MANAGER_CONFIG_FILE=" ] - defines += [ "CHIP_SYSTEM_WATCHABLE_SOCKET_CONFIG_FILE=" ] + defines += [ "CHIP_SYSTEM_WATCHABLE_SOCKET_CONFIG_FILE=" ] } } @@ -153,7 +153,8 @@ static_library("system") { "WakeEvent.cpp", "WakeEvent.h", "WatchableEventManager.h", - "WatchableSocket.h", + "WatchableEventManager${chip_system_config_event_loop}.cpp", + "WatchableEventManager${chip_system_config_event_loop}.h", ] cflags = [ "-Wconversion" ] @@ -168,12 +169,11 @@ static_library("system") { if (chip_system_config_use_sockets) { sources += [ - "WatchableEventManager${chip_system_config_sockets_event_loop}.cpp", - "WatchableEventManager${chip_system_config_sockets_event_loop}.h", - "WatchableSocket${chip_system_config_sockets_event_loop}.cpp", - "WatchableSocket${chip_system_config_sockets_event_loop}.h", + "WatchableSocket.h", + "WatchableSocket${chip_system_config_event_loop}.cpp", + "WatchableSocket${chip_system_config_event_loop}.h", ] - if (chip_system_config_sockets_event_loop == "Libevent") { + if (chip_system_config_event_loop == "Libevent") { libs = [ "event" ] } } diff --git a/src/system/SystemClock.cpp b/src/system/SystemClock.cpp index fc6f47ca9457af..fb5080233decca 100644 --- a/src/system/SystemClock.cpp +++ b/src/system/SystemClock.cpp @@ -22,23 +22,8 @@ * for POSIX and LwIP platforms. */ -// __STDC_LIMIT_MACROS must be defined for UINT8_MAX to be defined for pre-C++11 clib -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS -#endif // __STDC_LIMIT_MACROS - -// __STDC_CONSTANT_MACROS must be defined for INT64_C and UINT64_C to be defined for pre-C++11 clib -#ifndef __STDC_CONSTANT_MACROS -#define __STDC_CONSTANT_MACROS -#endif // __STDC_CONSTANT_MACROS - -// config -#include - -#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME - -// module header #include + // common private #include "SystemLayerPrivate.h" @@ -46,23 +31,38 @@ #include #include -#if CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS +#include +#include + +#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME + +#if CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS #include -#if !(HAVE_CLOCK_GETTIME) -#include -#endif #include -#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS +#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS #if CHIP_SYSTEM_CONFIG_USE_LWIP #include #endif // CHIP_SYSTEM_CONFIG_USE_LWIP -#include -#include +#endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME namespace chip { namespace System { + +bool Clock::IsEarlier(const Clock::MonotonicMilliseconds & inFirst, const Clock::MonotonicMilliseconds & inSecond) +{ + static const Clock::MonotonicMilliseconds kMaxTime_2 = static_cast( + (static_cast(0) - static_cast(1)) / 2); + + // account for timer wrap with the assumption that no two input times will "naturally" + // be more than half the timer range apart. + return (((inFirst < inSecond) && (inSecond - inFirst < kMaxTime_2)) || + ((inFirst > inSecond) && (inFirst - inSecond > kMaxTime_2))); +} + +#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME + namespace Platform { namespace Clock { @@ -239,7 +239,25 @@ CHIP_ERROR SetUnixTimeMicroseconds(uint64_t newCurTime) } // namespace Clock } // namespace Platform + +#endif // CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME + +#if CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS + +Clock::MonotonicMilliseconds TimevalToMilliseconds(const timeval & in) +{ + return static_cast(in.tv_sec) * 1000 + + static_cast(in.tv_usec / 1000); +} + +void MillisecondsToTimeval(Clock::MonotonicMilliseconds in, timeval & out) +{ + out.tv_sec = static_cast(in / 1000); + out.tv_usec = static_cast((in % 1000) * 1000); +} + +#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS + } // namespace System } // namespace chip -#endif // CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME diff --git a/src/system/SystemClock.h b/src/system/SystemClock.h index 1c6955ad72b015..4eba25f8f73fe1 100644 --- a/src/system/SystemClock.h +++ b/src/system/SystemClock.h @@ -33,6 +33,10 @@ #include +#if CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS +#include +#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS + namespace chip { namespace System { @@ -146,6 +150,7 @@ extern CHIP_ERROR SetUnixTimeMicroseconds(uint64_t newCurTime); class Clock { public: + // Note: these provide documentation, not type safety. using MonotonicMicroseconds = uint64_t; using MonotonicMilliseconds = uint64_t; using UnixTimeMicroseconds = uint64_t; @@ -251,7 +256,27 @@ class Clock // Current implementation is a simple pass-through to the platform. return Platform::Clock::SetUnixTimeMicroseconds(newCurTime); } + + /** + * Compares two Clock::MonotonicMilliseconds values and returns true if the first value is earlier than the second value. + * + * @brief + * A static API that gets called to compare 2 time values. This API attempts to account for timer wrap by assuming that the + * difference between the 2 input values will only be more than half the timestamp scalar range if a timer wrap has occurred + * between the 2 samples. + * + * @note + * This implementation assumes that Clock::MonotonicMilliseconds is an unsigned scalar type. + * + * @return true if the first param is earlier than the second, false otherwise. + */ + static bool IsEarlier(const Clock::MonotonicMilliseconds & first, const Clock::MonotonicMilliseconds & second); }; +#if CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS +Clock::MonotonicMilliseconds TimevalToMilliseconds(const timeval & in); +void MillisecondsToTimeval(Clock::MonotonicMilliseconds in, timeval & out); +#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS + } // namespace System } // namespace chip diff --git a/src/system/SystemLayer.cpp b/src/system/SystemLayer.cpp index 8c7ac6e7086cf0..73d1c287b1c901 100644 --- a/src/system/SystemLayer.cpp +++ b/src/system/SystemLayer.cpp @@ -22,127 +22,31 @@ * class methods and related data and functions. */ -// Include module header #include -// Include common private header -#include "SystemLayerPrivate.h" - -// Include local headers -#include -#include - -// Include additional CHIP headers #include -#include #include -#include -#include - -// Include system and language headers -#include -#include - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK -#include -#include -#include -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - -#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING -#include - -// Choose an approximation of PTHREAD_NULL if pthread.h doesn't define one. -#ifndef PTHREAD_NULL -#define PTHREAD_NULL 0 -#endif // PTHREAD_NULL -#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING namespace chip { namespace System { -Layer::Layer() : mLayerState(kLayerState_NotInitialized), mPlatformData(nullptr) +Layer::Layer() : mLayerState(kLayerState_NotInitialized) { -#if CHIP_SYSTEM_CONFIG_USE_LWIP - if (!sSystemEventHandlerDelegate.IsInitialized()) - sSystemEventHandlerDelegate.Init(HandleSystemLayerEvent); - - this->mEventDelegateList = NULL; - this->mTimerList = NULL; - this->mTimerComplete = false; -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK -#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING - this->mHandleSelectThread = PTHREAD_NULL; -#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK } CHIP_ERROR Layer::Init() { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - RegisterPOSIXErrorFormatter(); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS -#if CHIP_SYSTEM_CONFIG_USE_LWIP - RegisterLwIPErrorFormatter(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - - if (this->mLayerState != kLayerState_NotInitialized) - return CHIP_ERROR_INCORRECT_STATE; - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS + VerifyOrReturnError(State() == kLayerState_NotInitialized, CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(mWatchableEvents.Init(*this)); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS -#if CHIP_SYSTEM_CONFIG_USE_LWIP - this->AddEventHandlerDelegate(sSystemEventHandlerDelegate); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - this->mLayerState = kLayerState_Initialized; - return CHIP_NO_ERROR; } CHIP_ERROR Layer::Shutdown() { - if (this->mLayerState == kLayerState_NotInitialized) - return CHIP_ERROR_INCORRECT_STATE; - - for (size_t i = 0; i < Timer::sPool.Size(); ++i) - { - Timer * lTimer = Timer::sPool.Get(*this, i); - - if (lTimer != nullptr) - { - lTimer->Cancel(); - } - } - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS + VerifyOrReturnError(State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(mWatchableEvents.Shutdown()); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - this->mLayerState = kLayerState_NotInitialized; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR Layer::NewTimer(Timer *& aTimerPtr) -{ - Timer * lTimer = nullptr; - - if (this->State() != kLayerState_Initialized) - return CHIP_ERROR_INCORRECT_STATE; - - lTimer = Timer::sPool.TryCreate(*this); - aTimerPtr = lTimer; - - if (lTimer == nullptr) - { - ChipLogError(chipSystemLayer, "Timer pool EMPTY"); - return CHIP_ERROR_NO_MEMORY; - } - return CHIP_NO_ERROR; } @@ -155,32 +59,19 @@ CHIP_ERROR Layer::NewTimer(Timer *& aTimerPtr) * arguments. If called with @a aComplete and @a aAppState identical to an existing timer, * the currently-running timer will first be cancelled. * - * @param[in] aMilliseconds Expiration time in milliseconds. - * @param[in] aComplete A pointer to the function called when timer expires. - * @param[in] aAppState A pointer to the application state object used when timer expires. + * @param[in] aDelayMilliseconds Time in milliseconds before this timer fires. + * @param[in] aComplete A pointer to the function called when timer expires. + * @param[in] aAppState A pointer to the application state object used when timer expires. * * @return CHIP_NO_ERROR On success. * @return CHIP_ERROR_NO_MEMORY If a timer cannot be allocated. * @return Other Value indicating timer failed to start. * */ -CHIP_ERROR Layer::StartTimer(uint32_t aMilliseconds, TimerCompleteFunct aComplete, void * aAppState) +CHIP_ERROR Layer::StartFunctTimer(uint32_t aDelayMilliseconds, Timers::OnCompleteFunct aComplete, void * aAppState) { - CHIP_ERROR lReturn; - Timer * lTimer; - - this->CancelTimer(aComplete, aAppState); - lReturn = this->NewTimer(lTimer); - SuccessOrExit(lReturn); - - lReturn = lTimer->Start(aMilliseconds, aComplete, aAppState); - if (lReturn != CHIP_NO_ERROR) - { - lTimer->Release(); - } - -exit: - return lReturn; + VerifyOrReturnError(State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + return mWatchableEvents.WeStartTimer(aDelayMilliseconds, aComplete, aAppState); } /** @@ -196,32 +87,21 @@ CHIP_ERROR Layer::StartTimer(uint32_t aMilliseconds, TimerCompleteFunct aComplet * @param[in] aAppState A pointer to the application state object used in calling @p StartTimer(). * */ -void Layer::CancelTimer(Layer::TimerCompleteFunct aOnComplete, void * aAppState) +void Layer::CancelTimer(Timers::OnCompleteFunct aOnComplete, void * aAppState) { - if (this->State() != kLayerState_Initialized) - return; - - for (size_t i = 0; i < Timer::sPool.Size(); ++i) - { - Timer * lTimer = Timer::sPool.Get(*this, i); - - if (lTimer != nullptr && lTimer->OnComplete == aOnComplete && lTimer->AppState == aAppState) - { - lTimer->Cancel(); - break; - } - } + VerifyOrReturn(this->State() == kLayerState_Initialized); + return mWatchableEvents.WeCancelTimer(aOnComplete, aAppState); } /** * @brief * Schedules a function with a signature identical to - * `TimerCompleteFunct` to be run as soon as possible on the CHIP + * `OnCompleteFunct` to be run as soon as possible on the CHIP * thread. * * @note * This function could, in principle, be implemented as - * `StartTimer`. The specification for + * `StartFunctTimer`. The specification for * `SystemTimer` however permits certain optimizations that might * make that implementation impossible. Specifically, `SystemTimer` * API may only be called from the thread owning the particular @@ -245,330 +125,12 @@ void Layer::CancelTimer(Layer::TimerCompleteFunct aOnComplete, void * aAppState) * * @retval CHIP_NO_ERROR On success. */ -CHIP_ERROR Layer::ScheduleWork(TimerCompleteFunct aComplete, void * aAppState) -{ - assertChipStackLockedByCurrentThread(); - - CHIP_ERROR lReturn; - Timer * lTimer; - - lReturn = this->NewTimer(lTimer); - SuccessOrExit(lReturn); - - lReturn = lTimer->ScheduleWork(aComplete, aAppState); - if (lReturn != CHIP_NO_ERROR) - { - lTimer->Release(); - } - -exit: - return lReturn; -} - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK - -bool Layer::GetTimeout(struct timeval & aSleepTime) -{ - if (this->State() != kLayerState_Initialized) - return false; - - const Clock::MonotonicMilliseconds kCurrentTime = Clock::GetMonotonicMilliseconds(); - Clock::MonotonicMilliseconds lAwakenTime = kCurrentTime + static_cast(aSleepTime.tv_sec) * 1000 + - static_cast(aSleepTime.tv_usec) / 1000; - - bool anyTimer = false; - for (size_t i = 0; i < Timer::sPool.Size(); i++) - { - Timer * lTimer = Timer::sPool.Get(*this, i); - - if (lTimer != nullptr) - { - anyTimer = true; - - if (!Timer::IsEarlier(kCurrentTime, lTimer->mAwakenTime)) - { - lAwakenTime = kCurrentTime; - break; - } - - if (Timer::IsEarlier(lTimer->mAwakenTime, lAwakenTime)) - lAwakenTime = lTimer->mAwakenTime; - } - } - - const Clock::MonotonicMilliseconds kSleepTime = lAwakenTime - kCurrentTime; - aSleepTime.tv_sec = static_cast(kSleepTime / 1000); - aSleepTime.tv_usec = static_cast((kSleepTime % 1000) * 1000); - - return anyTimer; -} - -void Layer::HandleTimeout() +CHIP_ERROR Layer::SystemScheduleWork(Timers::OnCompleteFunct aComplete, void * aAppState) { assertChipStackLockedByCurrentThread(); - -#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING - this->mHandleSelectThread = pthread_self(); -#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING - - const Clock::MonotonicMilliseconds kCurrentTime = Clock::GetMonotonicMilliseconds(); - - for (size_t i = 0; i < Timer::sPool.Size(); i++) - { - Timer * lTimer = Timer::sPool.Get(*this, i); - - if (lTimer != nullptr && !Timer::IsEarlier(kCurrentTime, lTimer->mAwakenTime)) - { - lTimer->HandleComplete(); - } - } - -#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING - this->mHandleSelectThread = PTHREAD_NULL; -#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING -} - -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK - -#if CHIP_SYSTEM_CONFIG_USE_LWIP -LwIPEventHandlerDelegate Layer::sSystemEventHandlerDelegate; - -bool LwIPEventHandlerDelegate::IsInitialized() const -{ - return this->mFunction != NULL; -} - -void LwIPEventHandlerDelegate::Init(LwIPEventHandlerFunction aFunction) -{ - this->mFunction = aFunction; - this->mNextDelegate = NULL; -} - -void LwIPEventHandlerDelegate::Prepend(const LwIPEventHandlerDelegate *& aDelegateList) -{ - this->mNextDelegate = aDelegateList; - aDelegateList = this; -} - -/** - * This is the dispatch handler for system layer events. - * - * @param[in,out] aTarget A pointer to the CHIP System Layer object making the post request. - * @param[in] aEventType The type of event to post. - * @param[in,out] aArgument The argument associated with the event to post. - */ -CHIP_ERROR Layer::HandleSystemLayerEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) -{ - CHIP_ERROR lReturn = CHIP_NO_ERROR; - ; - - // Dispatch logic specific to the event type - switch (aEventType) - { - case kEvent_ReleaseObj: - aTarget.Release(); - break; - - case kEvent_ScheduleWork: - static_cast(aTarget).HandleComplete(); - break; - - default: - lReturn = CHIP_ERROR_UNEXPECTED_EVENT; - break; - } - - return lReturn; -} - -/** - * This adds an event handler delegate to the system layer to extend its ability to handle LwIP events. - * - * @param[in] aDelegate An uninitialied LwIP event handler delegate structure - * - * @retval CHIP_NO_ERROR On success. - * @retval CHIP_ERROR_INVALID_ARGUMENT If the function pointer contained in aDelegate is NULL - */ -CHIP_ERROR Layer::AddEventHandlerDelegate(LwIPEventHandlerDelegate & aDelegate) -{ - CHIP_ERROR lReturn; - - VerifyOrExit(aDelegate.mFunction != NULL, lReturn = CHIP_ERROR_INVALID_ARGUMENT); - aDelegate.Prepend(this->mEventDelegateList); - lReturn = CHIP_NO_ERROR; - -exit: - return lReturn; -} - -/** - * This posts an event / message of the specified type with the provided argument to this instance's platform-specific event - * queue. - * - * @param[in,out] aTarget A pointer to the CHIP System Layer object making the post request. - * @param[in] aEventType The type of event to post. - * @param[in,out] aArgument The argument associated with the event to post. - * - * @retval CHIP_NO_ERROR On success. - * @retval CHIP_ERROR_INCORRECT_STATE If the state of the Layer object is incorrect. - * @retval CHIP_ERROR_NO_MEMORY If the event queue is already full. - * @retval other Platform-specific errors generated indicating the reason for failure. - */ -CHIP_ERROR Layer::PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) -{ - CHIP_ERROR lReturn = CHIP_NO_ERROR; - VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_ERROR_INCORRECT_STATE); - - // Sanity check that this instance and the target layer haven't been "crossed". - VerifyOrDieWithMsg(aTarget.IsRetained(*this), chipSystemLayer, "wrong poster! [target %p != this %p]", &(aTarget.SystemLayer()), - this); - - lReturn = Platform::Eventing::PostEvent(*this, aTarget, aEventType, aArgument); - if (lReturn != CHIP_NO_ERROR) - { - ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer event (type %d): %s", aEventType, ErrorStr(lReturn)); - } - SuccessOrExit(lReturn); - -exit: - return lReturn; -} - -/** - * This is a syntactic wrapper around a platform-specific hook that effects an event loop, waiting on a queue that services this - * instance, pulling events off of that queue, and then dispatching them for handling. - * - * @return #CHIP_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure. - */ -CHIP_ERROR Layer::DispatchEvents() -{ - CHIP_ERROR lReturn = CHIP_NO_ERROR; - VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_ERROR_INCORRECT_STATE); - - lReturn = Platform::Eventing::DispatchEvents(*this); - SuccessOrExit(lReturn); - -exit: - return lReturn; -} - -/** - * This dispatches the specified event for handling by this instance. - * - * The unmarshalling of the type and arguments from the event is handled by a platform-specific hook which should then call - * back to Layer::HandleEvent for the actual dispatch. - * - * @param[in] aEvent The platform-specific event object to dispatch for handling. - * - * @return CHIP_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure. - */ -CHIP_ERROR Layer::DispatchEvent(Event aEvent) -{ - CHIP_ERROR lReturn = CHIP_NO_ERROR; - VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_ERROR_INCORRECT_STATE); - - lReturn = Platform::Eventing::DispatchEvent(*this, aEvent); - SuccessOrExit(lReturn); - -exit: - return lReturn; -} - -/** - * This implements the actual dispatch and handling of a CHIP System Layer event. - * - * @param[in,out] aTarget A reference to the layer object to which the event is targeted. - * @param[in] aEventType The event / message type to handle. - * @param[in] aArgument The argument associated with the event / message. - * - * @retval CHIP_NO_ERROR On success. - * @retval CHIP_ERROR_INCORRECT_STATE If the state of the InetLayer object is incorrect. - * @retval CHIP_ERROR_UNEXPECTED_EVENT If the event type is unrecognized. - */ -CHIP_ERROR Layer::HandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) -{ - const LwIPEventHandlerDelegate * lEventDelegate; - CHIP_ERROR lReturn; - VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_ERROR_INCORRECT_STATE); - - // Sanity check that this instance and the target layer haven't been "crossed". - VerifyOrDieWithMsg(aTarget.IsRetained(*this), chipSystemLayer, "wrong handler! [target %p != this %p]", - &(aTarget.SystemLayer()), this); - - lReturn = CHIP_ERROR_UNEXPECTED_EVENT; - lEventDelegate = this->mEventDelegateList; - - // Prevent the target object from being freed while dispatching the event. - aTarget.Retain(); - - while (lReturn == CHIP_ERROR_UNEXPECTED_EVENT && lEventDelegate != NULL) - { - lReturn = lEventDelegate->mFunction(aTarget, aEventType, aArgument); - lEventDelegate = lEventDelegate->mNextDelegate; - } - - if (lReturn == CHIP_ERROR_UNEXPECTED_EVENT) - { - ChipLogError(chipSystemLayer, "Unexpected event type %d", aEventType); - } - - /* - Release the reference to the target object. When the object's lifetime finally comes to an end, in most cases this will be - the release call that decrements the ref count to zero. - */ - aTarget.Release(); - -exit: - return lReturn; -} - -/** - * Start the platform timer with specified millsecond duration. - * - * @brief - * Calls the Platform specific API to start a platform timer. This API is called by the chip::System::Timer class when - * one or more timers are active and require deferred execution. - * - * @param[in] aDelayMilliseconds The timer duration in milliseconds. - * - * @return CHIP_NO_ERROR on success, error code otherwise. - * - */ -CHIP_ERROR Layer::StartPlatformTimer(uint32_t aDelayMilliseconds) -{ - CHIP_ERROR lReturn = CHIP_NO_ERROR; - VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_ERROR_INCORRECT_STATE); - - lReturn = Platform::Eventing::StartTimer(*this, aDelayMilliseconds); - SuccessOrExit(lReturn); - -exit: - return lReturn; -} - -/** - * Handle the platform timer expiration event. - * - * @brief - * Calls chip::System::Timer::HandleExpiredTimers to handle any expired timers. It is assumed that this API is called - * only while on the thread which owns the CHIP System Layer object. - * - * @return CHIP_NO_ERROR on success, error code otherwise. - * - */ -CHIP_ERROR Layer::HandlePlatformTimer() -{ - CHIP_ERROR lReturn = CHIP_NO_ERROR; - VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_ERROR_INCORRECT_STATE); - - lReturn = Timer::HandleExpiredTimers(*this); - - SuccessOrExit(lReturn); - -exit: - return lReturn; + VerifyOrReturnError(State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + return mWatchableEvents.WeScheduleWork(aComplete, aAppState); } -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP } // namespace System } // namespace chip diff --git a/src/system/SystemLayer.h b/src/system/SystemLayer.h index 8bf08971df06c9..af753f4e4920e8 100644 --- a/src/system/SystemLayer.h +++ b/src/system/SystemLayer.h @@ -36,17 +36,7 @@ #include #include #include - -// Include dependent headers -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS -#include #include -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - -#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING -#include -#include -#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING #if CHIP_SYSTEM_CONFIG_USE_DISPATCH #include @@ -59,16 +49,13 @@ class Layer; class Timer; class Object; -namespace Platform { -namespace Eventing { - -extern CHIP_ERROR PostEvent(System::Layer & aLayer, Object & aTarget, EventType aType, uintptr_t aArgument); -extern CHIP_ERROR DispatchEvents(System::Layer & aLayer); -extern CHIP_ERROR DispatchEvent(System::Layer & aLayer, Event aEvent); -extern CHIP_ERROR StartTimer(System::Layer & aLayer, uint32_t aMilliseconds); - -} // namespace Eventing -} // namespace Platform +class PlatformEventing { +public: + static CHIP_ERROR EventingPostEvent(System::Layer & aLayer, Object & aTarget, EventType aType, uintptr_t aArgument); + static CHIP_ERROR EventingDispatchEvents(System::Layer & aLayer); + static CHIP_ERROR EventingDispatchEvent(System::Layer & aLayer, Event aEvent); + static CHIP_ERROR EventingStartTimer(System::Layer & aLayer, uint32_t aMilliseconds); +}; /** * @enum LayerState @@ -81,34 +68,8 @@ enum LayerState kLayerState_Initialized = 1 /**< Initialized state. */ }; -#if CHIP_SYSTEM_CONFIG_USE_LWIP -typedef CHIP_ERROR (*LwIPEventHandlerFunction)(Object & aTarget, EventType aEventType, uintptr_t aArgument); - -class LwIPEventHandlerDelegate -{ - friend class Layer; - -public: - bool IsInitialized(void) const; - void Init(LwIPEventHandlerFunction aFunction); - void Prepend(const LwIPEventHandlerDelegate *& aDelegateList); - -private: - LwIPEventHandlerFunction mFunction; - const LwIPEventHandlerDelegate * mNextDelegate; -}; -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - /** - * @class Layer - * - * @brief - * This provides access to timers according to the configured event handling model. - * - * For \c CHIP_SYSTEM_CONFIG_USE_SOCKETS, event readiness notification is handled via WatchableEventManager. - * - * For \c CHIP_SYSTEM_CONFIG_USE_LWIP, event readiness notification is handle via events / messages and platform- and - * system-specific hooks for the event/message system. + * This provides access to timers according to the configured event handling model. */ class DLL_EXPORT Layer { @@ -121,92 +82,24 @@ class DLL_EXPORT Layer // to ensure that they are not used after calling Shutdown(). CHIP_ERROR Shutdown(); - LayerState State() const; - - CHIP_ERROR NewTimer(Timer *& aTimerPtr); - - using TimerCompleteFunct = Timer::OnCompleteFunct; - // typedef void (*TimerCompleteFunct)(Layer * aLayer, void * aAppState, CHIP_ERROR aError); - CHIP_ERROR StartTimer(uint32_t aMilliseconds, TimerCompleteFunct aComplete, void * aAppState); - void CancelTimer(TimerCompleteFunct aOnComplete, void * aAppState); - - CHIP_ERROR ScheduleWork(TimerCompleteFunct aComplete, void * aAppState); - - Clock & GetClock() { return mClock; } + LayerState State() const { return mLayerState; } -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK + CHIP_ERROR StartFunctTimer(uint32_t aMilliseconds, Timers::OnCompleteFunct aComplete, void * aAppState); + void CancelTimer(Timers::OnCompleteFunct aOnComplete, void * aAppState); + CHIP_ERROR SystemScheduleWork(Timers::OnCompleteFunct aComplete, void * aAppState); WatchableEventManager & WatchableEvents() { return mWatchableEvents; } - bool GetTimeout(struct timeval & aSleepTime); // TODO(#5556): Integrate timer platform details with WatchableEventManager. - void HandleTimeout(); // TODO(#5556): Integrate timer platform details with WatchableEventManager. -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK -#if CHIP_SYSTEM_CONFIG_USE_LWIP - typedef CHIP_ERROR (*EventHandler)(Object & aTarget, EventType aEventType, uintptr_t aArgument); - CHIP_ERROR AddEventHandlerDelegate(LwIPEventHandlerDelegate & aDelegate); - - // Event Handling - CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument); - CHIP_ERROR DispatchEvents(void); - CHIP_ERROR DispatchEvent(Event aEvent); - CHIP_ERROR HandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument); - - // Timer Management - CHIP_ERROR HandlePlatformTimer(void); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - void SetDispatchQueue(dispatch_queue_t dispatchQueue) { mDispatchQueue = dispatchQueue; }; - dispatch_queue_t GetDispatchQueue() { return mDispatchQueue; }; -#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH + Clock & GetClock() { return mClock; } private: LayerState mLayerState; - void * mPlatformData; - Clock mClock; - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK WatchableEventManager mWatchableEvents; -#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING - friend class WatchableEventManager; - std::atomic mHandleSelectThread; -#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - static LwIPEventHandlerDelegate sSystemEventHandlerDelegate; - - const LwIPEventHandlerDelegate * mEventDelegateList; - Timer * mTimerList; - bool mTimerComplete; - - static CHIP_ERROR HandleSystemLayerEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument); - - CHIP_ERROR StartPlatformTimer(uint32_t aDelayMilliseconds); - - friend CHIP_ERROR Platform::Eventing::PostEvent(Layer & aLayer, Object & aTarget, EventType aType, uintptr_t aArgument); - friend CHIP_ERROR Platform::Eventing::DispatchEvents(Layer & aLayer); - friend CHIP_ERROR Platform::Eventing::DispatchEvent(Layer & aLayer, Event aEvent); - friend CHIP_ERROR Platform::Eventing::StartTimer(Layer & aLayer, uint32_t aMilliseconds); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t mDispatchQueue; -#endif + Clock mClock; // Copy and assignment NOT DEFINED Layer(const Layer &) = delete; Layer & operator=(const Layer &) = delete; - - friend class Timer; }; -/** - * This returns the current state of the layer object. - */ -inline LayerState Layer::State() const -{ - return this->mLayerState; -} - } // namespace System } // namespace chip diff --git a/src/system/SystemMutex.h b/src/system/SystemMutex.h index 8ba9fa395de960..7c75f66282d5f3 100644 --- a/src/system/SystemMutex.h +++ b/src/system/SystemMutex.h @@ -32,8 +32,6 @@ #include -#if !CHIP_SYSTEM_CONFIG_NO_LOCKING - #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING #include #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING @@ -100,10 +98,24 @@ class DLL_EXPORT Mutex Mutex & operator=(const Mutex &) = delete; }; -inline Mutex::Mutex() {} +class ScopedMutexLock +{ +public: + ScopedMutexLock(Mutex & mutex): mMutex(mutex) { mutex.Lock(); } + ~ScopedMutexLock() { mMutex.Unlock(); } +private: + Mutex & mMutex; +}; +inline Mutex::Mutex() {} inline Mutex::~Mutex() {} +#if CHIP_SYSTEM_CONFIG_NO_LOCKING +inline CHIP_ERROR Init(Mutex & aMutex) { return CHIP_NO_ERROR; } +inline void Mutex::Lock() {} +inline void Mutex::Unlock() {} +#endif // CHIP_SYSTEM_CONFIG_NO_LOCKING + #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING inline void Mutex::Lock() { @@ -144,5 +156,3 @@ inline void Mutex::Unlock(void) } // namespace System } // namespace chip - -#endif // !CHIP_SYSTEM_CONFIG_NO_LOCKING diff --git a/src/system/SystemObject.cpp b/src/system/SystemObject.cpp index 3b46936213428b..a837711a2affdf 100644 --- a/src/system/SystemObject.cpp +++ b/src/system/SystemObject.cpp @@ -81,7 +81,7 @@ DLL_EXPORT bool Object::TryCreate(Layer & aLayer, size_t aOctets) void Object::DeferredRelease(Object::ReleaseDeferralErrorTactic aTactic) { Layer & lSystemLayer = *this->mSystemLayer; - CHIP_ERROR lError = lSystemLayer.PostEvent(*this, chip::System::kEvent_ReleaseObj, 0); + CHIP_ERROR lError = lSystemLayer.WatchableEvents().LayerLwIPPostEvent(*this, chip::System::kEvent_ReleaseObj, 0); if (lError != CHIP_NO_ERROR) { diff --git a/src/system/SystemTimer.cpp b/src/system/SystemTimer.cpp index 1191f6135626b7..26036440cf8e9c 100644 --- a/src/system/SystemTimer.cpp +++ b/src/system/SystemTimer.cpp @@ -38,14 +38,19 @@ #include +namespace chip { +namespace System { + +#if CHIP_SYSTEM_CONFIG_NUM_TIMERS + /******************************************************************************* * Timer state * * There are two fundamental state-change variables: Object::mSystemLayer and - * Timer::OnComplete. These must be checked and changed atomically. The state + * Timer::mOnComplete. These must be checked and changed atomically. The state * of the timer is governed by the following state machine: * - * INITIAL STATE: mSystemLayer == NULL, OnComplete == NULL + * INITIAL STATE: mSystemLayer == NULL, mOnComplete == NULL * | * V * UNALLOCATED<-----------------------------+ @@ -56,237 +61,55 @@ * ALLOCATED-------(set mSystemLayer NULL)--+ * | \-----------------------------+ * | | - * (set OnComplete != NULL) | + * (set mOnComplete != NULL) | * | | * V | - * ARMED ---------( clear OnComplete )--+ + * ARMED ---------( clear mOnComplete )--+ * * When in the ARMED state: * * * None of the member variables may mutate. - * * OnComplete must only be cleared by Cancel() or HandleComplete() + * * mOnComplete must only be cleared by Cancel() or HandleComplete() * * Cancel() and HandleComplete() will test that they are the one to - * successfully set OnComplete NULL. And if so, that will be the + * successfully set mOnComplete NULL. And if so, that will be the * thread that must call Object::Release(). * ******************************************************************************* */ -namespace chip { -namespace System { - ObjectPool Timer::sPool; -/** - * Compares two Clock::MonotonicMilliseconds values and returns true if the first value is earlier than the second value. - * - * @brief - * A static API that gets called to compare 2 time values. This API attempts to account for timer wrap by assuming that the - * difference between the 2 input values will only be more than half the timestamp scalar range if a timer wrap has occurred - * between the 2 samples. - * - * @note - * This implementation assumes that Clock::MonotonicMilliseconds is an unsigned scalar type. - * - * @return true if the first param is earlier than the second, false otherwise. - */ -bool Timer::IsEarlier(const Clock::MonotonicMilliseconds & inFirst, const Clock::MonotonicMilliseconds & inSecond) -{ - static const Clock::MonotonicMilliseconds kMaxTime_2 = static_cast( - (static_cast(0) - static_cast(1)) / 2); - - // account for timer wrap with the assumption that no two input times will "naturally" - // be more than half the timer range apart. - return (((inFirst < inSecond) && (inSecond - inFirst < kMaxTime_2)) || - ((inFirst > inSecond) && (inFirst - inSecond > kMaxTime_2))); -} - -/** - * This method registers an one-shot timer with the underlying timer mechanism provided by the platform. - * - * @param[in] aDelayMilliseconds The number of milliseconds before this timer fires - * @param[in] aOnComplete A pointer to the callback function when this timer fires - * @param[in] aAppState An arbitrary pointer to be passed into onComplete when this timer fires - * - * @retval #CHIP_NO_ERROR Unconditionally. - * - */ -CHIP_ERROR Timer::Start(uint32_t aDelayMilliseconds, OnCompleteFunct aOnComplete, void * aAppState) +Timer * Timer::New(System::Layer & systemLayer, uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * appState) { - Layer & lLayer = this->SystemLayer(); - - CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_TimeoutImmediate, aDelayMilliseconds = 0); - - this->AppState = aAppState; - this->mAwakenTime = Clock::GetMonotonicMilliseconds() + static_cast(aDelayMilliseconds); - if (!__sync_bool_compare_and_swap(&this->OnComplete, nullptr, aOnComplete)) + Timer * timer = Timer::sPool.TryCreate(systemLayer); + if (timer == nullptr) { - chipDie(); - } - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - // add to the sorted list of timers. Earliest timer appears first. - if (lLayer.mTimerList == NULL || this->IsEarlier(this->mAwakenTime, lLayer.mTimerList->mAwakenTime)) - { - this->mNextTimer = lLayer.mTimerList; - lLayer.mTimerList = this; - - // this is the new earliest timer and so the timer needs (re-)starting provided that - // the system is not currently processing expired timers, in which case it is left to - // HandleExpiredTimers() to re-start the timer. - if (!lLayer.mTimerComplete) - { - lLayer.StartPlatformTimer(aDelayMilliseconds); - } + ChipLogError(chipSystemLayer, "Timer pool EMPTY"); } else { - Timer * lTimer = lLayer.mTimerList; - - while (lTimer->mNextTimer) - { - if (this->IsEarlier(this->mAwakenTime, lTimer->mNextTimer->mAwakenTime)) - { - // found the insert location. - break; - } - - lTimer = lTimer->mNextTimer; - } - - this->mNextTimer = lTimer->mNextTimer; - lTimer->mNextTimer = this; - } - return CHIP_NO_ERROR; -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t dispatchQueue = lLayer.GetDispatchQueue(); - if (dispatchQueue) - { - dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatchQueue); - if (timerSource == nullptr) + timer->AppState = appState; + timer->mAwakenTime = Clock::GetMonotonicMilliseconds() + static_cast(delayMilliseconds); + if (!__sync_bool_compare_and_swap(&timer->mOnComplete, nullptr, onComplete)) { chipDie(); } - - mTimerSource = timerSource; - dispatch_source_set_timer(timerSource, dispatch_walltime(NULL, aDelayMilliseconds * NSEC_PER_MSEC), 0, 100 * NSEC_PER_MSEC); - dispatch_source_set_event_handler(timerSource, ^{ - dispatch_source_cancel(timerSource); - dispatch_release(timerSource); - - this->HandleComplete(); - }); - dispatch_resume(timerSource); - return CHIP_NO_ERROR; } -#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK - lLayer.WatchableEvents().Signal(); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK - - return CHIP_NO_ERROR; + return timer; } -CHIP_ERROR Timer::ScheduleWork(OnCompleteFunct aOnComplete, void * aAppState) +void Timer::Clear() { - CHIP_ERROR err = CHIP_NO_ERROR; - Layer & lLayer = this->SystemLayer(); - - this->AppState = aAppState; - this->mAwakenTime = Clock::GetMonotonicMilliseconds(); - if (!__sync_bool_compare_and_swap(&this->OnComplete, nullptr, aOnComplete)) - { - chipDie(); - } - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - err = lLayer.PostEvent(*this, chip::System::kEvent_ScheduleWork, 0); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t dispatchQueue = lLayer.GetDispatchQueue(); - if (dispatchQueue) - { - dispatch_async(dispatchQueue, ^{ - this->HandleComplete(); - }); - } - else - { -#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH - lLayer.WatchableEvents().Signal(); -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - } -#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK - - return err; -} - -/** - * This method de-initializes the timer object, and prevents this timer from firing if it hasn't done so. - * - * @retval #CHIP_NO_ERROR Unconditionally. - */ -CHIP_ERROR Timer::Cancel() -{ -#if CHIP_SYSTEM_CONFIG_USE_LWIP - Layer & lLayer = this->SystemLayer(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - OnCompleteFunct lOnComplete = this->OnComplete; + Timers::OnCompleteFunct lOnComplete = this->mOnComplete; // Check if the timer is armed - VerifyOrExit(lOnComplete != nullptr, ); - // Atomically disarm if the value has not changed - VerifyOrExit(__sync_bool_compare_and_swap(&this->OnComplete, lOnComplete, nullptr), ); + VerifyOrReturn(lOnComplete != nullptr); - // Since this thread changed the state of OnComplete, release the timer. - this->AppState = nullptr; - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - if (lLayer.mTimerList) - { - if (this == lLayer.mTimerList) - { - lLayer.mTimerList = this->mNextTimer; - } - else - { - Timer * lTimer = lLayer.mTimerList; - - while (lTimer->mNextTimer) - { - if (this == lTimer->mNextTimer) - { - lTimer->mNextTimer = this->mNextTimer; - break; - } - - lTimer = lTimer->mNextTimer; - } - } - - this->mNextTimer = NULL; - } -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - if (mTimerSource != nullptr) - { - dispatch_source_cancel(mTimerSource); - dispatch_release(mTimerSource); - } -#endif + // Atomically disarm if the value has not changed + VerifyOrReturn(__sync_bool_compare_and_swap(&mOnComplete, lOnComplete, nullptr)); - this->Release(); -exit: - return CHIP_NO_ERROR; + // Since this thread changed the state of mOnComplete, release the timer. + AppState = nullptr; } /** @@ -296,96 +119,145 @@ void Timer::HandleComplete() { // Save information needed to perform the callback. Layer & lLayer = this->SystemLayer(); - const OnCompleteFunct lOnComplete = this->OnComplete; + const Timers::OnCompleteFunct lOnComplete = this->mOnComplete; void * lAppState = this->AppState; // Check if timer is armed - VerifyOrExit(lOnComplete != nullptr, ); + VerifyOrReturn(lOnComplete != nullptr, ); // Atomically disarm if the value has not changed. - VerifyOrExit(__sync_bool_compare_and_swap(&this->OnComplete, lOnComplete, nullptr), ); + VerifyOrReturn(__sync_bool_compare_and_swap(&this->mOnComplete, lOnComplete, nullptr), ); - // Since this thread changed the state of OnComplete, release the timer. + // Since this thread changed the state of mOnComplete, release the timer. AppState = nullptr; this->Release(); // Invoke the app's callback, if it's still valid. if (lOnComplete != nullptr) lOnComplete(&lLayer, lAppState, CHIP_NO_ERROR); +} -exit: - return; +CHIP_ERROR Timer::List::Init() +{ + mHead = nullptr; +#if CHIP_SYSTEM_CONFIG_NO_LOCKING + return CHIP_NO_ERROR; +#else // CHIP_SYSTEM_CONFIG_NO_LOCKING + return Mutex::Init(mMutex); +#endif // CHIP_SYSTEM_CONFIG_NO_LOCKING } -#if CHIP_SYSTEM_CONFIG_USE_LWIP -/** - * Completes any timers that have expired. - * - * @brief - * A static API that gets called when the platform timer expires. Any expired timers are completed and removed from the list - * of active timers in the layer object. If unexpired timers remain on completion, StartPlatformTimer will be called to - * restart the platform timer. - * - * @note - * It's harmless if this API gets called and there are no expired timers. - * - * @return CHIP_NO_ERROR on success, error code otherwise. - * - */ -CHIP_ERROR Timer::HandleExpiredTimers(Layer & aLayer) +Timer * Timer::List::Add(Timer * add) +{ + ScopedMutexLock lock(mMutex); + + ChipLogProgress(chipSystemLayer, "Add timer %p to list %p", add, mHead); + VerifyOrDie(add != mHead); + if (mHead == NULL || Clock::IsEarlier(add->mAwakenTime, mHead->mAwakenTime)) + { + add->mNextTimer = mHead; + mHead = add; + } + else + { + Timer * lTimer = mHead; + while (lTimer->mNextTimer) + { + VerifyOrDie(lTimer->mNextTimer != add); + if (Clock::IsEarlier(add->mAwakenTime, lTimer->mNextTimer->mAwakenTime)) + { + // found the insert location. + break; + } + lTimer = lTimer->mNextTimer; + } + add->mNextTimer = lTimer->mNextTimer; + lTimer->mNextTimer = add; + } + return mHead; +} + +Timer * Timer::List::Remove(Timer * remove) { - size_t timersHandled = 0; + ScopedMutexLock lock(mMutex); - // Expire each timer in turn until an unexpired timer is reached or the timerlist is emptied. We set the current expiration - // time outside the loop; that way timers set after the current tick will not be executed within this expiration window - // regardless how long the processing of the currently expired timers took - Clock::MonotonicMilliseconds currentTime = Clock::GetMonotonicMilliseconds(); + VerifyOrDie(mHead != nullptr); - while (aLayer.mTimerList) + if (remove == mHead) + { + mHead = remove->mNextTimer; + } + else { - // limit the number of timers handled before the control is returned to the event queue. The bound is similar to - // (though not exactly same) as that on the sockets-based systems. + Timer * lTimer = mHead; - // The platform timer API has MSEC resolution so expire any timer with less than 1 msec remaining. - if ((timersHandled < Timer::sPool.Size()) && Timer::IsEarlier(aLayer.mTimerList->mAwakenTime, currentTime + 1)) + while (lTimer->mNextTimer) { - Timer & lTimer = *aLayer.mTimerList; - aLayer.mTimerList = lTimer.mNextTimer; - lTimer.mNextTimer = NULL; - - aLayer.mTimerComplete = true; - lTimer.HandleComplete(); - aLayer.mTimerComplete = false; + if (remove == lTimer->mNextTimer) + { + lTimer->mNextTimer = remove->mNextTimer; + break; + } - timersHandled++; + lTimer = lTimer->mNextTimer; } - else - { - // timers still exist so restart the platform timer. - uint64_t delayMilliseconds = 0ULL; + } - currentTime = Clock::GetMonotonicMilliseconds(); + remove->mNextTimer = nullptr; + return mHead; +} - // the next timer expires in the future, so set the delayMilliseconds to a non-zero value - if (currentTime < aLayer.mTimerList->mAwakenTime) +Timer * Timer::List::Remove(Timers::OnCompleteFunct aOnComplete, void * aAppState) +{ + ScopedMutexLock lock(mMutex); + + Timer *previous = nullptr; + for (Timer * timer = mHead; timer != nullptr; timer = timer->mNextTimer) + { + if (timer->mOnComplete == aOnComplete && timer->AppState == aAppState) + { + if (previous == nullptr) { - delayMilliseconds = aLayer.mTimerList->mAwakenTime - currentTime; + mHead = timer->mNextTimer; } - /* - * StartPlatformTimer() accepts a 32bit value in milliseconds. Timestamps are 64bit numbers. The only way in which this - * could overflow is if time went backwards (e.g. as a result of a time adjustment from time synchronization). Verify - * that the timer can still be executed (even if it is very late) and exit if that is the case. Note: if the time sync - * ever ends up adjusting the clock, we should implement a method that deals with all the timers in the system. - */ - VerifyOrDie(delayMilliseconds <= UINT32_MAX); - - aLayer.StartPlatformTimer(static_cast(delayMilliseconds)); - break; // all remaining timers are still ticking. + else + { + previous->mNextTimer = timer->mNextTimer; + } + timer->mNextTimer = nullptr; + return timer; } + previous = timer; } + return nullptr; +} - return CHIP_NO_ERROR; +Timer * Timer::List::PopEarliest() +{ + ScopedMutexLock lock(mMutex); + + if (mHead == nullptr) { + return nullptr; + } + Timer *earliest = mHead; + mHead = mHead->mNextTimer; + earliest->mNextTimer = nullptr; + return earliest; +} + +Timer * Timer::List::PopIfEarlier(Clock::MonotonicMilliseconds t) +{ + ScopedMutexLock lock(mMutex); + + if ((mHead == nullptr) || !Clock::IsEarlier(mHead->mAwakenTime, t)) { + return nullptr; + } + Timer *earliest = mHead; + mHead = mHead->mNextTimer; + earliest->mNextTimer = nullptr; + return earliest; } -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP + +#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS } // namespace System } // namespace chip diff --git a/src/system/SystemTimer.h b/src/system/SystemTimer.h index 044c4efc10da04..7cf274eaf239cf 100644 --- a/src/system/SystemTimer.h +++ b/src/system/SystemTimer.h @@ -21,6 +21,8 @@ * This file defines the chip::System::Timer class and its * related types used for representing an in-progress one-shot * timer. + * + * Some platforms use this to implement System::Layer timer events. */ #pragma once @@ -33,6 +35,7 @@ #include #include +#include #include #include @@ -43,47 +46,60 @@ namespace chip { namespace System { -class Layer; +namespace Timers { + +typedef void (*OnCompleteFunct)(Layer * aLayer, void * aAppState, CHIP_ERROR aError); + +} // namespace Timers + +#if CHIP_SYSTEM_CONFIG_NUM_TIMERS /** - * @class Timer - * - * @brief - * This is an internal class to CHIP System Layer, used to represent an in-progress one-shot timer. There is no real public - * interface available for the application layer. The static public methods used to acquire current system time are intended for - * internal use. - * + * This is an Object-pool based class that System::Layer implementations can use to assist in providing timer functions. */ class DLL_EXPORT Timer : public Object { - friend class Layer; - public: - static bool IsEarlier(const Clock::MonotonicMilliseconds & first, const Clock::MonotonicMilliseconds & second); - - typedef void (*OnCompleteFunct)(Layer * aLayer, void * aAppState, CHIP_ERROR aError); - OnCompleteFunct OnComplete; - - CHIP_ERROR Start(uint32_t aDelayMilliseconds, OnCompleteFunct aOnComplete, void * aAppState); - CHIP_ERROR Cancel(); - - static void GetStatistics(chip::System::Stats::count_t & aNumInUse, chip::System::Stats::count_t & aHighWatermark); + class List + { + public: + List() : mHead(nullptr) {} + CHIP_ERROR Init(); + bool Empty() const { return mHead == nullptr; } + Timer * Add(Timer * add); + Timer * Remove(Timer * remove); + Timer * Remove(Timers::OnCompleteFunct aOnComplete, void * aAppState); + Timer * PopEarliest(); + Timer * PopIfEarlier(Clock::MonotonicMilliseconds t); + Timer * Earliest() const { return mHead; } + + private: + Mutex mMutex; + Timer * mHead; + List(const List &) = delete; + List & operator=(const List &) = delete; + }; + + static Timer * New(System::Layer & systemLayer, uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, + void * appState); + void Clear(); + + static void GetStatistics(chip::System::Stats::count_t & aNumInUse, chip::System::Stats::count_t & aHighWatermark) + { + sPool.GetStatistics(aNumInUse, aHighWatermark); + } private: - static ObjectPool sPool; + friend class WatchableEventManager; - Clock::MonotonicMilliseconds mAwakenTime; + static ObjectPool sPool; void HandleComplete(); - CHIP_ERROR ScheduleWork(OnCompleteFunct aOnComplete, void * aAppState); - -#if CHIP_SYSTEM_CONFIG_USE_LWIP + Timers::OnCompleteFunct mOnComplete; + Clock::MonotonicMilliseconds mAwakenTime; Timer * mNextTimer; - static CHIP_ERROR HandleExpiredTimers(Layer & aLayer); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - #if CHIP_SYSTEM_CONFIG_USE_DISPATCH dispatch_source_t mTimerSource = nullptr; #endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH @@ -93,10 +109,7 @@ class DLL_EXPORT Timer : public Object Timer & operator=(const Timer &) = delete; }; -inline void Timer::GetStatistics(chip::System::Stats::count_t & aNumInUse, chip::System::Stats::count_t & aHighWatermark) -{ - sPool.GetStatistics(aNumInUse, aHighWatermark); -} +#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS } // namespace System } // namespace chip diff --git a/src/system/WatchableEventManager.h b/src/system/WatchableEventManager.h index 0ab91ce77cdfd2..6e286a5d5a406a 100644 --- a/src/system/WatchableEventManager.h +++ b/src/system/WatchableEventManager.h @@ -25,8 +25,6 @@ // Include configuration headers #include -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - namespace chip { namespace System { @@ -36,16 +34,94 @@ class Layer; /** * @class WatchableEventManager * - * An instance of this type is contained in System::Layer. Its purpose is to hold socket-event system state - * or methods available to every associated instance of WatchableSocket. + * An instance of this type is contained in System::Layer, to provide an implementation of event handling. + */ +class WatchableEventManager; + +/** + * @fn CHIP_ERROR WatchableEventManager::Init(System::Layer & systemLayer) + * + * Initialize the WatchableEventManager. Called from System::Layer::Init(). + */ + +/** + * @fn CHIP_ERROR WatchableEventManager::Shutdown() + * + * Shut down the WatchableEventManager. Called from System::Layer::Shutdown() + */ + +/** + * @fn void WatchableEventManager::Signal() + * + * Called to indicate that event monitoring may need to be refreshed or resumed. + */ + +/** + * @fn CHIP_ERROR WatchableEventManager::WeStartTimer(uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * + * appState) + * + * This method starts a one-shot timer. * - * It MUST provide at least three methods: + * Only a single timer is allowed to be started with the same @a onComplete and @a appState + * arguments. If called with @a onComplete and @a appState identical to an existing timer, + * the currently-running timer will first be cancelled. * - * - CHIP_ERROR Init(System::Layer & systemLayer) -- called from System::Layer::Init() - * - CHIP_ERROR Shutdown() -- called from System::Layer::Shutdown() - * - void Signal() -- called to indicate that event monitoring may need to be refreshed or resumed. + * @param[in] delayMilliseconds Expiration time in milliseconds. + * @param[in] onComplete A pointer to the function called when timer expires. + * @param[in] appState A pointer to the application state object used when timer expires. * - * Other contents depend on the contract between socket-event implementation and platform layer implementation. + * @return CHIP_NO_ERROR On success. + * @return CHIP_ERROR_NO_MEMORY If a timer cannot be allocated. + * @return Other value indicating timer failed to start. + */ + +/** + * @fn void WatchableEventManager::WeCancelTimer(Timers::OnCompleteFunct onComplete, void * appState) + * + * This method cancels a one-shot timer, started earlier through @p StartTimer(). + * + * The cancellation could fail silently in two different ways. If the timer specified by the combination of the callback + * function and application state object couldn't be found, cancellation could fail. If the timer has fired, but not yet + * removed from memory, cancellation could also fail. + * + * @param[in] onComplete A pointer to the callback function used in calling @p StartTimer(). + * @param[in] appState A pointer to the application state object used in calling @p StartTimer(). + */ + +/** + * @fn CHIP_ERROR WatchableEventManager::WeScheduleWork(Timers::OnCompleteFunct onComplete, void * appState) + * + * Schedules a function to be run as soon as possible on the CHIP thread. + * + * @note + * This function could, in principle, be implemented as + * `StartTimer`. The specification for + * `SystemTimer` however permits certain optimizations that might + * make that implementation impossible. Specifically, `SystemTimer` + * API may only be called from the thread owning the particular + * `SystemLayer`, whereas the `ScheduleWork` may be called from + * any thread. Additionally, whereas the `SystemTimer` API permits + * the invocation of the already expired handler in line, + * `ScheduleWork` guarantees that the handler function will be + * called only after the current CHIP event completes. + * + * @param[in] onComplete A pointer to a callback function to be called + * when this timer fires. + * + * @param[in] appState A pointer to an application state object to be + * passed to the callback function as argument. + * + * @retval CHIP_ERROR_INCORRECT_STATE If the SystemLayer has + * not been initialized. + * + * @retval CHIP_ERROR_NO_MEMORY If the SystemLayer cannot + * allocate a new timer. + * + * @retval CHIP_NO_ERROR On success. + */ + +/* + * Other contents depend on the contract between event implementation and platform layer implementation. * For POSIX-like platforms, WatchableEventManager provides a set of functions called from the event loop: * * - void EventLoopBegins() -- Called before the first iterations of the event loop. @@ -56,7 +132,6 @@ class Layer; * - void HandleEvents() -- Called at the end of each iteration of the event loop. * - void EventLoopEnds() -- Called after the last iteration of the event loop. */ -class WatchableEventManager; } // namespace System } // namespace chip @@ -68,5 +143,3 @@ class WatchableEventManager; #include #endif // CHIP_SYSTEM_WATCHABLE_EVENT_MANAGER_CONFIG_FILE #undef INCLUDING_CHIP_SYSTEM_WATCHABLE_EVENT_MANAGER_CONFIG_FILE - -#endif // CHIP_SYSTEM_CONFIG_USE_EVENT_MANAGERS diff --git a/src/system/WatchableEventManagerLibevent.cpp b/src/system/WatchableEventManagerLibevent.cpp index 141b95f4f2423d..f2fb9a13a37397 100644 --- a/src/system/WatchableEventManagerLibevent.cpp +++ b/src/system/WatchableEventManagerLibevent.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -38,9 +39,14 @@ void HandleMdnsTimeout(); #endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ #ifndef CHIP_CONFIG_LIBEVENT_DEBUG_CHECKS -#define CHIP_CONFIG_LIBEVENT_DEBUG_CHECKS 1 // TODO(#5556): default to off +#define CHIP_CONFIG_LIBEVENT_DEBUG_CHECKS 1 #endif +// Choose an approximation of PTHREAD_NULL if pthread.h doesn't define one. +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING && !defined(PTHREAD_NULL) +#define PTHREAD_NULL 0 +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING && !defined(PTHREAD_NULL) + namespace chip { namespace System { @@ -55,14 +61,14 @@ System::SocketEvents SocketEventsFromLibeventFlags(short eventFlags) void TimeoutCallbackHandler(evutil_socket_t fd, short eventFlags, void * data) { - event * const ev = reinterpret_cast(data); - evtimer_del(ev); } } // anonymous namespace CHIP_ERROR WatchableEventManager::Init(System::Layer & systemLayer) { + RegisterPOSIXErrorFormatter(); + #if CHIP_CONFIG_LIBEVENT_DEBUG_CHECKS static bool enabled_event_debug_mode = false; if (!enabled_event_debug_mode) @@ -74,9 +80,15 @@ CHIP_ERROR WatchableEventManager::Init(System::Layer & systemLayer) mEventBase = event_base_new(); mTimeoutEvent = evtimer_new(mEventBase, TimeoutCallbackHandler, event_self_cbarg()); +ChipLogError(chipSystemLayer, "XXX Init mTimeoutEvent←%p", mTimeoutEvent); mActiveSockets = nullptr; mSystemLayer = &systemLayer; - return CHIP_NO_ERROR; + +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + mHandleSelectThread = PTHREAD_NULL; +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING + + return mTimerList.Init(); } void WatchableEventManager::PrepareEvents() @@ -88,8 +100,22 @@ void WatchableEventManager::PrepareEvents() void WatchableEventManager::PrepareEventsWithTimeout(struct timeval & nextTimeout) { - // TODO(#5556): Integrate timer platform details with WatchableEventManager. - mSystemLayer->GetTimeout(nextTimeout); + const Clock::MonotonicMilliseconds currentTime = Clock::GetMonotonicMilliseconds(); + Clock::MonotonicMilliseconds awakenTime = currentTime + TimevalToMilliseconds(nextTimeout); + + Timer * timer = mTimerList.Earliest(); + if (timer && Clock::IsEarlier(timer->mAwakenTime, awakenTime)) + { + awakenTime = timer->mAwakenTime; + } + + const Clock::MonotonicMilliseconds sleepTime = (awakenTime > currentTime) ? (awakenTime - currentTime) : 0; + MillisecondsToTimeval(sleepTime, nextTimeout); + +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ && !__MBED__ + chip::Mdns::GetMdnsTimeout(nextTimeout); +#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ + if (nextTimeout.tv_sec || nextTimeout.tv_usec) { evtimer_add(mTimeoutEvent, &nextTimeout); @@ -104,7 +130,16 @@ void WatchableEventManager::WaitForEvents() void WatchableEventManager::HandleEvents() { - mSystemLayer->HandleTimeout(); +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + mHandleSelectThread = pthread_self(); +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING + + const Clock::MonotonicMilliseconds timeout = 1 + Clock::GetMonotonicMilliseconds(); + Timer *timer = nullptr; + while ((timer = mTimerList.PopIfEarlier(timeout)) != nullptr) + { + timer->HandleComplete(); + } #if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ chip::Mdns::HandleMdnsTimeout(); @@ -116,6 +151,10 @@ void WatchableEventManager::HandleEvents() mActiveSockets = watcher->mActiveNext; watcher->InvokeCallback(); } + +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + mHandleSelectThread = PTHREAD_NULL; +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING } CHIP_ERROR WatchableEventManager::Shutdown() @@ -125,6 +164,15 @@ CHIP_ERROR WatchableEventManager::Shutdown() mTimeoutEvent = nullptr; event_base_free(mEventBase); mEventBase = nullptr; + + Timer * timer; + while ((timer = mTimerList.PopEarliest()) != nullptr) + { + timer->Clear(); + timer->Release(); + } + + mSystemLayer = nullptr; return CHIP_NO_ERROR; } @@ -133,14 +181,14 @@ void WatchableEventManager::Signal() /* * Wake up the I/O thread by writing a single byte to the wake pipe. * - * If p WakeIOThread() is being called from within an I/O event callback, then writing to the wake pipe can be skipped, + * If this is being called from within an I/O event callback, then writing to the wake pipe can be skipped, * since the I/O thread is already awake. * * Furthermore, we don't care if this write fails as the only reasonably likely failure is that the pipe is full, in which * case the select calling thread is going to wake up anyway. */ #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING - if (pthread_equal(mSystemLayer->mHandleSelectThread, pthread_self())) + if (pthread_equal(mHandleSelectThread, pthread_self())) { return; } @@ -154,6 +202,35 @@ void WatchableEventManager::Signal() } } +CHIP_ERROR WatchableEventManager::WeStartTimer(uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * appState) +{ + // Note: the libevent implementation currently uses a single libevent timer, playing the same role as the select() timeout. + // A more ‘native' implementation would have Timer contain a libevent timer and callback data for each CHIP timer. + CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_TimeoutImmediate, delayMilliseconds = 0); + + WeCancelTimer(onComplete, appState); + + Timer * timer = Timer::New(*mSystemLayer, delayMilliseconds, onComplete, appState); + VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY); + + if (mTimerList.Add(timer) == timer) + { + // The new timer is the earliest, so the time until the next event has probably changed. + Signal(); + } + return CHIP_NO_ERROR; +} + +void WatchableEventManager::WeCancelTimer(Timers::OnCompleteFunct onComplete, void * appState) +{ + Timer * timer = mTimerList.Remove(onComplete, appState); + VerifyOrReturn(timer != nullptr); + + timer->Clear(); + timer->Release(); + Signal(); +} + // static void WatchableEventManager::LibeventCallbackHandler(evutil_socket_t fd, short eventFlags, void * data) { diff --git a/src/system/WatchableEventManagerLibevent.h b/src/system/WatchableEventManagerLibevent.h index 5bbab07a131b33..c6c8b9cddbe30f 100644 --- a/src/system/WatchableEventManagerLibevent.h +++ b/src/system/WatchableEventManagerLibevent.h @@ -27,8 +27,15 @@ #include #endif // !INCLUDING_CHIP_SYSTEM_WATCHABLE_EVENT_MANAGER_CONFIG_FILE +#include + #include +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING +#include +#include +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING + namespace chip { namespace System { @@ -37,10 +44,17 @@ class WatchableEventManager { public: WatchableEventManager() : mActiveSockets(nullptr), mSystemLayer(nullptr), mEventBase(nullptr), mTimeoutEvent(nullptr) {} + + // Core ‘overrides’. CHIP_ERROR Init(Layer & systemLayer); CHIP_ERROR Shutdown(); void Signal(); + // Timer ‘overrides’. + CHIP_ERROR WeStartTimer(uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * appState); + void WeCancelTimer(Timers::OnCompleteFunct onComplete, void * appState); + CHIP_ERROR WeScheduleWork(Timers::OnCompleteFunct onComplete, void * appState) { return WeStartTimer(0, onComplete, appState); } + void EventLoopBegins() {} void PrepareEvents(); void WaitForEvents(); @@ -60,13 +74,19 @@ class WatchableEventManager friend class WatchableSocket; static void LibeventCallbackHandler(evutil_socket_t fd, short eventFlags, void * data); void RemoveFromQueueIfPresent(WatchableSocket * watcher); + WatchableSocket * mActiveSockets; ///< List of sockets activated by libevent. Layer * mSystemLayer; event_base * mEventBase; ///< libevent shared state. event * mTimeoutEvent; + Timer::List mTimerList; WakeEvent mWakeEvent; + +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + std::atomic mHandleSelectThread; +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING }; } // namespace System diff --git a/src/system/WatchableEventManagerLwIP.cpp b/src/system/WatchableEventManagerLwIP.cpp new file mode 100644 index 00000000000000..072e8f048a501c --- /dev/null +++ b/src/system/WatchableEventManagerLwIP.cpp @@ -0,0 +1,341 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2014-2017 Nest Labs, Inc. + * + * 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. + */ + +/** + * @file + * This file implements WatchableEventManager using LwIP. + */ + +#include +#include +#include +#include + +namespace chip { +namespace System { + +LayerLwIPEventHandlerDelegate WatchableEventManager::sSystemEventHandlerDelegate; + +WatchableEventManager::WatchableEventManager() : mHandlingTimerComplete(false), mEventDelegateList(nullptr) +{ + if (!sSystemEventHandlerDelegate.IsInitialized()) + sSystemEventHandlerDelegate.Init(LayerLwIPHandleSystemLayerEvent); +} + +CHIP_ERROR WatchableEventManager::Init(Layer & systemLayer) +{ + RegisterLwIPErrorFormatter(); + + mSystemLayer = &systemLayer; + AddEventHandlerDelegate(sSystemEventHandlerDelegate); + return mTimerList.Init(); +} + +CHIP_ERROR WatchableEventManager::Shutdown() +{ + mSystemLayer = nullptr; + return CHIP_NO_ERROR; +} + +void WatchableEventManager::Signal() +{ +} + +CHIP_ERROR WatchableEventManager::WeStartTimer(uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * appState) +{ + CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_TimeoutImmediate, delayMilliseconds = 0); + + WeCancelTimer(onComplete, appState); + + Timer * timer = Timer::New(*mSystemLayer, delayMilliseconds, onComplete, appState); + VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY); + + if (mTimerList.Add(timer) == timer) + { + // this is the new earliest timer and so the timer needs (re-)starting provided that + // the system is not currently processing expired timers, in which case it is left to + // TimerLwIPHandleExpiredTimers() to re-start the timer. + if (!mHandlingTimerComplete) + { + LayerLwIPStartPlatformTimer(delayMilliseconds); + } + } + return CHIP_NO_ERROR; +} + +void WatchableEventManager::WeCancelTimer(Timers::OnCompleteFunct onComplete, void * appState) +{ + Timer * timer = mTimerList.Remove(onComplete, appState); + VerifyOrReturn(timer != nullptr); + + timer->Clear(); + timer->Release(); +} + +CHIP_ERROR WatchableEventManager::WeScheduleWork(Timers::OnCompleteFunct onComplete, void * appState) +{ + Timer * timer = Timer::New(*mSystemLayer, 0, onComplete, appState); + VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY); + + return LayerLwIPPostEvent(*timer, chip::System::kEvent_ScheduleWork, 0); +} + +bool LayerLwIPEventHandlerDelegate::IsInitialized() const +{ + return mFunction != nullptr; +} + +void LayerLwIPEventHandlerDelegate::Init(LayerLwIPEventHandlerFunction aFunction) +{ + mFunction = aFunction; + mNextDelegate = nullptr; +} + +void LayerLwIPEventHandlerDelegate::Prepend(const LayerLwIPEventHandlerDelegate *& aDelegateList) +{ + mNextDelegate = aDelegateList; + aDelegateList = this; +} + +/** + * This is the dispatch handler for system layer events. + * + * @param[in,out] aTarget A pointer to the CHIP System Layer object making the post request. + * @param[in] aEventType The type of event to post. + * @param[in,out] aArgument The argument associated with the event to post. + */ +CHIP_ERROR WatchableEventManager::LayerLwIPHandleSystemLayerEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) +{ + // Dispatch logic specific to the event type + switch (aEventType) + { + case kEvent_ReleaseObj: + aTarget.Release(); + return CHIP_NO_ERROR; + + case kEvent_ScheduleWork: + static_cast(aTarget).HandleComplete(); + return CHIP_NO_ERROR; + + default: + return CHIP_ERROR_UNEXPECTED_EVENT; + } +} + +/** + * This adds an event handler delegate to the system layer to extend its ability to handle LwIP events. + * + * @param[in] aDelegate An uninitialied LwIP event handler delegate structure + * + * @retval CHIP_NO_ERROR On success. + * @retval CHIP_ERROR_INVALID_ARGUMENT If the function pointer contained in aDelegate is NULL + */ +CHIP_ERROR WatchableEventManager::AddEventHandlerDelegate(LayerLwIPEventHandlerDelegate & aDelegate) +{ + VerifyOrReturnError(aDelegate.mFunction != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + aDelegate.Prepend(mEventDelegateList); + return CHIP_NO_ERROR; +} + +/** + * This posts an event / message of the specified type with the provided argument to this instance's platform-specific event + * queue. + * + * @param[in,out] aTarget A pointer to the CHIP System Layer object making the post request. + * @param[in] aEventType The type of event to post. + * @param[in,out] aArgument The argument associated with the event to post. + * + * @retval CHIP_NO_ERROR On success. + * @retval CHIP_ERROR_INCORRECT_STATE If the state of the Layer object is incorrect. + * @retval CHIP_ERROR_NO_MEMORY If the event queue is already full. + * @retval other Platform-specific errors generated indicating the reason for failure. + */ +CHIP_ERROR WatchableEventManager::LayerLwIPPostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) +{ + VerifyOrReturnError(mSystemLayer->State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + + // Sanity check that this instance and the target layer haven't been "crossed". + VerifyOrDieWithMsg(aTarget.IsRetained(*mSystemLayer), chipSystemLayer, "wrong poster! [target %p != this %p]", &(aTarget.SystemLayer()), + mSystemLayer); + + CHIP_ERROR lReturn = PlatformEventing::EventingPostEvent(*mSystemLayer, aTarget, aEventType, aArgument); + if (lReturn != CHIP_NO_ERROR) + { + ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer event (type %d): %s", aEventType, ErrorStr(lReturn)); + } + return lReturn; +} + +/** + * This is a syntactic wrapper around a platform-specific hook that effects an event loop, waiting on a queue that services this + * instance, pulling events off of that queue, and then dispatching them for handling. + * + * @return #CHIP_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure. + */ +CHIP_ERROR WatchableEventManager::LayerLwIPDispatchEvents() +{ + VerifyOrReturnError(mSystemLayer->State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + return PlatformEventing::EventingDispatchEvents(*mSystemLayer); +} + +/** + * This dispatches the specified event for handling by this instance. + * + * The unmarshalling of the type and arguments from the event is handled by a platform-specific hook which should then call + * back to Layer::HandleEvent for the actual dispatch. + * + * @param[in] aEvent The platform-specific event object to dispatch for handling. + * + * @return CHIP_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure. + */ +CHIP_ERROR WatchableEventManager::LayerLwIPDispatchEvent(Event aEvent) +{ + VerifyOrReturnError(mSystemLayer->State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + return PlatformEventing::EventingDispatchEvent(*mSystemLayer, aEvent); +} + +/** + * This implements the actual dispatch and handling of a CHIP System Layer event. + * + * @param[in,out] aTarget A reference to the layer object to which the event is targeted. + * @param[in] aEventType The event / message type to handle. + * @param[in] aArgument The argument associated with the event / message. + * + * @retval CHIP_NO_ERROR On success. + * @retval CHIP_ERROR_INCORRECT_STATE If the state of the InetLayer object is incorrect. + * @retval CHIP_ERROR_UNEXPECTED_EVENT If the event type is unrecognized. + */ +CHIP_ERROR WatchableEventManager::LayerLwIPHandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) +{ + VerifyOrReturnError(mSystemLayer->State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + + // Sanity check that this instance and the target layer haven't been "crossed". + VerifyOrDieWithMsg(aTarget.IsRetained(*mSystemLayer), chipSystemLayer, "wrong handler! [target %p != this %p]", + &(aTarget.SystemLayer()), mSystemLayer); + + // Prevent the target object from being freed while dispatching the event. + aTarget.Retain(); + + CHIP_ERROR lReturn = CHIP_ERROR_UNEXPECTED_EVENT; + const LayerLwIPEventHandlerDelegate * lEventDelegate = mEventDelegateList; + + while (lReturn == CHIP_ERROR_UNEXPECTED_EVENT && lEventDelegate != nullptr) + { + lReturn = lEventDelegate->mFunction(aTarget, aEventType, aArgument); + lEventDelegate = lEventDelegate->mNextDelegate; + } + + if (lReturn == CHIP_ERROR_UNEXPECTED_EVENT) + { + ChipLogError(chipSystemLayer, "Unexpected event type %d", aEventType); + } + + /* + Release the reference to the target object. When the object's lifetime finally comes to an end, in most cases this will be + the release call that decrements the ref count to zero. + */ + aTarget.Release(); + + return lReturn; +} + +/** + * Start the platform timer with specified millsecond duration. + * + * @brief + * Calls the Platform specific API to start a platform timer. This API is called by the chip::System::Timer class when + * one or more timers are active and require deferred execution. + * + * @param[in] aDelayMilliseconds The timer duration in milliseconds. + * + * @return CHIP_NO_ERROR on success, error code otherwise. + * + */ +CHIP_ERROR WatchableEventManager::LayerLwIPStartPlatformTimer(uint32_t aDelayMilliseconds) +{ + VerifyOrReturnError(mSystemLayer->State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + return PlatformEventing::EventingStartTimer(*mSystemLayer, aDelayMilliseconds); +} + +/** + * Handle the platform timer expiration event. Completes any timers that have expired. + * + * A static API that gets called when the platform timer expires. Any expired timers are completed and removed from the list + * of active timers in the layer object. If unexpired timers remain on completion, StartPlatformTimer will be called to + * restart the platform timer. + * + * It is assumed that this API is called only while on the thread which owns the CHIP System Layer object. + * + * @note + * It's harmless if this API gets called and there are no expired timers. + * + * @return CHIP_NO_ERROR on success, error code otherwise. + * + */ +CHIP_ERROR WatchableEventManager::LayerLwIPHandlePlatformTimer() +{ + VerifyOrReturnError(mSystemLayer->State() == kLayerState_Initialized, CHIP_ERROR_INCORRECT_STATE); + + // Expire each timer in turn until an unexpired timer is reached or the timerlist is emptied. We set the current expiration + // time outside the loop; that way timers set after the current tick will not be executed within this expiration window + // regardless how long the processing of the currently expired timers took + Clock::MonotonicMilliseconds currentTime = Clock::GetMonotonicMilliseconds(); + + // limit the number of timers handled before the control is returned to the event queue. The bound is similar to + // (though not exactly same) as that on the sockets-based systems. + + // The platform timer API has MSEC resolution so expire any timer with less than 1 msec remaining. + size_t timersHandled = 0; + Timer *timer = nullptr; + while ((timersHandled < Timer::sPool.Size()) && ((timer = mTimerList.PopIfEarlier(currentTime + 1)) != nullptr)) + { + mHandlingTimerComplete = true; + timer->HandleComplete(); + mHandlingTimerComplete = false; + + timersHandled++; + } + + if (!mTimerList.Empty()) + { + // timers still exist so restart the platform timer. + uint64_t delayMilliseconds = 0ULL; + + currentTime = Clock::GetMonotonicMilliseconds(); + + // the next timer expires in the future, so set the delayMilliseconds to a non-zero value + if (currentTime < mTimerList.Earliest()->mAwakenTime) + { + delayMilliseconds = mTimerList.Earliest()->mAwakenTime - currentTime; + } + /* + * StartPlatformTimer() accepts a 32bit value in milliseconds. Timestamps are 64bit numbers. The only way in which this + * could overflow is if time went backwards (e.g. as a result of a time adjustment from time synchronization). Verify + * that the timer can still be executed (even if it is very late) and exit if that is the case. Note: if the time sync + * ever ends up adjusting the clock, we should implement a method that deals with all the timers in the system. + */ + VerifyOrDie(delayMilliseconds <= UINT32_MAX); + + LayerLwIPStartPlatformTimer(static_cast(delayMilliseconds)); + } + + return CHIP_NO_ERROR; +} + +} // namespace System +} // namespace chip diff --git a/src/system/WatchableEventManagerLwIP.h b/src/system/WatchableEventManagerLwIP.h new file mode 100644 index 00000000000000..f50180b62474fe --- /dev/null +++ b/src/system/WatchableEventManagerLwIP.h @@ -0,0 +1,89 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * 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. + */ + +/** + * @file + * This file declares an implementation of WatchableEventManager using LwIP. + */ + +#pragma once + +#if !INCLUDING_CHIP_SYSTEM_WATCHABLE_EVENT_MANAGER_CONFIG_FILE +#error "This file should only be included from " +#include +#endif // !INCLUDING_CHIP_SYSTEM_WATCHABLE_EVENT_MANAGER_CONFIG_FILE + +namespace chip { +namespace System { + +class LayerLwIPEventHandlerDelegate +{ + friend class WatchableEventManager; + +public: + typedef CHIP_ERROR (*LayerLwIPEventHandlerFunction)(Object & aTarget, EventType aEventType, uintptr_t aArgument); + + bool IsInitialized(void) const; + void Init(LayerLwIPEventHandlerFunction aFunction); + void Prepend(const LayerLwIPEventHandlerDelegate *& aDelegateList); + +private: + LayerLwIPEventHandlerFunction mFunction; + const LayerLwIPEventHandlerDelegate * mNextDelegate; +}; + +class WatchableEventManager +{ +public: + // Core ‘overrides’. + WatchableEventManager(); + CHIP_ERROR Init(System::Layer & systemLayer); + CHIP_ERROR Shutdown(); + void Signal(); + + // Timer ‘overrides’. + CHIP_ERROR WeStartTimer(uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * appState); + void WeCancelTimer(Timers::OnCompleteFunct onComplete, void * appState); + CHIP_ERROR WeScheduleWork(Timers::OnCompleteFunct onComplete, void * appState); + + // Platform implementation. + // typedef CHIP_ERROR (*EventHandler)(Object & aTarget, EventType aEventType, uintptr_t aArgument); + CHIP_ERROR AddEventHandlerDelegate(LayerLwIPEventHandlerDelegate & aDelegate); + + CHIP_ERROR LayerLwIPPostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument); + CHIP_ERROR LayerLwIPDispatchEvents(void); + CHIP_ERROR LayerLwIPHandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument); + CHIP_ERROR LayerLwIPHandlePlatformTimer(void); + +private: + friend class PlatformEventing; + + static CHIP_ERROR LayerLwIPHandleSystemLayerEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument); + + CHIP_ERROR LayerLwIPDispatchEvent(Event aEvent); + CHIP_ERROR LayerLwIPStartPlatformTimer(uint32_t aDelayMilliseconds); + + static LayerLwIPEventHandlerDelegate sSystemEventHandlerDelegate; + + Layer * mSystemLayer = nullptr; + Timer::List mTimerList; + bool mHandlingTimerComplete; // true while handling any timer completion + const LayerLwIPEventHandlerDelegate * mEventDelegateList; +}; + +} // namespace System +} // namespace chip diff --git a/src/system/WatchableEventManagerSelect.cpp b/src/system/WatchableEventManagerSelect.cpp index a46fd956f7b7cc..8d1b5dd3504cd0 100644 --- a/src/system/WatchableEventManagerSelect.cpp +++ b/src/system/WatchableEventManagerSelect.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,11 @@ #define DEFAULT_MIN_SLEEP_PERIOD (60 * 60 * 24 * 30) // Month [sec] +// Choose an approximation of PTHREAD_NULL if pthread.h doesn't define one. +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING && !defined(PTHREAD_NULL) +#define PTHREAD_NULL 0 +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING && !defined(PTHREAD_NULL) + #if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ namespace chip { @@ -47,18 +53,32 @@ namespace System { CHIP_ERROR WatchableEventManager::Init(Layer & systemLayer) { + RegisterPOSIXErrorFormatter(); + mSystemLayer = &systemLayer; mMaxFd = -1; FD_ZERO(&mRequest.mReadSet); FD_ZERO(&mRequest.mWriteSet); FD_ZERO(&mRequest.mErrorSet); + ReturnErrorOnFailure(mTimerList.Init()); + +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + mHandleSelectThread = PTHREAD_NULL; +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING + // Create an event to allow an arbitrary thread to wake the thread in the select loop. return mWakeEvent.Open(*this); } CHIP_ERROR WatchableEventManager::Shutdown() { + Timer * timer; + while ((timer = mTimerList.PopEarliest()) != nullptr) + { + timer->Clear(); + timer->Release(); + } mWakeEvent.Close(); mSystemLayer = nullptr; return CHIP_NO_ERROR; @@ -69,14 +89,14 @@ void WatchableEventManager::Signal() /* * Wake up the I/O thread by writing a single byte to the wake pipe. * - * If p WakeIOThread() is being called from within an I/O event callback, then writing to the wake pipe can be skipped, + * If this is being called from within an I/O event callback, then writing to the wake pipe can be skipped, * since the I/O thread is already awake. * * Furthermore, we don't care if this write fails as the only reasonably likely failure is that the pipe is full, in which * case the select calling thread is going to wake up anyway. */ #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING - if (pthread_equal(mSystemLayer->mHandleSelectThread, pthread_self())) + if (pthread_equal(mHandleSelectThread, pthread_self())) { return; } @@ -90,6 +110,99 @@ void WatchableEventManager::Signal() } } +CHIP_ERROR WatchableEventManager::WeStartTimer(uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * appState) +{ + CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_TimeoutImmediate, delayMilliseconds = 0); + + WeCancelTimer(onComplete, appState); + + Timer * timer = Timer::New(*mSystemLayer, delayMilliseconds, onComplete, appState); + VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY); + +#if CHIP_SYSTEM_CONFIG_USE_DISPATCH + dispatch_queue_t dispatchQueue = GetDispatchQueue(); + if (dispatchQueue) + { + (void) mTimerList.Add(timer); + dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatchQueue); + ChipLogProgress(DeviceLayer, "XXX StartTimer using dispatch queue %p source %p", dispatchQueue, timerSource); + if (timerSource == nullptr) + { + chipDie(); + } + + timer->mTimerSource = timerSource; + dispatch_source_set_timer(timerSource, dispatch_walltime(NULL, delayMilliseconds * NSEC_PER_MSEC), 0, 100 * NSEC_PER_MSEC); + dispatch_source_set_event_handler(timerSource, ^{ + dispatch_source_cancel(timerSource); + dispatch_release(timerSource); + + timer->HandleComplete(); + }); + dispatch_resume(timerSource); + return CHIP_NO_ERROR; + } + ChipLogProgress(DeviceLayer, "XXX StartTimer NOT using dispatch queue"); +#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH + + if (mTimerList.Add(timer) == timer) + { + // The new timer is the earliest, so the time until the next event has probably changed. + Signal(); + } + return CHIP_NO_ERROR; +} + +void WatchableEventManager::WeCancelTimer(Timers::OnCompleteFunct onComplete, void * appState) +{ + Timer * timer = mTimerList.Remove(onComplete, appState); + VerifyOrReturn(timer != nullptr); + + timer->Clear(); + +#if CHIP_SYSTEM_CONFIG_USE_DISPATCH + if (timer->mTimerSource != nullptr) + { + ChipLogProgress(DeviceLayer, "XXX CancelTimer source %p", timer->mTimerSource); + dispatch_source_cancel(timer->mTimerSource); + dispatch_release(timer->mTimerSource); + } + ChipLogProgress(DeviceLayer, "XXX CancelTimer NO timer source"); +#endif + + timer->Release(); + Signal(); +} + +CHIP_ERROR WatchableEventManager::WeScheduleWork(Timers::OnCompleteFunct onComplete, void * appState) +{ + WeCancelTimer(onComplete, appState); + + Timer * timer = Timer::New(*mSystemLayer, 0, onComplete, appState); + VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY); + +#if CHIP_SYSTEM_CONFIG_USE_DISPATCH + dispatch_queue_t dispatchQueue = GetDispatchQueue(); + if (dispatchQueue) + { + ChipLogProgress(DeviceLayer, "XXX ScheduleWork using dispatch queue %p", dispatchQueue); + (void) mTimerList.Add(timer); + dispatch_async(dispatchQueue, ^{ + timer->HandleComplete(); + }); + return CHIP_NO_ERROR; + } + ChipLogProgress(DeviceLayer, "XXX ScheduleWork NOT using dispatch queue"); +#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH + + if (mTimerList.Add(timer) == timer) + { + // The new timer is the earliest, so the time until the next event has probably changed. + Signal(); + } + return CHIP_NO_ERROR; +} + /** * Set the read, write or exception bit flags for the specified socket based on its status in * the corresponding file descriptor sets. @@ -121,12 +234,12 @@ SocketEvents WatchableEventManager::SocketEventsFromFDs(int socket, const fd_set return res; } -bool WatchableEventManager::HasAny(int fd) +bool WatchableEventManager::HasAnyRequest(int fd) { return FD_ISSET(fd, &mRequest.mReadSet) || FD_ISSET(fd, &mRequest.mWriteSet) || FD_ISSET(fd, &mRequest.mErrorSet); } -CHIP_ERROR WatchableEventManager::Set(int fd, fd_set * fds) +CHIP_ERROR WatchableEventManager::SetRequest(int fd, fd_set * fds) { FD_SET(fd, fds); if (fd > mMaxFd) @@ -138,7 +251,7 @@ CHIP_ERROR WatchableEventManager::Set(int fd, fd_set * fds) return CHIP_NO_ERROR; } -CHIP_ERROR WatchableEventManager::Clear(int fd, fd_set * fds) +CHIP_ERROR WatchableEventManager::ClearRequest(int fd, fd_set * fds) { FD_CLR(fd, fds); if (fd == mMaxFd) @@ -150,7 +263,7 @@ CHIP_ERROR WatchableEventManager::Clear(int fd, fd_set * fds) return CHIP_NO_ERROR; } -void WatchableEventManager::Reset(int fd) +void WatchableEventManager::ResetRequests(int fd) { FD_CLR(fd, &mRequest.mReadSet); FD_CLR(fd, &mRequest.mWriteSet); @@ -166,7 +279,7 @@ void WatchableEventManager::MaybeLowerMaxFd() int fd; for (fd = mMaxFd; fd >= 0; --fd) { - if (HasAny(fd)) + if (HasAnyRequest(fd)) { break; } @@ -186,8 +299,17 @@ void WatchableEventManager::PrepareEvents() void WatchableEventManager::PrepareEventsWithTimeout(struct timeval & nextTimeout) { - // TODO(#5556): Integrate timer platform details with WatchableEventManager. - mSystemLayer->GetTimeout(nextTimeout); + const Clock::MonotonicMilliseconds currentTime = Clock::GetMonotonicMilliseconds(); + Clock::MonotonicMilliseconds awakenTime = currentTime + TimevalToMilliseconds(nextTimeout); + + Timer * timer = mTimerList.Earliest(); + if (timer && Clock::IsEarlier(timer->mAwakenTime, awakenTime)) + { + awakenTime = timer->mAwakenTime; + } + + const Clock::MonotonicMilliseconds sleepTime = (awakenTime > currentTime) ? (awakenTime - currentTime) : 0; + MillisecondsToTimeval(sleepTime, nextTimeout); #if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ && !__MBED__ chip::Mdns::GetMdnsTimeout(nextTimeout); @@ -212,7 +334,17 @@ void WatchableEventManager::HandleEvents() } VerifyOrDie(mSystemLayer != nullptr); - mSystemLayer->HandleTimeout(); + +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + mHandleSelectThread = pthread_self(); +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING + + const Clock::MonotonicMilliseconds timeout = 1 + Clock::GetMonotonicMilliseconds(); + Timer *timer = nullptr; + while ((timer = mTimerList.PopIfEarlier(timeout)) != nullptr) + { + timer->HandleComplete(); + } for (WatchableSocket * watchable = mAttachedSockets; watchable != nullptr; watchable = watchable->mAttachedNext) { @@ -230,6 +362,10 @@ void WatchableEventManager::HandleEvents() #if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ && !__MBED__ chip::Mdns::HandleMdnsTimeout(); #endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ + +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + mHandleSelectThread = PTHREAD_NULL; +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING } } // namespace System diff --git a/src/system/WatchableEventManagerSelect.h b/src/system/WatchableEventManagerSelect.h index 2b1239777c6a0f..0fb17eb6468ab8 100644 --- a/src/system/WatchableEventManagerSelect.h +++ b/src/system/WatchableEventManagerSelect.h @@ -29,22 +29,37 @@ #include +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING +#include +#include +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING + #include #include +#include #include namespace chip { namespace System { +class Layer; +class Timer; class WatchableSocket; class WatchableEventManager { public: + // Core ‘overrides’. CHIP_ERROR Init(System::Layer & systemLayer); CHIP_ERROR Shutdown(); void Signal(); + // Timer ‘overrides’. + CHIP_ERROR WeStartTimer(uint32_t delayMilliseconds, Timers::OnCompleteFunct onComplete, void * appState); + void WeCancelTimer(Timers::OnCompleteFunct onComplete, void * appState); + CHIP_ERROR WeScheduleWork(Timers::OnCompleteFunct onComplete, void * appState); + + // Platform implementation. void EventLoopBegins() {} void PrepareEvents(); void WaitForEvents(); @@ -56,17 +71,21 @@ class WatchableEventManager static SocketEvents SocketEventsFromFDs(int socket, const fd_set & readfds, const fd_set & writefds, const fd_set & exceptfds); +#if CHIP_SYSTEM_CONFIG_USE_DISPATCH + void SetDispatchQueue(dispatch_queue_t dispatchQueue) { mDispatchQueue = dispatchQueue; }; + dispatch_queue_t GetDispatchQueue() { return mDispatchQueue; }; +#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH + protected: friend class WatchableSocket; - CHIP_ERROR Set(int fd, fd_set * fds); - CHIP_ERROR Clear(int fd, fd_set * fds); + CHIP_ERROR SetRequest(int fd, fd_set * fds); + CHIP_ERROR ClearRequest(int fd, fd_set * fds); Layer * mSystemLayer = nullptr; WatchableSocket * mAttachedSockets = nullptr; - - // TODO(#5556): Integrate timer platform details with WatchableEventManager. - struct timeval mNextTimeout; + Timer::List mTimerList; + timeval mNextTimeout; // Members for select loop struct SelectSets @@ -78,14 +97,24 @@ class WatchableEventManager SelectSets mRequest; SelectSets mSelected; int mMaxFd; - int mSelectResult; ///< return value from select() + + // Return value from select(), carried between WaitForEvents() and HandleEvents(). + int mSelectResult; WakeEvent mWakeEvent; +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING + std::atomic mHandleSelectThread; +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING + +#if CHIP_SYSTEM_CONFIG_USE_DISPATCH + dispatch_queue_t mDispatchQueue; +#endif + private: - bool HasAny(int fd); + bool HasAnyRequest(int fd); void MaybeLowerMaxFd(); - void Reset(int fd); + void ResetRequests(int fd); }; } // namespace System diff --git a/src/system/WatchableSocketSelect.cpp b/src/system/WatchableSocketSelect.cpp index e418493a5d7fe1..65ce2fb71a047b 100644 --- a/src/system/WatchableSocketSelect.cpp +++ b/src/system/WatchableSocketSelect.cpp @@ -34,7 +34,7 @@ namespace System { CHIP_ERROR WatchableSocket::OnAttach() { - mSharedState->Reset(mFD); + mSharedState->ResetRequests(mFD); VerifyOrReturnError(mAttachedNext == nullptr, CHIP_ERROR_INCORRECT_STATE); mAttachedNext = mSharedState->mAttachedSockets; @@ -45,7 +45,7 @@ CHIP_ERROR WatchableSocket::OnAttach() CHIP_ERROR WatchableSocket::OnRelease() { VerifyOrReturnError(mFD >= 0, CHIP_ERROR_INCORRECT_STATE); - mSharedState->Reset(mFD); + mSharedState->ResetRequests(mFD); WatchableSocket ** pp = &mSharedState->mAttachedSockets; while (*pp != nullptr) @@ -65,22 +65,22 @@ CHIP_ERROR WatchableSocket::OnRelease() CHIP_ERROR WatchableSocket::OnRequestCallbackOnPendingRead() { - return mSharedState->Set(mFD, &mSharedState->mRequest.mReadSet); + return mSharedState->SetRequest(mFD, &mSharedState->mRequest.mReadSet); } CHIP_ERROR WatchableSocket::OnRequestCallbackOnPendingWrite() { - return mSharedState->Set(mFD, &mSharedState->mRequest.mWriteSet); + return mSharedState->SetRequest(mFD, &mSharedState->mRequest.mWriteSet); } CHIP_ERROR WatchableSocket::OnClearCallbackOnPendingRead() { - return mSharedState->Clear(mFD, &mSharedState->mRequest.mReadSet); + return mSharedState->ClearRequest(mFD, &mSharedState->mRequest.mReadSet); } CHIP_ERROR WatchableSocket::OnClearCallbackOnPendingWrite() { - return mSharedState->Clear(mFD, &mSharedState->mRequest.mWriteSet); + return mSharedState->ClearRequest(mFD, &mSharedState->mRequest.mWriteSet); } /** diff --git a/src/system/system.gni b/src/system/system.gni index 0775d1f94e8423..12e371a7c29d1b 100644 --- a/src/system/system.gni +++ b/src/system/system.gni @@ -23,9 +23,6 @@ declare_args() { # Use BSD/POSIX socket API. chip_system_config_use_sockets = current_os != "freertos" - # Socket event loop type. - chip_system_config_sockets_event_loop = "Select" - # Mutex implementation: posix, freertos, none. chip_system_config_locking = "" @@ -42,6 +39,15 @@ declare_args() { (current_os == "mac" || current_os == "ios") } +declare_args() { + # Event loop type. + if (chip_system_config_use_lwip) { + chip_system_config_event_loop = "LwIP" + } else { + chip_system_config_event_loop = "Select" + } +} + if (chip_system_config_locking == "") { if (current_os == "freertos") { chip_system_config_locking = "freertos" diff --git a/src/system/tests/TestSystemTimer.cpp b/src/system/tests/TestSystemTimer.cpp index 8327ca3626726a..1adc79697f647f 100644 --- a/src/system/tests/TestSystemTimer.cpp +++ b/src/system/tests/TestSystemTimer.cpp @@ -63,7 +63,7 @@ static void ServiceEvents(Layer & aLayer, ::timeval & aSleepTime) { // TODO: Currently timers are delayed by aSleepTime above. A improved solution would have a mechanism to reduce // aSleepTime according to the next timer. - aLayer.HandlePlatformTimer(); + aLayer.WatchableEvents().LayerLwIPHandlePlatformTimer(); } #endif // CHIP_SYSTEM_CONFIG_USE_LWIP } @@ -133,8 +133,8 @@ static void CheckOverflow(nlTestSuite * inSuite, void * aContext) sOverflowTestDone = false; - lSys.StartTimer(timeout_overflow_0ms, HandleTimerFailed, aContext); - lSys.StartTimer(timeout_10ms, HandleTimer10Success, aContext); + lSys.StartFunctTimer(timeout_overflow_0ms, HandleTimerFailed, aContext); + lSys.StartFunctTimer(timeout_10ms, HandleTimer10Success, aContext); while (!sOverflowTestDone) { @@ -160,7 +160,7 @@ void HandleGreedyTimer(Layer * aLayer, void * aState, CHIP_ERROR aError) return; } - aLayer->StartTimer(0, HandleGreedyTimer, aState); + aLayer->StartFunctTimer(0, HandleGreedyTimer, aState); sNumTimersHandled++; } @@ -170,7 +170,7 @@ static void CheckStarvation(nlTestSuite * inSuite, void * aContext) Layer & lSys = *lContext.mLayer; struct timeval sleepTime; - lSys.StartTimer(0, HandleGreedyTimer, aContext); + lSys.StartFunctTimer(0, HandleGreedyTimer, aContext); sleepTime.tv_sec = 0; sleepTime.tv_usec = 1000; // 1 ms tick diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index 4750398a1d3ffc..e97206e90dfe73 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -272,7 +272,7 @@ CHIP_ERROR SecureSessionMgr::NewPairing(const Optional & void SecureSessionMgr::ScheduleExpiryTimer() { CHIP_ERROR err = - mSystemLayer->StartTimer(CHIP_PEER_CONNECTION_TIMEOUT_CHECK_FREQUENCY_MS, SecureSessionMgr::ExpiryTimerCallback, this); + mSystemLayer->StartFunctTimer(CHIP_PEER_CONNECTION_TIMEOUT_CHECK_FREQUENCY_MS, SecureSessionMgr::ExpiryTimerCallback, this); VerifyOrDie(err == CHIP_NO_ERROR); }