Skip to content

C++ SDK: Thread-Safety Contract

If you embed the SDK in a GUI or otherwise multi-threaded application, follow this contract so you call it without data races. It states which calls are safe to make concurrently and which are not.


A single aureva::Api instance is safe to use from one thread at a time.

Do not call the mutating methods init(), license(), or check() concurrently on the same instance. These calls advance the instance’s state machine; issuing them at the same time from different threads is unsupported.

Typical pattern: run init() and license() on a worker (off your UI / render thread, since they block on the network), and schedule check() from a single timer or loop — never overlapping with another mutating call on the same instance.


Reading the published snapshots — app.response and app.user_data — from a thread other than the one making the most recent mutating call is safe and non-blocking.

The SDK publishes those snapshots under its own internal synchronization, so a reader on a separate thread (for example a render thread polling the current authorization status to draw UI) always observes an internally consistent value and never a torn or partial one. The reader never blocks on the network-holding work that license() / check() perform.

// Worker thread:
app.license(key); // mutating call — single owner
// Render thread (concurrently): safe, non-blocking snapshot reads
if (app.response.success) {
drawStatus(app.user_data.tier, app.user_data.expiry);
}

While the background session is alive, the SDK runs an internal heartbeat thread. The SDK synchronizes its internal shared state — the authorization verdict, the session state, the subscription / entitlement cache, and the lockout state — so the heartbeat thread and the reads performed by check() and user_data do not data-race.


Concurrent mutation is undefined and unsupported

Section titled “Concurrent mutation is undefined and unsupported”

If you violate the contract — for example by issuing concurrent mutating calls on a single instance — the resulting behavior is undefined and unsupported, not guaranteed. The SDK is not required to defend against this misuse beyond the guarantees stated here.


Multiple keys or applications — use a separate instance

Section titled “Multiple keys or applications — use a separate instance”

If you need concurrent authentication for multiple keys or applications, use a separate aureva::Api instance per logical session.

Distinct instances do not share mutable SDK state in a way that would cause cross-instance races. The one process- and machine-global facility is the HWID store on disk; the SDK serializes access to it with a process-wide named lock, so concurrent instances on the same machine coordinate and never corrupt the persisted identifier.


OperationRule
init() / license() / check() on one instanceOne thread at a time — never concurrently
Reading response / user_dataSafe and non-blocking from any thread
Concurrent mutating calls on one instanceUndefined / unsupported
Multiple keys or applicationsOne aureva::Api instance per logical session
HWID storeShared but synchronized by the SDK across instances