From c9a976fe6ebc6da0a9f40970774c41cb6155324c Mon Sep 17 00:00:00 2001 From: Arnaud Date: Mon, 1 Jun 2026 15:30:49 +0400 Subject: [PATCH] Add documentation about onStateChange usage --- api.md | 9 ++++++++- libplum/plum.nim | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/api.md b/api.md index 11d08fb..1fc7e59 100644 --- a/api.md +++ b/api.md @@ -98,13 +98,20 @@ Returns a `MappingResult` containing the mapping `id` (needed for `destroyMappin Returns an error if no NAT device is found, the mapping fails, or the timeout expires. +> **Warning:** `onStateChange` runs on libplum's internal C thread, not the +> chronos event loop. Do not call chronos APIs or touch non-thread-safe state +> from it; restrict it to thread-safe operations (e.g. `Atomic`, a channel). + ### destroyMapping ```nim proc destroyMapping*(id: cint) ``` -Removes a mapping. Must be called exactly once after a successful `createMapping`. +Removes a mapping. Must be called exactly once after a successful `createMapping`, +otherwise the mapping's internal handle is leaked for the lifetime of the process. +Calling it again, or with an unknown `id`, is a safe no-op. `cleanup` also releases +any mappings still active. ### hasMapping diff --git a/libplum/plum.nim b/libplum/plum.nim index 3ce65e4..8253e8a 100644 --- a/libplum/plum.nim +++ b/libplum/plum.nim @@ -59,6 +59,9 @@ type mapping*: PlumMapping PlumStateCallback* = proc(state: PlumState, mapping: PlumMapping) {.callback.} + ## Invoked on mapping state changes after the initial result. Runs on + ## libplum's internal C thread, not the chronos loop: only touch + ## thread-safe state from it (e.g. Atomic), never chronos APIs. MappingHandle = ref object signal: ThreadSignalPtr