Skip to content

Commit

Permalink
Add PlatformManager::Shutdown to permit the event loop to terminate p…
Browse files Browse the repository at this point in the history
…roperly for POSIX platforms (#1531)
  • Loading branch information
vivien-apple authored Jul 9, 2020
1 parent 67a1b59 commit e0f65ef
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 24 deletions.
6 changes: 6 additions & 0 deletions src/include/platform/PlatformManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class PlatformManager
void LockChipStack(void);
bool TryLockChipStack(void);
void UnlockChipStack(void);
CHIP_ERROR Shutdown(void);

private:
// ===== Members for internal use by the following friends.
Expand Down Expand Up @@ -234,6 +235,11 @@ inline CHIP_ERROR PlatformManager::StartChipTimer(uint32_t durationMS)
return static_cast<ImplClass *>(this)->_StartChipTimer(durationMS);
}

inline CHIP_ERROR PlatformManager::Shutdown(void)
{
return static_cast<ImplClass *>(this)->_Shutdown();
}

} // namespace DeviceLayer
} // namespace chip

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class GenericPlatformManagerImpl_FreeRTOS : public GenericPlatformManagerImpl<Im
void _RunEventLoop(void);
CHIP_ERROR _StartEventLoopTask(void);
CHIP_ERROR _StartChipTimer(uint32_t durationMS);
CHIP_ERROR _Shutdown(void);

// ===== Methods available to the implementation subclass.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,30 @@
#ifndef GENERIC_PLATFORM_MANAGER_IMPL_FREERTOS_IPP
#define GENERIC_PLATFORM_MANAGER_IMPL_FREERTOS_IPP

#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <platform/PlatformManager.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.h>

// Include the non-inline definitions for the GenericPlatformManagerImpl<> template,
// from which the GenericPlatformManagerImpl_FreeRTOS<> template inherits.
#include <platform/internal/GenericPlatformManagerImpl.ipp>


namespace chip {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>;

template<class ImplClass>
template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_InitChipStack(void)
{
CHIP_ERROR err = CHIP_NO_ERROR;

vTaskSetTimeOutState(&mNextTimerBaseTime);
mNextTimerDurationTicks = 0;
mEventLoopTask = NULL;
mChipTimerActive = false;
mEventLoopTask = NULL;
mChipTimerActive = false;

mChipStackLock = xSemaphoreCreateMutex();
if (mChipStackLock == NULL)
Expand All @@ -73,25 +72,25 @@ exit:
return err;
}

template<class ImplClass>
template <class ImplClass>
void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_LockChipStack(void)
{
xSemaphoreTake(mChipStackLock, portMAX_DELAY);
}

template<class ImplClass>
template <class ImplClass>
bool GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_TryLockChipStack(void)
{
return xSemaphoreTake(mChipStackLock, 0) == pdTRUE;
}

template<class ImplClass>
template <class ImplClass>
void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_UnlockChipStack(void)
{
xSemaphoreGive(mChipStackLock);
}

template<class ImplClass>
template <class ImplClass>
void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_PostEvent(const ChipDeviceEvent * event)
{
if (mChipEventQueue != NULL)
Expand All @@ -103,7 +102,7 @@ void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_PostEvent(const ChipDevice
}
}

template<class ImplClass>
template <class ImplClass>
void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_RunEventLoop(void)
{
CHIP_ERROR err;
Expand Down Expand Up @@ -180,29 +179,26 @@ void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_RunEventLoop(void)
}
}

template<class ImplClass>
template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_StartEventLoopTask(void)
{
BaseType_t res;

res = xTaskCreate(EventLoopTaskMain,
CHIP_DEVICE_CONFIG_CHIP_TASK_NAME,
CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE / sizeof(StackType_t),
this,
CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY,
NULL);
res = xTaskCreate(EventLoopTaskMain, CHIP_DEVICE_CONFIG_CHIP_TASK_NAME,
CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE / sizeof(StackType_t), this, CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY,
NULL);

return (res == pdPASS) ? CHIP_NO_ERROR : CHIP_ERROR_NO_MEMORY;
}

template<class ImplClass>
template <class ImplClass>
void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::EventLoopTaskMain(void * arg)
{
ChipLogDetail(DeviceLayer, "CHIP task running");
static_cast<GenericPlatformManagerImpl_FreeRTOS<ImplClass>*>(arg)->Impl()->RunEventLoop();
static_cast<GenericPlatformManagerImpl_FreeRTOS<ImplClass> *>(arg)->Impl()->RunEventLoop();
}

template<class ImplClass>
template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_StartChipTimer(uint32_t aMilliseconds)
{
mChipTimerActive = true;
Expand All @@ -222,7 +218,7 @@ CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_StartChipTimer(uint3
return CHIP_NO_ERROR;
}

template<class ImplClass>
template <class ImplClass>
void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::PostEventFromISR(const ChipDeviceEvent * event, BaseType_t & yieldRequired)
{
yieldRequired = pdFALSE;
Expand All @@ -236,6 +232,12 @@ void GenericPlatformManagerImpl_FreeRTOS<ImplClass>::PostEventFromISR(const Chip
}
}

template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_Shutdown(void)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class GenericPlatformManagerImpl_POSIX : public GenericPlatformManagerImpl<ImplC
void _RunEventLoop(void);
CHIP_ERROR _StartEventLoopTask(void);
CHIP_ERROR _StartChipTimer(uint32_t durationMS);
CHIP_ERROR _Shutdown(void);

// ===== Methods available to the implementation subclass.

Expand All @@ -92,6 +93,7 @@ class GenericPlatformManagerImpl_POSIX : public GenericPlatformManagerImpl<ImplC

void ProcessDeviceEvents();

bool mShouldRunEventLoop;
static void * EventLoopTaskMain(void * arg);
};

Expand Down
22 changes: 19 additions & 3 deletions src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ CHIP_ERROR GenericPlatformManagerImpl_POSIX<ImplClass>::_InitChipStack(void)
err = GenericPlatformManagerImpl<ImplClass>::_InitChipStack();
SuccessOrExit(err);

mShouldRunEventLoop = true;

exit:
return err;
}
Expand Down Expand Up @@ -190,20 +192,22 @@ void GenericPlatformManagerImpl_POSIX<ImplClass>::_RunEventLoop(void)
{
Impl()->LockChipStack();

// TODO(#742): add exit condition
while (true)
do
{
SysUpdate();
SysProcess();
}
} while (mShouldRunEventLoop);

Impl()->UnlockChipStack();

pthread_exit(0);
}

template <class ImplClass>
void * GenericPlatformManagerImpl_POSIX<ImplClass>::EventLoopTaskMain(void * arg)
{
ChipLogDetail(DeviceLayer, "CHIP task running");

static_cast<GenericPlatformManagerImpl_POSIX<ImplClass> *>(arg)->Impl()->RunEventLoop();
return NULL;
}
Expand All @@ -224,6 +228,18 @@ exit:
return System::MapErrorPOSIX(err);
}

template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl_POSIX<ImplClass>::_Shutdown(void)
{
int err;
mShouldRunEventLoop = false;
err = pthread_join(mChipTask, NULL);
SuccessOrExit(err);

exit:
return System::MapErrorPOSIX(err);
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericPlatformManagerImpl_POSIX<PlatformManagerImpl>;

Expand Down

0 comments on commit e0f65ef

Please sign in to comment.