SW Task Event Loop Framework v1.0.0
High-performance C++ asynchronous event loop framework with timer management and promise-based programming
Loading...
Searching...
No Matches
swt::TimerManager Class Reference

High-performance timer management with configurable backend. More...

#include <TimerManager.h>

Collaboration diagram for swt::TimerManager:
Collaboration graph

Classes

struct  TimerInfo
 Internal timer information structure. More...
 

Public Member Functions

 TimerManager (std::weak_ptr< SLLooper > looper)
 Construct a new TimerManager.
 
 ~TimerManager ()
 Destroy the TimerManager and cleanup all resources.
 
TimerId createTimer (std::function< void()> callback, uint64_t delay_ms, bool periodic, std::atomic< bool > *cancelled)
 Create a new timer.
 
bool cancelTimer (TimerId id)
 Cancel an active timer.
 
bool hasTimer (TimerId id)
 Check if a timer exists and is active.
 
bool restartTimer (TimerId id, uint64_t delay_ms)
 Restart an existing timer with new delay.
 
void updateCancelledPtr (TimerId id, std::atomic< bool > *newPtr)
 Update the cancellation flag pointer for an existing timer.
 
size_t getActiveTimerCount ()
 Get the number of currently active timers.
 

Static Public Member Functions

static const char * getBackendName ()
 Get the name of the currently compiled timer backend.
 

Detailed Description

High-performance timer management with configurable backend.

TimerManager provides a unified interface for managing timers with two different backend implementations:

TIMERFD_EPOLL Backend (Linux):

  • Uses Linux timerfd + epoll for high performance
  • Single dedicated thread processes all timer events
  • Excellent scalability for many concurrent timers
  • Low CPU overhead and precise timing

SIGEV_THREAD Backend (POSIX):

  • Uses POSIX timer_create with SIGEV_THREAD
  • Each timer callback runs in its own thread
  • Portable across UNIX systems
  • Higher resource usage but better compatibility
Thread Safety
All public methods are thread-safe and can be called from multiple threads concurrently. Timer callbacks are executed on the SLLooper main thread.
Performance Characteristics
  • TIMERFD_EPOLL: O(1) timer creation/deletion, O(log n) event processing
  • SIGEV_THREAD: O(1) timer creation/deletion, O(1) event processing per timer
Example Usage
auto looper = std::make_shared<SLLooper>();
TimerManager manager(looper);
// Create one-shot timer
std::atomic<bool> cancelled(false);
TimerId id = manager.createTimer([]() {
std::cout << "Timer fired!" << std::endl;
}, 1000, false, &cancelled);
// Create periodic timer
TimerId periodicId = manager.createTimer([]() {
std::cout << "Periodic timer!" << std::endl;
}, 500, true, nullptr);
High-performance timer management with configurable backend.
uint64_t TimerId
Unique identifier type for timer instances.
Definition Timer.h:25
Warning
Timer callbacks must not block for extended periods as they run on the main event loop thread.
See also
SLLooper
Timer

Definition at line 137 of file TimerManager.h.

Constructor & Destructor Documentation

◆ TimerManager()

swt::TimerManager::TimerManager ( std::weak_ptr< SLLooper looper)
explicit

Construct a new TimerManager.

Parameters
looperWeak reference to parent SLLooper for callback posting

Initializes the timer management system with the compile-time selected backend. For TIMERFD_EPOLL, creates epoll instance and starts timer thread. For SIGEV_THREAD, performs minimal initialization.

Exceptions
std::runtime_errorIf backend initialization fails (e.g., epoll_create fails)
Example
auto looper = std::make_shared<SLLooper>();
TimerManager manager(looper); // Automatically uses configured backend
Warning
The SLLooper must remain alive for the lifetime of TimerManager
See also
~TimerManager()

Definition at line 17 of file TimerManager.cpp.

References getBackendName(), TIMER_DEBUG, TIMER_DEBUG_STREAM, and TIMER_ERROR_STREAM.

Here is the call graph for this function:

◆ ~TimerManager()

swt::TimerManager::~TimerManager ( )

Destroy the TimerManager and cleanup all resources.

Safely shuts down the timer system by:

  1. Setting running flag to false
  2. Cancelling all active timers
  3. Cleaning up backend-specific resources
  4. Joining timer thread (TIMERFD_EPOLL only)

All timer callbacks in progress will complete before destruction finishes.

Note
Destructor is thread-safe and can be called while timers are active
Cleanup Details
  • TIMERFD_EPOLL: Closes all timerfd handles, joins timer thread, closes epoll fd
  • SIGEV_THREAD: Deletes all POSIX timers, removes from global map
See also
TimerManager()

Definition at line 41 of file TimerManager.cpp.

References TIMER_DEBUG, TIMER_DEBUG_STREAM, and TIMER_INFO.

