Skip to content

4.0.0

Latest

Choose a tag to compare

@LK-Simon LK-Simon released this 13 Aug 18:56

Make Event listener ownership RAII-safe and enforce bounded retained Event counts

Problem

Event listener registration currently returns a raw owning IEventListenerHandle*. Losing this pointer leaks the registration handle, while manual deletion requirements make lifetime management error-prone.

Event receiver queues also default to an unlimited pending-event count. A producer that consistently outruns a consumer can therefore exhaust the embedded heap.

The existing pending limit counts queued Events only. Events moved into an active processing batch are removed from that count before their references are released, allowing the actual number of retained Event references to temporarily exceed the configured limit.

Proposed changes

Listener ownership

  • Introduce EventListenerHandlePtr as std::unique_ptr<IEventListenerHandle>.
  • Change callback and Observer registration APIs to return the owning smart-pointer type.
  • Automatically unregister listeners when their handles are reset or destroyed.
  • Make EventListenerHandle destruction exception-safe.
  • Update Event Observer and callback-listener examples to use RAII.
  • Remove manual delete requirements from the documentation and examples.

Event queue bounds

  • Default each EventReceiver to a maximum of 64 retained Events.
  • Continue using BlockProducer as the default overflow policy.
  • Allow the default bound to be configured through:
    • ESPRESSIO_EVENT_DEFAULT_MAX_PENDING_EVENT_COUNT
  • Continue allowing an explicit maximum of zero for applications that genuinely require an unbounded receiver.
  • Include Events currently being processed in the retained-event bound.
  • Release capacity only after the processing batch has released its Event references.
  • Ensure DropOldest rejects the incoming Event safely when all retained capacity belongs to an active batch and no queued Event can be displaced.
  • Preserve exception-safe reference release when listener processing throws.

Infrastructure documentation

  • Document EventManager as process-lifetime FreeRTOS infrastructure.
  • Clarify that its task, semaphore, dispatcher, and per-type routing buckets are fixed infrastructure rather than per-dispatch Event leaks.

Version impact

The Event listener registration return type and ownership contract change.

Target version: 4.0.0

Dependency changes

  • ESPressio-Threads >=2.0.0
  • ESPressio-Observable >=3.0.0

Acceptance criteria

  • Listener and Observer registrations return owning smart pointers.
  • Losing manual raw-pointer cleanup is no longer a leak path.
  • Receiver queues are bounded by default.
  • The configured bound includes queued and actively processed Event references.
  • Overflow policies continue releasing rejected or displaced Event references correctly.
  • Listener destruction cannot propagate an exception.
  • Strict host tests pass with warnings treated as errors.
  • UBSan tests pass.
  • The 10,000-Event reference-count stress test passes.
  • Heap analysis reports no leaked listener allocations.