akheron / jansson

C library for encoding, decoding and manipulating JSON data
http://www.digip.org/jansson/
Other
3.06k stars 815 forks source link

thread safety of json_incref and json_decref #648

Closed halajohn closed 1 year ago

halajohn commented 1 year ago

The jansson document says that json_incref/decref are thread safety.

However, reference count manipulation (json_incref(), json_decref()) is usually thread-safe, and can be performed on JSON values that are shared among threads.

Consider the following condition:

Thread A:

static JSON_INLINE json_t *json_incref(json_t *json) {
    if (json && json->refcount != (size_t)-1) {
         // ^ context switch to thread B at this point.
         // In other words, after determining 'json' is not NULL, before 'json->refcount'
        JSON_INTERNAL_INCREF(json);
    }
    return json;
}

Thread B: When thread B is executing, it completes the whole json_decref() function on the same json instance.

static JSON_INLINE void json_decref(json_t *json) {
    if (json && json->refcount != (size_t)-1 && JSON_INTERNAL_DECREF(json) == 0) {
        json_delete(json);
        // context switch to thread A at this line.
   }
}

Then a segmentation fault would occur in thread A because of json->refcount.

Therefore, what condition should be met so that we can use json_incref/decref on the same json instance in multiple threads without locking?