Skip to content

Commit

Permalink
Merge pull request #2420 from JuhaSointusalo/mgr-per-thread-locale
Browse files Browse the repository at this point in the history
 lib, mgr: use per-thread locale on Linux
  • Loading branch information
CharlieFenton authored and Kevin Reed committed Apr 2, 2018
1 parent 78bd561 commit 899d76e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 105 deletions.
33 changes: 12 additions & 21 deletions clientgui/AsyncRPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#pragma implementation "AsyncRPC.h"
#endif

#ifdef _WIN32
#include "boinc_win.h"
#endif
#include "config.h"

#if HAVE_XLOCALE_H
#include <xlocale.h>
#endif
Expand Down Expand Up @@ -137,25 +142,16 @@ void *RPCThread::Entry() {
wxMutexError mutexErr = wxMUTEX_NO_ERROR;
wxCondError condErr = wxCOND_NO_ERROR;

#ifndef NO_PER_THREAD_LOCALE
#ifdef __WXMSW__
// On Windows, set all locales for this thread on a per-thread basis
#ifdef HAVE__CONFIGTHREADLOCALE
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
setlocale(LC_ALL, "C");
#else
// We initialize RPC_Thread_Locale to fix a compiler warning
locale_t RPC_Thread_Locale = LC_GLOBAL_LOCALE;
#if defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
if (uselocale) // uselocale() is not available in Mac OS 10.3.9
#elif defined(HAVE_USELOCALE)
locale_t RPC_Thread_Locale = newlocale(LC_ALL_MASK, "C", (locale_t) 0);
uselocale(RPC_Thread_Locale);
#endif
{
// On Mac / Unix / Linux, set "C" locale for this thread only
RPC_Thread_Locale = newlocale(LC_ALL_MASK, "C", NULL);
uselocale(RPC_Thread_Locale);
}
#endif // ifndef __WXMSW__
#endif // ifndef NO_PER_THREAD_LOCALE



m_pRPC_Thread_Mutex->Lock();
m_pDoc->m_bRPCThreadIsReady = true;
while(true) {
Expand All @@ -167,14 +163,9 @@ void *RPCThread::Entry() {
wxASSERT(condErr == wxCOND_NO_ERROR);

if (m_pDoc->m_bShutDownRPCThread) {
#if !defined(NO_PER_THREAD_LOCALE) && !defined(__WXMSW__)
#if defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
if (uselocale) // uselocale() is not available in Mac OS 10.3.9
#endif
{
#ifdef HAVE_USELOCALE
uselocale(LC_GLOBAL_LOCALE);
freelocale(RPC_Thread_Locale);
}
#endif
m_pRPC_Thread_Mutex->Unlock(); // Just for safety - not really needed
// Tell CMainDocument that thread has gracefully ended
Expand Down
3 changes: 0 additions & 3 deletions clientgui/DlgDiagnosticLogFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "BOINCBaseFrame.h"
#include "Events.h"
#include "error_numbers.h"
#include "gui_rpc_client.h" // For SET_LOCALE
#include "SkinManager.h"


Expand Down Expand Up @@ -156,7 +155,6 @@ CDlgDiagnosticLogFlags::~CDlgDiagnosticLogFlags() {


void CDlgDiagnosticLogFlags::CreateCheckboxes() {
SET_LOCALE sl;
char buf[64000];
MIOFILE mf;
bool val;
Expand Down Expand Up @@ -196,7 +194,6 @@ void CDlgDiagnosticLogFlags::CreateCheckboxes() {
}

void CDlgDiagnosticLogFlags::SaveFlags() {
SET_LOCALE sl;
char buf[64000];
MIOFILE mf;
bool val;
Expand Down
3 changes: 3 additions & 0 deletions clientgui/mac/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* Define to 1 if you have the `uselocale' function. */
#define HAVE_USELOCALE 1

/* Define to 1 if you have the <utmp.h> header file. */
#define HAVE_UTMP_H 1

Expand Down
22 changes: 4 additions & 18 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ else
echo "DEBUG: GLUT_CFLAGS = $GLUT_CFLAGS" >&5
echo "DEBUG: GLUT_LIBS = $GLUT_LIBS" >&5

AC_CHECK_HEADERS([gl.h glu.h glut.h glaux.h GL/gl.h GL/glu.h GL/glut.h GL/glaux.h OpenGL/gl.h OpenGL/glu.h OpenGL/glut.h OpenGL/glaux.h GLUT/glut.h MesaGL/gl.h MesaGL/glu.h MesaGL/glut.h MesaGL/glaux.h libnotify/notify.h gtk/gtk.h locale.h xlocale.h])
AC_CHECK_HEADERS([gl.h glu.h glut.h glaux.h GL/gl.h GL/glu.h GL/glut.h GL/glaux.h OpenGL/gl.h OpenGL/glu.h OpenGL/glut.h OpenGL/glaux.h GLUT/glut.h MesaGL/gl.h MesaGL/glu.h MesaGL/glut.h MesaGL/glaux.h libnotify/notify.h gtk/gtk.h])

AC_CHECK_LIB([jpeg], [jpeg_start_compress],[have_jpeg=1],[have_jpeg=0])
AC_CHECK_HEADER([jpeglib.h],[have_jpeg=1],[have_jpeg=0])
Expand Down Expand Up @@ -638,14 +638,6 @@ AH_TOP([
])
AH_BOTTOM([
#if !HAVE_DECL__CONFIGTHREADLOCALE
#define NO_PER_THREAD_LOCALE 1
#undef HAVE__CONFIGTHREADLOCALE
#else
#undef NO_PER_THREAD_LOCALE
#define HAVE__CONFIGTHREADLOCALE 1
#endif
#ifndef HAVE_RES_INIT
#define res_init() (0)
#endif
Expand All @@ -666,7 +658,7 @@ AC_TYPE_SIGNAL
if test "${isWIN32}" = "yes" ; then
AC_CHECK_HEADERS(winsock2.h winsock.h windows.h ws2tcpip.h winternl.h crtdbg.h)
fi
AC_CHECK_HEADERS(sys/types.h sys/un.h arpa/inet.h dirent.h grp.h fcntl.h inttypes.h stdint.h memory.h netdb.h netinet/in.h netinet/tcp.h netinet/ether.h net/if.h net/if_arp.h signal.h strings.h sys/auxv.h sys/file.h sys/fcntl.h sys/ipc.h sys/ioctl.h sys/msg.h sys/param.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/socket.h sys/stat.h sys/statvfs.h sys/statfs.h sys/systeminfo.h sys/time.h sys/types.h sys/utsname.h sys/vmmeter.h sys/wait.h unistd.h utmp.h errno.h procfs.h ieeefp.h setjmp.h float.h sal.h execinfo.h)
AC_CHECK_HEADERS([sys/types.h sys/un.h arpa/inet.h dirent.h grp.h fcntl.h inttypes.h stdint.h memory.h netdb.h netinet/in.h netinet/tcp.h netinet/ether.h net/if.h net/if_arp.h signal.h strings.h sys/auxv.h sys/file.h sys/fcntl.h sys/ipc.h sys/ioctl.h sys/msg.h sys/param.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/socket.h sys/stat.h sys/statvfs.h sys/statfs.h sys/systeminfo.h sys/time.h sys/types.h sys/utsname.h sys/vmmeter.h sys/wait.h unistd.h utmp.h errno.h procfs.h ieeefp.h setjmp.h float.h sal.h execinfo.h xlocale.h])

save_cxxflags="${CXXFLAGS}"
save_cppflags="${CPPFLAGS}"
Expand Down Expand Up @@ -924,9 +916,9 @@ AC_LANG_POP
dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(ether_ntoa setpriority sched_setscheduler strlcpy strlcat strcasestr strcasecmp sigaction getutent setutent getisax strdup _strdup strdupa _strdupa daemon stat64 putenv setenv unsetenv res_init strtoull localtime localtime_r gmtime gmtime_r)
AC_CHECK_FUNCS([ether_ntoa setpriority sched_setscheduler strlcpy strlcat strcasestr strcasecmp sigaction getutent setutent getisax strdup _strdup strdupa _strdupa daemon stat64 putenv setenv unsetenv res_init strtoull localtime localtime_r gmtime gmtime_r uselocale _configthreadlocale])

AC_CHECK_DECLS([_fpreset, fpreset, _configthreadlocale],
AC_CHECK_DECLS([_fpreset, fpreset],
[],[],[[
#include <stdio.h>
#if HAVE_SYS_TYPES_H
Expand Down Expand Up @@ -973,12 +965,6 @@ AC_CHECK_DECLS([_fpreset, fpreset, _configthreadlocale],
#ifdef HAVE_MATH_H
#include <math.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
]])

dnl Checks for typedefs, structures, and compiler characteristics.
Expand Down
2 changes: 0 additions & 2 deletions lib/boinc_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@
#define HAVE_DECL__FPRESET 1
#define HAVE_DECL___CPUID 1
#define HAVE_MSVCRT 1
#undef NO_PER_THREAD_LOCALE
#define HAVE_DECL__CONFIGTHREADLOCALE 1
#define HAVE__CONFIGTHREADLOCALE 1
#define HAVE_DECL___CPUID 1

Expand Down
78 changes: 17 additions & 61 deletions lib/gui_rpc_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
#ifndef BOINC_GUI_RPC_CLIENT_H
#define BOINC_GUI_RPC_CLIENT_H

#ifdef _WIN32
#include "boinc_win.h"
#endif
#include "config.h"

#if !defined(_WIN32) || defined (__CYGWIN__)
#include <cstdio>
#include <string>
Expand All @@ -30,9 +35,10 @@
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <locale.h>
#endif

#include <locale.h>

#include <deque>

#include "cc_config.h"
Expand Down Expand Up @@ -773,73 +779,23 @@ struct RPC {
int parse_reply();
};

// We recommend using the XCode project under OS 10.5 to compile
// the BOINC library, but some projects still use config & make,
// so the following compatibility code avoids compiler errors when
// building libboinc.a using config & make on system OS 10.3.9 or
// with the OS 10.3.9 SDK (but using config & make is not recommended.)
//
#if defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) && (!defined(BUILDING_MANAGER))
#define NO_PER_THREAD_LOCALE 1
#endif

// uselocal() API should be available on UNIX, Fedora & Ubuntu.
// For any platforms which do not support setting locale on a
// per-thread basis, add code here similar to the following sample:
//#if defined(__UNIVAC__)
//#define NO_PER_THREAD_LOCALE 1
//#endif
#if defined(__HAIKU__)
#define NO_PER_THREAD_LOCALE 1
#endif


#ifdef NO_PER_THREAD_LOCALE
// Use this code for any platforms which do not support
// setting locale on a per-thread basis (see comment above)
struct SET_LOCALE {
std::string locale;
inline SET_LOCALE() {
locale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "C");
}
inline ~SET_LOCALE() {
setlocale(LC_ALL, locale.c_str());
}
};

#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
// uselocale() is not available in OS 10.3.9 so use weak linking
#if HAVE_XLOCALE_H
#include <xlocale.h>
#endif
extern int freelocale(locale_t) __attribute__((weak_import));
extern locale_t newlocale(int, __const char *, locale_t) __attribute__((weak_import));
extern locale_t uselocale(locale_t) __attribute__((weak_import));

#if defined(HAVE__CONFIGTHREADLOCALE) || defined(HAVE_USELOCALE)
// no-op, the calling thread is already set to use C locale
struct SET_LOCALE {
locale_t old_locale, RPC_locale;
std::string locale;
inline SET_LOCALE() {
if (uselocale == NULL) {
locale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "C");
}
}
inline ~SET_LOCALE() {
if (uselocale == NULL) {
setlocale(LC_ALL, locale.c_str());
}
}
SET_LOCALE() {}
~SET_LOCALE() {}
};

#else

struct SET_LOCALE {
// Don't need to juggle locales if we have per-thread locale
inline SET_LOCALE() {
std::string old_locale;
SET_LOCALE() {
old_locale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "C");
}
inline ~SET_LOCALE() {
~SET_LOCALE() {
setlocale(LC_ALL, old_locale.c_str());
}
};
#endif
Expand Down

0 comments on commit 899d76e

Please sign in to comment.