init() and release() now use atomic operation to keep track of session count (init_count).

doc_update_sequoia
Edouard Tisserant 6 years ago
parent 120578a07f
commit 87c57aab4c

@ -8,7 +8,8 @@
#include "blacklist.h"
#include "sync_fsm.h"
static int init_count = -1;
// This is C 2011
static _Atomic volatile int init_count = -1;
// sql overloaded functions - modified from sqlite3.c
static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
@ -264,9 +265,21 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
// a little race condition - but still a race condition
// mitigated by calling caveat (see documentation)
++init_count;
if (init_count == 0)
// This increment is made atomic by using "_Atomic volatile" qualifier thus
// ensuring consistent counting provided that init/release calls are balanced
int _count = ++init_count;
if (_count == 0)
in_first = true;
// Race contition mitigated by calling caveat starts here :
// If another call to init() preempts right now, then preemptive call
// will have in_first false, will not create SQL tables, and following
// calls relying on those tables will fail. Therefore, first session
// is to be created and last session to be deleted alone, and not
// concurently to other sessions creation or deletion.
// We expect adapters to enforce this either by implicitely creating a
// client session, or by using synchronization primitive to protect
// creation/deletion of first/last session from the app.
assert(session);
if (session == NULL)
@ -772,19 +785,19 @@ pep_error:
DYNAMIC_API void release(PEP_SESSION session)
{
bool out_last = false;
assert(init_count >= 0);
int _count = --init_count;
assert(_count >= -1);
assert(session);
if (!((init_count >= 0) && session))
if (!((_count >= -1) && session))
return;
// a small race condition but still a race condition
// mitigated by calling caveat (see documentation)
if (init_count == 0)
if (_count == -1)
out_last = true;
--init_count;
if (session) {
if (session->sync_state != DeviceState_state_NONE)

Loading…
Cancel
Save