Ken Van Hoeylandt 686f7cce83
TactilityCore improvements (#187)
FreeRTOS handles were stored plainly and they were deleted in the destructor of classes.
This meant that if a class were to be copied, the destructor would be called twice on the same handles and lead to double-free.

Seha on Discord suggested to fix this by using `std::unique_ptr` with a custom deletion function.

The changes affect:
- Thread
- Semaphore
- Mutex
- StreamBuffer
- Timer
- MessageQueue
- EventFlag

Thread  changes:
- Removal of the hack with the `Data` struct
- Thread's main body is now just a private static function inside the class.
- The C functions were relocated to static class members

PubSub changes:
- Refactored pubsub into class
- Renamed files to `PubSub` instead of `Pubsub`
- `PubSubSubscription` is now a private inner struct and `PubSub` only exposes `SubscriptionHandle`

Lockable, ScopedLockable, Mutex:
- Added `lock()` method that locks indefinitely
- Remove deprecated `acquire()` and `release()` methods
- Removed `TtWaitForever` in favour of `portMAX_DELAY`
2025-01-25 17:29:11 +01:00

62 lines
1.4 KiB
C++

/**
* @file pubsub.h
* PubSub
*/
#pragma once
#include "Mutex.h"
#include <list>
namespace tt {
/** PubSub Callback type */
typedef void (*PubSubCallback)(const void* message, void* context);
/** Publish and subscribe to messages in a thread-safe manner. */
class PubSub {
private:
struct Subscription {
uint64_t id;
PubSubCallback callback;
void* callbackParameter;
};
typedef std::list<Subscription> Subscriptions;
uint64_t lastId = 0;
Subscriptions items;
Mutex mutex;
public:
typedef void* SubscriptionHandle;
PubSub() = default;
~PubSub() {
tt_check(items.empty());
}
/** Start receiving messages at the specified handle (Threadsafe, Re-entrable)
* @param[in] callback
* @param[in] callbackParameter the data to pass to the callback
* @return subscription instance
*/
SubscriptionHandle subscribe(PubSubCallback callback, void* callbackParameter);
/** Stop receiving messages at the specified handle (Threadsafe, Re-entrable.)
* No use of `tt_pubsub_subscription` allowed after call of this method
* @param[in] subscription
*/
void unsubscribe(SubscriptionHandle subscription);
/** Publish message to all subscribers (Threadsafe, Re-entrable.)
* @param[in] message message pointer to publish - it is passed as-is to the callback
*/
void publish(void* message);
};
} // namespace