From fad5928f1cc150b947eee4c477e1676892b5f479 Mon Sep 17 00:00:00 2001 From: Sebastian Ramacher Date: Fri, 5 Jul 2013 15:26:12 +0200 Subject: [PATCH] Use pthread_once to call bindtextdomain only once Calling bindtextdomain everytime in discid_new incurs a little overhead. If pthread is available, we can ensure with pthread_once that bindtextdomain is called exactly once. The autoconf function AX_PTHREADS is available from autoconf-archive. In cmake FIND_LIBRARY(Threads) is used to find pthread. Signed-off-by: Sebastian Ramacher --- CMakeLists.txt | 19 +++++++++++++++++++ config-cmake.h.in | 3 +++ configure.ac | 8 ++++++++ src/disc.c | 17 ++++++++++++++++- 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e44a268..152dffa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,25 @@ ENDIF() STRING(REPLACE ";" " " libdiscid_OSDEP_STR "${libdiscid_OSDEP_SRCS}") MESSAGE(STATUS "Using discid implementation ${libdiscid_OSDEP_STR}") +# check if pthread is available +IF(ENABLE_NLS) + SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) + IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER MATCHES "clang") + # FIND_PACKAGE(Threads) prefers -lpthread over -pthread, -pthread is + # recommend though + SET(THREADS_HAVE_PTHREAD_ARG "-pthread") + ENDIF() + FIND_PACKAGE(Threads) + IF(CMAKE_USE_PTHREADS_INIT) + SET(HAVE_PTHREAD TRUE) + SET(libdiscid_LIBS ${LIBDISCID_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + IF(${CMAKE_THREAD_LIBS_INIT} MATCHES "-pthread") + # if we have -pthread, also pass -pthread to CC + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") + ENDIF() + ENDIF() +ENDIF() + ADD_LIBRARY(libdiscid SHARED ${libdiscid_OSDEP_SRCS} ${libdiscid_RCS} src/base64.c src/disc.c src/sha1.c) TARGET_LINK_LIBRARIES(libdiscid ${libdiscid_OSDEP_LIBS} ${libdiscid_LIBS}) SET_TARGET_PROPERTIES(libdiscid PROPERTIES diff --git a/config-cmake.h.in b/config-cmake.h.in index 6d00d21..96fc0d9 100644 --- a/config-cmake.h.in +++ b/config-cmake.h.in @@ -12,6 +12,9 @@ /* enable string translation (gettext) */ #cmakedefine ENABLE_NLS +/* pthread is available */ +#cmakedefine HAVE_PTHREAD + /** * Values needed by our sha1.h */ diff --git a/configure.ac b/configure.ac index 7e4877a..9948625 100644 --- a/configure.ac +++ b/configure.ac @@ -87,6 +87,14 @@ AC_CHECK_SIZEOF(long) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION(0.18.1) +if test "$USE_NLS" = "yes"; then + AX_PTHREAD([ + AC_DEFINE(HAVE_PTHREAD, [], "pthread is available") + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CLAFGS $PTHREAD_CFLAGS" + CC="$PTHREAD_CC" + ]) +fi if test "$cross_compiling" = "yes" && test "$os" = "win32"; then AC_MSG_WARN([detected cross compilation: disabling tests!!!]) diff --git a/src/disc.c b/src/disc.c index 9dce8af..eb08a6b 100644 --- a/src/disc.c +++ b/src/disc.c @@ -43,6 +43,17 @@ #define TRACK_NUM_IS_VALID(disc, i) \ ( i >= disc->first_track_num && i <= disc->last_track_num ) +#ifdef ENABLE_NLS +static void init_nls(void) { + bindtextdomain(PACKAGE, LOCALEDIR); +} + +#ifdef HAVE_PTHREAD +#include +static pthread_once_t nls_initialized = PTHREAD_ONCE_INIT; +#endif +#endif + static void create_disc_id(mb_disc_private *d, char buf[]); static void create_freedb_disc_id(mb_disc_private *d, char buf[]); @@ -61,7 +72,11 @@ DiscId *discid_new() { * just in case the prefix was set weird */ #ifdef ENABLE_NLS - bindtextdomain(PACKAGE, LOCALEDIR); +#ifdef HAVE_PTHREAD + pthread_once(&nls_initialized, init_nls); +#else + init_nls(); +#endif #endif printf(_("one two three\n")); /* initializes everything to zero */