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,36 +172,28 @@ 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
|
||||
orig_start = threading.Thread.start
|
||||
import threading
|
||||
|
||||
def new_start(self):
|
||||
orig_start(self)
|
||||
try:
|
||||
orig_start = threading.Thread.start
|
||||
|
||||
def new_start(self):
|
||||
orig_start(self)
|
||||
try:
|
||||
name = self.name
|
||||
if not name or name.startswith('Thread-'):
|
||||
name = self.__class__.__name__
|
||||
if name == 'Thread':
|
||||
name = self.name
|
||||
if not name or name.startswith('Thread-'):
|
||||
name = self.__class__.__name__
|
||||
if name == 'Thread':
|
||||
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])
|
||||
except Exception:
|
||||
pass # Don't care about failure to set name
|
||||
threading.Thread.start = new_start
|
||||
if name:
|
||||
if isinstance(name, unicode):
|
||||
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
|
||||
|
||||
|
||||
def test_lopen():
|
||||
|
@ -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>
|
||||
@ -42,7 +44,7 @@ speedup_parse_date(PyObject *self, PyObject *args) {
|
||||
year = strtol(raw, &end, 10);
|
||||
if ((end - raw) != 4) Py_RETURN_NONE;
|
||||
raw += 5;
|
||||
|
||||
|
||||
|
||||
month = strtol(raw, &end, 10);
|
||||
if ((end - raw) != 2) Py_RETURN_NONE;
|
||||
@ -51,7 +53,7 @@ speedup_parse_date(PyObject *self, PyObject *args) {
|
||||
day = strtol(raw, &end, 10);
|
||||
if ((end - raw) != 2) Py_RETURN_NONE;
|
||||
raw += 3;
|
||||
|
||||
|
||||
hour = strtol(raw, &end, 10);
|
||||
if ((end - raw) != 2) Py_RETURN_NONE;
|
||||
raw += 3;
|
||||
@ -88,7 +90,7 @@ static PyObject*
|
||||
speedup_pdf_float(PyObject *self, PyObject *args) {
|
||||
double f = 0.0, a = 0.0;
|
||||
char *buf = "0", *dot;
|
||||
void *free_buf = NULL;
|
||||
void *free_buf = NULL;
|
||||
int precision = 6, l = 0;
|
||||
PyObject *ret;
|
||||
|
||||
@ -215,7 +217,7 @@ speedup_create_texture(PyObject *self, PyObject *args, PyObject *kw) {
|
||||
}
|
||||
}
|
||||
|
||||
// Create the texture in PPM (P6) format
|
||||
// Create the texture in PPM (P6) format
|
||||
memcpy(ppm, header, strlen(header));
|
||||
t = ppm + strlen(header);
|
||||
for (i = 0, j = 0; j < width * height; i += 3, j += 1) {
|
||||
@ -340,7 +342,7 @@ clean_xml_chars(PyObject *self, PyObject *text) {
|
||||
for (; i < PyUnicode_GET_SIZE(text); i++) {
|
||||
ch = PyUnicode_AS_UNICODE(text)[i];
|
||||
#ifdef Py_UNICODE_WIDE
|
||||
if ((0x20 <= ch && ch <= 0xd7ff && ch != 0x7f) || ch == 9 || ch == 10 || ch == 13 || (0xe000 <= ch && ch <= 0xfffd) || (0xffff < ch && ch <= 0x10ffff))
|
||||
if ((0x20 <= ch && ch <= 0xd7ff && ch != 0x7f) || ch == 9 || ch == 10 || ch == 13 || (0xe000 <= ch && ch <= 0xfffd) || (0xffff < ch && ch <= 0x10ffff))
|
||||
buf[j++] = ch;
|
||||
#else
|
||||
if ((0x20 <= ch && ch <= 0xd7ff && ch != 0x7f) || ch == 9 || ch == 10 || ch == 13 || (0xd000 <= ch && ch <= 0xfffd)) {
|
||||
@ -349,7 +351,7 @@ clean_xml_chars(PyObject *self, PyObject *text) {
|
||||
if (ch <= 0xdbff && i + 1 < PyUnicode_GET_SIZE(text) && 0xdc00 <= PyUnicode_AS_UNICODE(text)[i + 1] && PyUnicode_AS_UNICODE(text)[i+1] <= 0xdfff) {
|
||||
buf[j++] = ch; buf[j++] = PyUnicode_AS_UNICODE(text)[++i];
|
||||
}
|
||||
} else
|
||||
} else
|
||||
buf[j++] = ch;
|
||||
}
|
||||
#endif
|
||||
@ -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