Member Function Documentation

◆ cancelTimer()

bool swt::TimerManager::cancelTimer ( TimerId  id)

Cancel an active timer.

Parameters
idTimer ID returned by createTimer()
Returns
true if timer was found and cancelled successfully
false if timer ID not found or already cancelled

Immediately stops the specified timer and removes it from the system. If the timer callback is currently executing, this method will wait for it to complete before returning.

After cancellation, the timer ID becomes invalid and should not be used.

Thread Safety
This method is thread-safe and can be called from any thread, including from within timer callbacks.
Backend Behavior
  • TIMERFD_EPOLL: Removes from epoll, closes timerfd, removes from map
  • SIGEV_THREAD: Calls timer_delete(), removes from global map
Example
TimerId id = manager.createTimer(callback, 1000, false, nullptr);
// Cancel immediately
if (manager.cancelTimer(id)) {
std::cout << "Timer cancelled successfully" << std::endl;
}
// Attempting to cancel again returns false
bool result = manager.cancelTimer(id); // false
Note
Cancelling an invalid ID is safe and returns false
See also
createTimer()
hasTimer()

Definition at line 416 of file TimerManager.cpp.

References getBackendName(), and TIMER_DEBUG_STREAM.

Here is the call graph for this function:

◆ createTimer()

TimerId swt::TimerManager::createTimer ( std::function< void()>  callback,
uint64_t  delay_ms,
bool  periodic,
std::atomic< bool > *  cancelled 
)

Create a new timer.

Parameters
callbackFunction to call when timer expires (must not be null)
delay_msDelay in milliseconds before first expiration (must be > 0)
periodictrue for repeating timer, false for one-shot timer
cancelledOptional pointer to atomic bool for external cancellation
Returns
TimerId Unique timer identifier (0 if creation failed)

Creates and starts a new timer that will call the provided callback after the specified delay. For periodic timers, the callback will be called repeatedly at the specified interval until cancelled.

The callback will be executed on the SLLooper main thread, ensuring thread safety with other event loop operations.

Cancellation Mechanism
If a cancelled pointer is provided, the timer will check this flag before executing the callback. This allows for external cancellation even after the timer has fired but before callback execution.
Backend Behavior
  • TIMERFD_EPOLL: Creates timerfd, configures timing, adds to epoll
  • SIGEV_THREAD: Creates POSIX timer with SIGEV_THREAD notification
Error Conditions
Returns 0 if:
  • callback is null
  • System timer creation fails (out of resources, invalid parameters)
  • Backend-specific errors (epoll_ctl failure, timer_create failure)
Example
// One-shot timer
TimerId id = manager.createTimer([]() {
std::cout << "Timer fired once!" << std::endl;
}, 1000, false, nullptr);
// Periodic timer with cancellation
std::atomic<bool> cancelled(false);
TimerId periodicId = manager.createTimer([&]() {
std::cout << "Periodic: " << std::chrono::steady_clock::now() << std::endl;
}, 500, true, &cancelled);
// Cancel after some time
std::this_thread::sleep_for(std::chrono::seconds(2));
cancelled = true;
Warning
Callback must not block for extended periods
Do not capture TimerManager or Timer objects in callback to avoid cycles
See also
cancelTimer()
restartTimer()

Definition at line 77 of file TimerManager.cpp.

References swt::TimerManager::TimerInfo::callback, swt::TimerManager::TimerInfo::cancelled, swt::TimerManager::TimerInfo::fd, getBackendName(), swt::TimerManager::TimerInfo::id, swt::TimerManager::TimerInfo::interval_ms, swt::TimerManager::TimerInfo::periodic, TIMER_DEBUG_STREAM, TIMER_ERROR, and TIMER_ERROR_STREAM.

Here is the call graph for this function:

◆ getActiveTimerCount()

size_t swt::TimerManager::getActiveTimerCount ( )

Get the number of currently active timers.

Returns
size_t Number of active timers managed by this instance

Returns the current count of active timers. This includes both one-shot and periodic timers that have not yet been cancelled or expired.

Thread Safety
This method is thread-safe and returns a consistent snapshot at call time.
Performance
This is an O(1) operation that returns the size of the internal timer map.
Example
std::cout << "Active timers: " << manager.getActiveTimerCount() << std::endl;
// Create some timers
auto id1 = manager.createTimer(callback, 1000, false, nullptr);
auto id2 = manager.createTimer(callback, 2000, true, nullptr);
std::cout << "After creation: " << manager.getActiveTimerCount() << std::endl; // 2
manager.cancelTimer(id1);
std::cout << "After cancel: " << manager.getActiveTimerCount() << std::endl; // 1
Note
Count may change immediately after return due to concurrent operations
See also
hasTimer()
createTimer()
cancelTimer()

