Merge pull request #2420 from JuhaSointusalo/mgr-per-thread-locale

lib, mgr: use per-thread locale on Linux
This commit is contained in:
CharlieFenton 2018-03-29 02:16:31 -07:00 committed by GitHub
commit 1c38628f95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 105 deletions

View File

@ -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
@ -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) {
@ -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

View File

@ -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"
@ -156,7 +155,6 @@ CDlgDiagnosticLogFlags::~CDlgDiagnosticLogFlags() {
void CDlgDiagnosticLogFlags::CreateCheckboxes() {
SET_LOCALE sl;
char buf[64000];
MIOFILE mf;
bool val;
@ -196,7 +194,6 @@ void CDlgDiagnosticLogFlags::CreateCheckboxes() {
}
void CDlgDiagnosticLogFlags::SaveFlags() {
SET_LOCALE sl;
char buf[64000];
MIOFILE mf;
bool val;

View File

@ -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

View File

@ -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])
@ -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
@ -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}"
@ -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
@ -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.

View File

@ -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

View File

@ -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>
@ -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"
@ -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