mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use native code for setting thread names
Fixes #924 (Fixed exception not caught in Startup.py thrown by "pthread_setname_np" on Linux)
This commit is contained in:
parent
57a68ad841
commit
0bd223a88a
@ -17,7 +17,7 @@ __builtin__.__dict__['_'] = lambda s: s
|
||||
# immediately translated to the environment language
|
||||
__builtin__.__dict__['__'] = lambda s: s
|
||||
|
||||
from calibre.constants import iswindows, preferred_encoding, plugins, isosx, islinux, isfrozen, DEBUG
|
||||
from calibre.constants import iswindows, preferred_encoding, plugins, isosx, islinux, isfrozen, DEBUG, isfreebsd
|
||||
|
||||
_run_once = False
|
||||
winutil = winutilerror = None
|
||||
@ -172,17 +172,11 @@ if not _run_once:
|
||||
bound_signal.connect(slot, **kw)
|
||||
__builtin__.__dict__['connect_lambda'] = connect_lambda
|
||||
|
||||
if islinux:
|
||||
if islinux or isosx or isfreebsd:
|
||||
# Name all threads at the OS level created using the threading module, see
|
||||
# http://bugs.python.org/issue15500
|
||||
import ctypes, ctypes.util, threading
|
||||
libpthread_path = ctypes.util.find_library("pthread")
|
||||
if libpthread_path:
|
||||
libpthread = ctypes.CDLL(libpthread_path)
|
||||
if hasattr(libpthread, "pthread_setname_np"):
|
||||
pthread_setname_np = libpthread.pthread_setname_np
|
||||
pthread_setname_np.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
|
||||
pthread_setname_np.restype = ctypes.c_int
|
||||
import threading
|
||||
|
||||
orig_start = threading.Thread.start
|
||||
|
||||
def new_start(self):
|
||||
@ -195,10 +189,8 @@ if not _run_once:
|
||||
name = self.name
|
||||
if name:
|
||||
if isinstance(name, unicode):
|
||||
name = name.encode('ascii', 'replace')
|
||||
ident = getattr(self, "ident", None)
|
||||
if ident is not None:
|
||||
pthread_setname_np(ident, name[:15])
|
||||
name = name.encode('ascii', 'replace').decode('ascii')
|
||||
plugins['speedup'][0].set_thread_name(name[:15])
|
||||
except Exception:
|
||||
pass # Don't care about failure to set name
|
||||
threading.Thread.start = new_start
|
||||
|
@ -1,10 +1,12 @@
|
||||
#define UNICODE
|
||||
#include <Python.h>
|
||||
#include <datetime.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
@ -490,6 +492,48 @@ speedup_iso_8601(PyObject *self, PyObject *args) {
|
||||
return Py_BuildValue("NOi", PyDateTime_FromDateAndTime(year, month, day, hour, minute, second, usecond), (tzhour == 1000) ? Py_False : Py_True, tzsign*60*(tzhour*60 + tzminute));
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#define FREEBSD_SET_NAME
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
// I cant figure out how to get pthread.h to include this definition on macOS. MACOSX_DEPLOYMENT_TARGET does not work.
|
||||
extern int pthread_setname_np(const char *name);
|
||||
#elif defined(FREEBSD_SET_NAME)
|
||||
// Function has a different name on FreeBSD
|
||||
void pthread_set_name_np(pthread_t tid, const char *name);
|
||||
#else
|
||||
// Need _GNU_SOURCE for pthread_setname_np on linux and that causes other issues on systems with old glibc
|
||||
extern int pthread_setname_np(pthread_t, const char *name);
|
||||
#endif
|
||||
|
||||
|
||||
static PyObject*
|
||||
set_thread_name(PyObject *self, PyObject *args) {
|
||||
(void)(self); (void)(args);
|
||||
#if defined(_MSC_VER)
|
||||
PyErr_SetString(PyExc_OSError, "Setting thread names not supported on windows");
|
||||
return NULL;
|
||||
#else
|
||||
char *name;
|
||||
int ret;
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) return NULL;
|
||||
while (1) {
|
||||
errno = 0;
|
||||
#if defined(__APPLE__)
|
||||
ret = pthread_setname_np(name);
|
||||
#elif defined(FREEBSD_SET_NAME)
|
||||
pthread_set_name_np(pthread_self(), name);
|
||||
ret = 0;
|
||||
#else
|
||||
ret = pthread_setname_np(pthread_self(), name);
|
||||
#endif
|
||||
if (ret != 0 && (errno == EINTR || errno == EAGAIN)) continue;
|
||||
break;
|
||||
}
|
||||
if (ret != 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; }
|
||||
Py_RETURN_NONE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static PyMethodDef speedup_methods[] = {
|
||||
{"parse_date", speedup_parse_date, METH_VARARGS,
|
||||
@ -534,6 +578,10 @@ static PyMethodDef speedup_methods[] = {
|
||||
"clean_xml_chars(unicode_object)\n\nRemove codepoints in unicode_object that are not allowed in XML"
|
||||
},
|
||||
|
||||
{"set_thread_name", set_thread_name, METH_VARARGS,
|
||||
"set_thread_name(name)\n\nWrapper for pthread_setname_np"
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user