Skip to content

v3.0.0 — Multi-threaded reuseport listener support, deferred frames, and improved timer API

Choose a tag to compare

@g2px1 g2px1 released this 21 Oct 17:19
· 191 commits to main since this release
0bc2f5c

Release notes:

This update introduces major runtime and coroutine improvements for uvent, enabling finer scheduling control, better scalability, and safer timer usage.


🧩 Coroutine System

Deferred frame model

  • Added deferred_task_tag and DeferredFrame concept.

  • Coroutines can now start immediately or deferred depending on whether their frame inherits from deferred_task_tag.

    • Example: AwaitableIOFrame is now deferred by default — execution begins only when explicitly resumed (e.g. by an I/O event).
    • Regular AwaitableFrame coroutines still start immediately once enqueued.
  • This mechanism unifies instant and event-driven coroutine behavior without runtime branching.

AwaitableFrameBase improvements

  • Clearer coroutine chaining (prev_ / next_) and destruction semantics.
  • Consistent push_frame_into_task_queue logic between deferred and active frames.
  • Simplified and safer final suspend behavior.

⚙️ Runtime & Scheduling

Per-thread scheduling API

  • Added Uvent::for_each_thread(F&& fn) — iterate all worker threads before run().
    Enables per-thread initialization or static coroutine registration.
  • Added system::co_spawn_static(F&& f, int threadIndex) — enqueue coroutines into a specific thread inbox before startup.
    Ideal for binding listeners or initializing thread-local resources.

SO_REUSEPORT optimization

  • When UVENT_ENABLE_REUSEADDR is defined and supported by the platform,
    each worker thread can create its own TCP listener.
    Combined with for_each_thread, this enables true parallel accept loops and linear scalability across cores.

⏱️ Timers

Timer API redesigned

  • Updated addFunction signature to use std::any:

    void addFunction(std::function<void(std::any&)> f, std::any arg);
    void addFunction(std::function<void(std::any&)> f, std::any& arg);

    Simplifies type handling and supports arbitrary callback payloads.

  • Added INTERVAL timers for periodic execution.

  • Safer coroutine-based sleep_for() using internal TimerWheel.

  • Updated docs with examples and warnings against use-after-free.


🧵 Core fixes and enhancements

  • Unified handling of thread-local storage registry (TLSRegistry) for consistent pre-start coroutine enqueue.

  • Improved lifecycle management in coroutine destruction paths.

  • Refined exception propagation and await_suspend behavior.

  • Documentation rewritten for all affected modules:

    • Awaitable
    • AwaitableFrame
    • System Primitives
    • Timer API
    • Uvent (runtime entry)

✅ Summary

This release introduces:

  • Deferred coroutine execution model
  • Per-thread listener scheduling via for_each_thread
  • SO_REUSEPORT-based scalability
  • New std::any-based timer callbacks
  • Safer and more extensible coroutine lifecycle

Recommended version: v3.0.0
Tag message:

Deferred coroutine frames, per-thread listeners, and enhanced timer API for high-performance multi-core scalability.