You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by dc...@apache.org on 2012/05/20 16:24:20 UTC
svn commit: r1340735 - in /avro/trunk: CHANGES.txt lang/c/CMakeLists.txt
lang/c/INSTALL lang/c/README.maintaining_win32.txt
lang/c/src/CMakeLists.txt lang/c/src/errors.c
Author: dcreager
Date: Sun May 20 14:24:19 2012
New Revision: 1340735
URL: http://svn.apache.org/viewvc?rev=1340735&view=rev
Log:
AVRO-1092. C: Thread-safe versions of error handling code.
We now provide optional thread-safe versions of the error managing code
on Unix. (Only on Unix for now, because we rely on pthread's
thread-local storage API.) You can ask for thread-safe versions by
defining the THREADSAFE cmake variable.
Contributed by Pugachev Maxim; Windows compatibility added by Vivek
Nadkarni.
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/c/CMakeLists.txt
avro/trunk/lang/c/INSTALL
avro/trunk/lang/c/README.maintaining_win32.txt
avro/trunk/lang/c/src/CMakeLists.txt
avro/trunk/lang/c/src/errors.c
Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1340735&r1=1340734&r2=1340735&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Sun May 20 14:24:19 2012
@@ -104,6 +104,9 @@ Avro 1.7.0 (unreleased)
AVRO-1088. C: Performance tests for arrays and schema resolution.
(Vivek Nadkarni via dcreager)
+ AVRO-1092. C: Error management code can be defined in a thread-safe
+ manner. (Pugachev Maxim and Vivek Nadkarni via dcreager)
+
Avro 1.6.3 (5 March 2012)
AVRO-1077. Missing 'inline' for union set function. (thiru)
Modified: avro/trunk/lang/c/CMakeLists.txt
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/CMakeLists.txt?rev=1340735&r1=1340734&r2=1340735&view=diff
==============================================================================
--- avro/trunk/lang/c/CMakeLists.txt (original)
+++ avro/trunk/lang/c/CMakeLists.txt Sun May 20 14:24:19 2012
@@ -106,6 +106,20 @@ endif(WIN32)
# Uncomment to allow non-atomic increment/decrement of reference count
# add_definitions(-DAVRO_ALLOW_NON_ATOMIC_REFCOUNT)
+# Thread support (only for *nix with pthreads)
+set(THREADS_LIBRARIES)
+if(UNIX AND THREADSAFE AND CMAKE_COMPILER_IS_GNUCC)
+ set(CMAKE_THREAD_PREFER_PTHREAD)
+ find_package(Threads)
+
+ if(NOT CMAKE_USE_PTHREADS_INIT)
+ message(FATAL_ERROR "pthreads not found")
+ endif(NOT CMAKE_USE_PTHREADS_INIT)
+
+ add_definitions(-DTHREADSAFE -D_REENTRANT)
+ set(THREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+endif(UNIX AND THREADSAFE AND CMAKE_COMPILER_IS_GNUCC)
+
include_directories(${AvroC_SOURCE_DIR}/src)
include_directories(${AvroC_SOURCE_DIR}/jansson/src)
Modified: avro/trunk/lang/c/INSTALL
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/INSTALL?rev=1340735&r1=1340734&r2=1340735&view=diff
==============================================================================
--- avro/trunk/lang/c/INSTALL (original)
+++ avro/trunk/lang/c/INSTALL Sun May 20 14:24:19 2012
@@ -55,3 +55,9 @@ like the following:
to the cmake command given above. The set of architectures that you can
choose from differs depending on which version of OS X you're running;
common possibilities include "i386", "x86_64", "ppc", and "ppc64".
+
+On Unix, you can request thread-safe versions of the Avro library's
+global functions by defining the THREADSAFE cmake variable. Just add
+the following to your cmake invokation:
+
+ -DTHREADSAFE=true
Modified: avro/trunk/lang/c/README.maintaining_win32.txt
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/README.maintaining_win32.txt?rev=1340735&r1=1340734&r2=1340735&view=diff
==============================================================================
--- avro/trunk/lang/c/README.maintaining_win32.txt (original)
+++ avro/trunk/lang/c/README.maintaining_win32.txt Sun May 20 14:24:19 2012
@@ -152,3 +152,15 @@ Instructions for Maintenance
changes in st.c and st.h -- which were converted to new-style
function declarations.
+19. Structures cannot be initialized using the .element notation for
+ Win32. For example if we have a struct test_t:
+ typedef struct
+ {
+ int a;
+ int b;
+ } test_t;
+ Then we can initialize the struct using the syntax:
+ test_t t1 = { 0, 0 };
+ But we cannot use the syntax:
+ test_t t2 = { .a = 0, . b = 0 };
+ because Win32 does not support it.
Modified: avro/trunk/lang/c/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/CMakeLists.txt?rev=1340735&r1=1340734&r2=1340735&view=diff
==============================================================================
--- avro/trunk/lang/c/src/CMakeLists.txt (original)
+++ avro/trunk/lang/c/src/CMakeLists.txt Sun May 20 14:24:19 2012
@@ -102,13 +102,13 @@ source_group(Jansson FILES ${JANSSON_SRC
string(REPLACE ":" "." LIBAVRO_DOT_VERSION ${LIBAVRO_VERSION})
add_library(avro-static STATIC ${AVRO_SRC} ${JANSSON_SRC})
-target_link_libraries(avro-static ${CODEC_LIBRARIES})
+target_link_libraries(avro-static ${CODEC_LIBRARIES} ${THREADS_LIBRARIES})
set_target_properties(avro-static PROPERTIES OUTPUT_NAME avro)
if (NOT WIN32)
# TODO: Create Windows DLLs. See http://www.cmake.org/Wiki/BuildingWinDLL
add_library(avro-shared SHARED ${AVRO_SRC} ${JANSSON_SRC})
-target_link_libraries(avro-shared ${CODEC_LIBRARIES})
+target_link_libraries(avro-shared ${CODEC_LIBRARIES} ${THREADS_LIBRARIES})
set_target_properties(avro-shared PROPERTIES
OUTPUT_NAME avro
SOVERSION ${LIBAVRO_DOT_VERSION})
Modified: avro/trunk/lang/c/src/errors.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/errors.c?rev=1340735&r1=1340734&r2=1340735&view=diff
==============================================================================
--- avro/trunk/lang/c/src/errors.c (original)
+++ avro/trunk/lang/c/src/errors.c Sun May 20 14:24:19 2012
@@ -18,9 +18,21 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "avro/errors.h"
+#if defined THREADSAFE && (defined __unix__ || defined __unix)
+#include <pthread.h>
+static pthread_key_t error_data_key;
+static pthread_once_t error_data_key_once = PTHREAD_ONCE_INIT;
+
+static void make_error_data_key()
+{
+ pthread_key_create(&error_data_key, free);
+}
+#endif
+
/* 4K should be enough, right? */
#define AVRO_ERROR_SIZE 4096
@@ -31,11 +43,46 @@
* buffer, and then swaps them.
*/
-static char AVRO_ERROR1[AVRO_ERROR_SIZE] = {'\0'};
-static char AVRO_ERROR2[AVRO_ERROR_SIZE] = {'\0'};
+struct avro_error_data_t {
+ char AVRO_ERROR1[AVRO_ERROR_SIZE];
+ char AVRO_ERROR2[AVRO_ERROR_SIZE];
+
+ char *AVRO_CURRENT_ERROR;
+ char *AVRO_OTHER_ERROR;
+};
+
-static char *AVRO_CURRENT_ERROR = AVRO_ERROR1;
-static char *AVRO_OTHER_ERROR = AVRO_ERROR2;
+static struct avro_error_data_t *
+avro_get_error_data(void)
+{
+#if defined THREADSAFE && (defined __unix__ || defined __unix)
+ pthread_once(&error_data_key_once, make_error_data_key);
+
+ struct avro_error_data_t *ERROR_DATA =
+ (struct avro_error_data_t*) pthread_getspecific(error_data_key);
+
+ if (!ERROR_DATA) {
+ ERROR_DATA = (struct avro_error_data_t*) malloc(sizeof(struct avro_error_data_t));
+ pthread_setspecific(error_data_key, ERROR_DATA);
+
+ ERROR_DATA->AVRO_ERROR1[0] = '\0';
+ ERROR_DATA->AVRO_ERROR2[0] = '\0';
+ ERROR_DATA->AVRO_CURRENT_ERROR = ERROR_DATA->AVRO_ERROR1;
+ ERROR_DATA->AVRO_OTHER_ERROR = ERROR_DATA->AVRO_ERROR2;
+ }
+
+ return ERROR_DATA;
+#else
+ static struct avro_error_data_t ERROR_DATA = {
+ /* .AVRO_ERROR1 = */ {'\0'},
+ /* .AVRO_ERROR2 = */ {'\0'},
+ /* .AVRO_CURRENT_ERROR = */ ERROR_DATA.AVRO_ERROR1,
+ /* .AVRO_OTHER_ERROR = */ ERROR_DATA.AVRO_ERROR2,
+ };
+
+ return &ERROR_DATA;
+#endif
+}
void
@@ -43,7 +90,7 @@ avro_set_error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- vsnprintf(AVRO_CURRENT_ERROR, AVRO_ERROR_SIZE, fmt, args);
+ vsnprintf(avro_get_error_data()->AVRO_CURRENT_ERROR, AVRO_ERROR_SIZE, fmt, args);
va_end(args);
//fprintf(stderr, "--- %s\n", AVRO_CURRENT_ERROR);
}
@@ -52,13 +99,15 @@ avro_set_error(const char *fmt, ...)
void
avro_prefix_error(const char *fmt, ...)
{
+ struct avro_error_data_t *ERROR_DATA = avro_get_error_data();
+
/*
* First render the prefix into OTHER_ERROR.
*/
va_list args;
va_start(args, fmt);
- int bytes_written = vsnprintf(AVRO_OTHER_ERROR, AVRO_ERROR_SIZE, fmt, args);
+ int bytes_written = vsnprintf(ERROR_DATA->AVRO_OTHER_ERROR, AVRO_ERROR_SIZE, fmt, args);
va_end(args);
/*
@@ -66,9 +115,9 @@ avro_prefix_error(const char *fmt, ...)
*/
if (bytes_written < AVRO_ERROR_SIZE) {
- strncpy(&AVRO_OTHER_ERROR[bytes_written], AVRO_CURRENT_ERROR,
+ strncpy(&ERROR_DATA->AVRO_OTHER_ERROR[bytes_written], ERROR_DATA->AVRO_CURRENT_ERROR,
AVRO_ERROR_SIZE - bytes_written);
- AVRO_OTHER_ERROR[AVRO_ERROR_SIZE-1] = '\0';
+ ERROR_DATA->AVRO_OTHER_ERROR[AVRO_ERROR_SIZE-1] = '\0';
}
/*
@@ -76,14 +125,14 @@ avro_prefix_error(const char *fmt, ...)
*/
char *tmp;
- tmp = AVRO_OTHER_ERROR;
- AVRO_OTHER_ERROR = AVRO_CURRENT_ERROR;
- AVRO_CURRENT_ERROR = tmp;
+ tmp = ERROR_DATA->AVRO_OTHER_ERROR;
+ ERROR_DATA->AVRO_OTHER_ERROR = ERROR_DATA->AVRO_CURRENT_ERROR;
+ ERROR_DATA->AVRO_CURRENT_ERROR = tmp;
//fprintf(stderr, "+++ %s\n", AVRO_CURRENT_ERROR);
}
const char *avro_strerror(void)
{
- return AVRO_CURRENT_ERROR;
+ return avro_get_error_data()->AVRO_CURRENT_ERROR;
}