Definition at line 478 of file TimerManager.cpp.

◆ getBackendName()

static const char * swt::TimerManager::getBackendName ( )
inlinestatic

Get the name of the currently compiled timer backend.

Returns
const char* Backend name string ("TIMERFD_EPOLL" or "SIGEV_THREAD")

Returns a string identifying which timer backend was selected at compile time. This is useful for logging, debugging, and runtime feature detection.

Return Values
  • "TIMERFD_EPOLL" - Linux timerfd + epoll backend
  • "SIGEV_THREAD" - POSIX timer_create + sigev_thread backend
Example
std::cout << "Timer backend: " << TimerManager::getBackendName() << std::endl;
if (strcmp(TimerManager::getBackendName(), "TIMERFD_EPOLL") == 0) {
std::cout << "Using high-performance Linux backend" << std::endl;
}
static const char * getBackendName()
Get the name of the currently compiled timer backend.
Note
This is a static method and can be called without TimerManager instance
See also
SLLooper::getTimerBackend()

Definition at line 536 of file TimerManager.h.

Referenced by cancelTimer(), createTimer(), swt::SLLooper::getTimerBackend(), restartTimer(), and TimerManager().

Here is the caller graph for this function:

◆ hasTimer()

bool swt::TimerManager::hasTimer ( TimerId  id)

Check if a timer exists and is active.

Parameters
idTimer ID to check
Returns
true if timer exists and is active
false if timer ID not found, cancelled, or expired (for one-shot)

Queries whether the specified timer ID corresponds to an active timer. This is useful for checking timer status before performing operations.

Thread Safety
This method is thread-safe and provides a consistent snapshot of timer state.
Example
TimerId id = manager.createTimer(callback, 5000, false, nullptr);
if (manager.hasTimer(id)) {
std::cout << "Timer is still active" << std::endl;
manager.cancelTimer(id);
}
Note
Result may become stale immediately after return due to concurrent operations
See also
createTimer()
cancelTimer()
getActiveTimerCount()

Definition at line 442 of file TimerManager.cpp.

References TIMER_DEBUG_STREAM.

◆ restartTimer()

bool swt::TimerManager::restartTimer ( TimerId  id,
uint64_t  delay_ms 
)

Restart an existing timer with new delay.

Parameters
idTimer ID to restart
delay_msNew delay in milliseconds
Returns
true if timer was found and restarted successfully
false if timer ID not found

Resets an existing timer to fire after the new specified delay. The timer becomes a one-shot timer regardless of its original periodic setting. If the timer was cancelled via external flag, the cancellation is reset.

This operation is more efficient than cancelling and creating a new timer as it reuses the existing timer resources.

Thread Safety
This method is thread-safe and can be called from any thread.
Backend Behavior
  • TIMERFD_EPOLL: Updates timerfd with new interval using timerfd_settime()
  • SIGEV_THREAD: Updates POSIX timer with new interval using timer_settime()
Example
TimerId id = manager.createTimer(callback, 1000, true, nullptr);
// Change to fire in 5 seconds (becomes one-shot)
if (manager.restartTimer(id, 5000)) {
std::cout << "Timer restarted with 5s delay" << std::endl;
}
Warning
Restarted timer always becomes one-shot, losing periodic behavior
See also
createTimer()
cancelTimer()

Definition at line 449 of file TimerManager.cpp.

References getBackendName(), and TIMER_DEBUG_STREAM.

Here is the call graph for this function:

◆ updateCancelledPtr()

void swt::TimerManager::updateCancelledPtr ( TimerId  id,
std::atomic< bool > *  newPtr 
)

Update the cancellation flag pointer for an existing timer.

Parameters
idTimer ID to update
newPtrNew pointer to atomic bool cancellation flag

Updates the cancellation flag pointer for an existing timer. This allows changing the external cancellation mechanism after timer creation.

The new pointer will be checked before each callback execution. Pass nullptr to disable external cancellation for the timer.

Thread Safety
This method is thread-safe. The pointer update is atomic.
Use Cases
  • Changing ownership of cancellation control
  • Disabling external cancellation (pass nullptr)
  • Updating to new cancellation flag after object moves
Example
std::atomic<bool> cancelled1(false);
TimerId id = manager.createTimer(callback, 1000, true, &cancelled1);
// Change to different cancellation flag
std::atomic<bool> cancelled2(false);
manager.updateCancelledPtr(id, &cancelled2);
// Disable external cancellation
manager.updateCancelledPtr(id, nullptr);
Warning
Ensure the new pointer remains valid for timer lifetime
Old pointer may still be checked if callback is in progress
See also
createTimer()

Definition at line 483 of file TimerManager.cpp.

References TIMER_DEBUG_STREAM.


The documentation for this class was generated from the following files: