mirror of
https://github.com/json-c/json-c.git
synced 2026-04-05 05:19:07 +08:00
Explicitly check for GCC's atomic functions instead of depending on the __GNUC__ define.
Add a comment mentioning the limitation even though the _ref_count value is hanled atomically.
This commit is contained in:
24
configure.ac
24
configure.ac
@@ -66,6 +66,30 @@ AC_CHECK_DECLS([isnan], [], [], [[#include <math.h>]])
|
|||||||
AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
|
AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
|
||||||
AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
|
AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
|
||||||
AC_CHECK_DECLS([_finite], [], [], [[#include <float.h>]])
|
AC_CHECK_DECLS([_finite], [], [], [[#include <float.h>]])
|
||||||
|
AC_MSG_CHECKING(for GCC atomic builtins)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[
|
||||||
|
AC_LANG_SOURCE([[
|
||||||
|
int main() {
|
||||||
|
volatile unsigned int val = 1;
|
||||||
|
/* Note: __sync_val_compare_and_swap isn't checked here
|
||||||
|
* because it's protected by __GCC_HAVE_SYNC_COMPARE_AND_SWAP_<n>,
|
||||||
|
* which is automatically defined by gcc.
|
||||||
|
*/
|
||||||
|
__sync_add_and_fetch(&val, 1);
|
||||||
|
__sync_sub_and_fetch(&val, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE([HAVE_ATOMIC_BUILTINS],[1],[Has atomic builtins])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
AC_MSG_WARN([json-c will be built without atomic refcounts because atomic builtins are missing])
|
||||||
|
])
|
||||||
|
|
||||||
case "${host_os}" in
|
case "${host_os}" in
|
||||||
linux*)
|
linux*)
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ extern struct json_object* json_object_get(struct json_object *jso)
|
|||||||
{
|
{
|
||||||
if (!jso) return jso;
|
if (!jso) return jso;
|
||||||
|
|
||||||
#if defined __GNUC__
|
#ifdef HAVE_ATOMIC_BUILTINS
|
||||||
__sync_add_and_fetch(&jso->_ref_count, 1);
|
__sync_add_and_fetch(&jso->_ref_count, 1);
|
||||||
#else
|
#else
|
||||||
++jso->_ref_count;
|
++jso->_ref_count;
|
||||||
@@ -178,7 +178,13 @@ int json_object_put(struct json_object *jso)
|
|||||||
{
|
{
|
||||||
if(!jso) return 0;
|
if(!jso) return 0;
|
||||||
|
|
||||||
#if defined __GNUC__
|
#ifdef HAVE_ATOMIC_BUILTINS
|
||||||
|
/* Note: this only allow the refcount to remain correct
|
||||||
|
* when multiple threads are adjusting it. It is still an error
|
||||||
|
* for a thread to decrement the refcount if it doesn't "own" it,
|
||||||
|
* as that can result in the thread that loses the race to 0
|
||||||
|
* operating on an already-freed object.
|
||||||
|
*/
|
||||||
if (__sync_sub_and_fetch(&jso->_ref_count, 1) > 0) return 0;
|
if (__sync_sub_and_fetch(&jso->_ref_count, 1) > 0) return 0;
|
||||||
#else
|
#else
|
||||||
if (--jso->_ref_count > 0) return 0;
|
if (--jso->_ref_count > 0) return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user