#define MS_CLASS "TimerHandle"
#include "handles/TimerHandle.hpp"
#include "DepLibUV.hpp"
#include "Logger.hpp"
#include "MediaSoupErrors.hpp"
inline static void onTimer(uv_timer_t* handle)
{
static_cast<TimerHandle*>(handle->data)->OnUvTimer();
}
inline static void onCloseTimer(uv_handle_t* handle)
{
delete reinterpret_cast<uv_timer_t*>(handle);
}
TimerHandle::TimerHandle(Listener* listener) : listener(listener)
{
MS_TRACE();
this->uvHandle = new uv_timer_t;
this->uvHandle->data = static_cast<void*>(this);
const int err = uv_timer_init(DepLibUV::GetLoop(), this->uvHandle);
if (err != 0)
{
delete this->uvHandle;
this->uvHandle = nullptr;
MS_THROW_ERROR("uv_timer_init() failed: %s", uv_strerror(err));
}
}
TimerHandle::~TimerHandle()
{
MS_TRACE();
if (!this->closed)
{
Close();
}
}
void TimerHandle::Close()
{
MS_TRACE();
if (this->closed)
{
return;
}
this->closed = true;
uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseTimer));
}
void TimerHandle::Start(uint64_t timeout, uint64_t repeat)
{
MS_TRACE();
if (this->closed)
{
MS_THROW_ERROR("closed");
}
this->timeout = timeout;
this->repeat = repeat;
if (uv_is_active(reinterpret_cast<uv_handle_t*>(this->uvHandle)) != 0)
{
Stop();
}
const int err = uv_timer_start(this->uvHandle, static_cast<uv_timer_cb>(onTimer), timeout, repeat);
if (err != 0)
{
MS_THROW_ERROR("uv_timer_start() failed: %s", uv_strerror(err));
}
}
void TimerHandle::Stop()
{
MS_TRACE();
if (this->closed)
{
MS_THROW_ERROR("closed");
}
const int err = uv_timer_stop(this->uvHandle);
if (err != 0)
{
MS_THROW_ERROR("uv_timer_stop() failed: %s", uv_strerror(err));
}
}
void TimerHandle::Reset()
{
MS_TRACE();
if (this->closed)
{
MS_THROW_ERROR("closed");
}
if (uv_is_active(reinterpret_cast<uv_handle_t*>(this->uvHandle)) == 0)
{
return;
}
if (this->repeat == 0u)
{
return;
}
const int err =
uv_timer_start(this->uvHandle, static_cast<uv_timer_cb>(onTimer), this->repeat, this->repeat);
if (err != 0)
{
MS_THROW_ERROR("uv_timer_start() failed: %s", uv_strerror(err));
}
}
void TimerHandle::Restart()
{
MS_TRACE();
if (this->closed)
{
MS_THROW_ERROR("closed");
}
if (uv_is_active(reinterpret_cast<uv_handle_t*>(this->uvHandle)) != 0)
{
Stop();
}
const int err =
uv_timer_start(this->uvHandle, static_cast<uv_timer_cb>(onTimer), this->timeout, this->repeat);
if (err != 0)
{
MS_THROW_ERROR("uv_timer_start() failed: %s", uv_strerror(err));
}
}
inline void TimerHandle::OnUvTimer()
{
MS_TRACE();
this->listener->OnTimer(this);
}