| @@ -45,7 +45,7 @@ $ sh autogen.sh | |||
| followed by | |||
| ```sh | |||
| $ ./configure | |||
| $ ./configure # --enable-threading | |||
| $ make | |||
| $ make install | |||
| ``` | |||
| @@ -56,6 +56,25 @@ To build and run the test programs: | |||
| $ make check | |||
| ``` | |||
| Building with partial threading support | |||
| ---------------------------------------- | |||
| Although json-c does not support fully multi-threaded access to | |||
| object trees, it has some code to help make use in threaded programs | |||
| a bit safer. Currently, this is limited to using atomic operations for | |||
| json_object_get() and json_object_put(). | |||
| Since this may have a performance impact, of at least 3x slower | |||
| according to https://stackoverflow.com/a/11609063, it is disabled by | |||
| default. You may turn it on by adjusting your configure command with: | |||
| --enable-threading | |||
| Separately, the default hash function used for object field keys, | |||
| lh_char_hash, uses a compare-and-swap operation to ensure the randomly | |||
| seed is only generated once. Because this is a one-time operation, it | |||
| is always compiled in when the compare-and-swap operation is available. | |||
| Linking to `libjson-c` | |||
| ---------------------- | |||
| @@ -11,12 +11,26 @@ AC_PROG_MAKE_SET | |||
| AC_CANONICAL_HOST | |||
| AC_ARG_ENABLE(threading, | |||
| AS_HELP_STRING([--enable-threading], | |||
| [Enable code to support partly multi-threaded use]), | |||
| [if test x$enableval = xyes; then | |||
| enable_threading=yes | |||
| AC_DEFINE(ENABLE_THREADING, 1, [Enable partial threading support]) | |||
| fi]) | |||
| if test "x$enable_threading" = "xyes"; then | |||
| AC_MSG_RESULT([Partial multi-threaded support enabled.]) | |||
| else | |||
| AC_MSG_RESULT([Multi-threaded support disabled. Use --enable-threading to enable.]) | |||
| fi | |||
| AC_ARG_ENABLE(rdrand, | |||
| AS_HELP_STRING([--enable-rdrand], | |||
| [Enable RDRAND Hardware RNG Hash Seed generation on supported x86/x64 platforms.]), | |||
| [if test x$enableval = xyes; then | |||
| enable_rdrand=yes | |||
| AC_DEFINE(ENABLE_RDRAND, 1, [Enable RDRANR Hardware RNG Hash Seed]) | |||
| AC_DEFINE(ENABLE_RDRAND, 1, [Enable RDRAND Hardware RNG Hash Seed]) | |||
| fi]) | |||
| if test "x$enable_rdrand" = "xyes"; then | |||
| @@ -165,7 +165,7 @@ extern struct json_object* json_object_get(struct json_object *jso) | |||
| { | |||
| if (!jso) return jso; | |||
| #ifdef HAVE_ATOMIC_BUILTINS | |||
| #if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING) | |||
| __sync_add_and_fetch(&jso->_ref_count, 1); | |||
| #else | |||
| ++jso->_ref_count; | |||
| @@ -178,7 +178,7 @@ int json_object_put(struct json_object *jso) | |||
| { | |||
| if(!jso) return 0; | |||
| #ifdef HAVE_ATOMIC_BUILTINS | |||
| #if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING) | |||
| /* 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, | |||
| @@ -703,7 +703,7 @@ int json_object_set_int64(struct json_object *jso,int64_t new_value){ | |||
| /* json_object_double */ | |||
| #ifdef HAVE___THREAD | |||
| #if defined(HAVE___THREAD) && defined(ENABLE_THREADING) | |||
| // i.e. __thread or __declspec(thread) | |||
| static SPEC___THREAD char *tls_serialization_float_format = NULL; | |||
| #endif | |||
| @@ -713,7 +713,7 @@ int json_c_set_serialization_double_format(const char *double_format, int global | |||
| { | |||
| if (global_or_thread == JSON_C_OPTION_GLOBAL) | |||
| { | |||
| #ifdef HAVE___THREAD | |||
| #if defined(HAVE___THREAD) && defined(ENABLE_THREADING) | |||
| if (tls_serialization_float_format) | |||
| { | |||
| free(tls_serialization_float_format); | |||
| @@ -726,7 +726,7 @@ int json_c_set_serialization_double_format(const char *double_format, int global | |||
| } | |||
| else if (global_or_thread == JSON_C_OPTION_THREAD) | |||
| { | |||
| #ifdef HAVE___THREAD | |||
| #if defined(HAVE___THREAD) && defined(ENABLE_THREADING) | |||
| if (tls_serialization_float_format) | |||
| { | |||
| free(tls_serialization_float_format); | |||
| @@ -775,7 +775,7 @@ static int json_object_double_to_json_string_format(struct json_object* jso, | |||
| { | |||
| const char *std_format = "%.17g"; | |||
| #ifdef HAVE___THREAD | |||
| #if defined(HAVE___THREAD) && defined(ENABLE_THREADING) | |||
| if (tls_serialization_float_format) | |||
| std_format = tls_serialization_float_format; | |||
| else | |||