mirror of
https://github.com/python/cpython.git
synced 2025-08-26 11:45:20 +00:00
bpo-6532: Make the thread id an unsigned integer. (#781)
* bpo-6532: Make the thread id an unsigned integer. From C API side the type of results of PyThread_start_new_thread() and PyThread_get_thread_ident(), the id parameter of PyThreadState_SetAsyncExc(), and the thread_id field of PyThreadState changed from "long" to "unsigned long". * Restore a check in thread_get_ident().
This commit is contained in:
parent
1e2147b9d7
commit
aefa7ebf0f
27 changed files with 116 additions and 88 deletions
|
@ -148,7 +148,7 @@ static long dxp[256];
|
|||
#include "pythread.h"
|
||||
|
||||
static PyThread_type_lock pending_lock = 0; /* for pending calls */
|
||||
static long main_thread = 0;
|
||||
static unsigned long main_thread = 0;
|
||||
/* This single variable consolidates all requests to break out of the fast path
|
||||
in the eval loop. */
|
||||
static _Py_atomic_int eval_breaker = {0};
|
||||
|
|
|
@ -147,14 +147,14 @@ _PyImportZip_Init(void)
|
|||
#include "pythread.h"
|
||||
|
||||
static PyThread_type_lock import_lock = 0;
|
||||
static long import_lock_thread = -1;
|
||||
static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID;
|
||||
static int import_lock_level = 0;
|
||||
|
||||
void
|
||||
_PyImport_AcquireLock(void)
|
||||
{
|
||||
long me = PyThread_get_thread_ident();
|
||||
if (me == -1)
|
||||
unsigned long me = PyThread_get_thread_ident();
|
||||
if (me == PYTHREAD_INVALID_THREAD_ID)
|
||||
return; /* Too bad */
|
||||
if (import_lock == NULL) {
|
||||
import_lock = PyThread_allocate_lock();
|
||||
|
@ -165,7 +165,8 @@ _PyImport_AcquireLock(void)
|
|||
import_lock_level++;
|
||||
return;
|
||||
}
|
||||
if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0))
|
||||
if (import_lock_thread != PYTHREAD_INVALID_THREAD_ID ||
|
||||
!PyThread_acquire_lock(import_lock, 0))
|
||||
{
|
||||
PyThreadState *tstate = PyEval_SaveThread();
|
||||
PyThread_acquire_lock(import_lock, 1);
|
||||
|
@ -179,15 +180,15 @@ _PyImport_AcquireLock(void)
|
|||
int
|
||||
_PyImport_ReleaseLock(void)
|
||||
{
|
||||
long me = PyThread_get_thread_ident();
|
||||
if (me == -1 || import_lock == NULL)
|
||||
unsigned long me = PyThread_get_thread_ident();
|
||||
if (me == PYTHREAD_INVALID_THREAD_ID || import_lock == NULL)
|
||||
return 0; /* Too bad */
|
||||
if (import_lock_thread != me)
|
||||
return -1;
|
||||
import_lock_level--;
|
||||
assert(import_lock_level >= 0);
|
||||
if (import_lock_level == 0) {
|
||||
import_lock_thread = -1;
|
||||
import_lock_thread = PYTHREAD_INVALID_THREAD_ID;
|
||||
PyThread_release_lock(import_lock);
|
||||
}
|
||||
return 1;
|
||||
|
@ -209,7 +210,7 @@ _PyImport_ReInitLock(void)
|
|||
}
|
||||
if (import_lock_level > 1) {
|
||||
/* Forked as a side effect of import */
|
||||
long me = PyThread_get_thread_ident();
|
||||
unsigned long me = PyThread_get_thread_ident();
|
||||
/* The following could fail if the lock is already held, but forking as
|
||||
a side-effect of an import is a) rare, b) nuts, and c) difficult to
|
||||
do thanks to the lock only being held when doing individual module
|
||||
|
@ -218,7 +219,7 @@ _PyImport_ReInitLock(void)
|
|||
import_lock_thread = me;
|
||||
import_lock_level--;
|
||||
} else {
|
||||
import_lock_thread = -1;
|
||||
import_lock_thread = PYTHREAD_INVALID_THREAD_ID;
|
||||
import_lock_level = 0;
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +239,7 @@ _imp_lock_held_impl(PyObject *module)
|
|||
/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
return PyBool_FromLong(import_lock_thread != -1);
|
||||
return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID);
|
||||
#else
|
||||
Py_RETURN_FALSE;
|
||||
#endif
|
||||
|
|
|
@ -580,7 +580,8 @@ PyThreadState_GetDict(void)
|
|||
existing async exception. This raises no exceptions. */
|
||||
|
||||
int
|
||||
PyThreadState_SetAsyncExc(long id, PyObject *exc) {
|
||||
PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
|
||||
{
|
||||
PyInterpreterState *interp = GET_INTERP_STATE();
|
||||
PyThreadState *p;
|
||||
|
||||
|
@ -668,7 +669,7 @@ _PyThread_CurrentFrames(void)
|
|||
struct _frame *frame = t->frame;
|
||||
if (frame == NULL)
|
||||
continue;
|
||||
id = PyLong_FromLong(t->thread_id);
|
||||
id = PyLong_FromUnsignedLong(t->thread_id);
|
||||
if (id == NULL)
|
||||
goto Fail;
|
||||
stat = PyDict_SetItem(result, id, (PyObject *)frame);
|
||||
|
|
|
@ -172,7 +172,7 @@ struct key {
|
|||
struct key *next;
|
||||
|
||||
/* The thread id, according to PyThread_get_thread_ident(). */
|
||||
long id;
|
||||
unsigned long id;
|
||||
|
||||
/* The key and its associated value. */
|
||||
int key;
|
||||
|
@ -208,7 +208,7 @@ static struct key *
|
|||
find_key(int set_value, int key, void *value)
|
||||
{
|
||||
struct key *p, *prev_p;
|
||||
long id = PyThread_get_thread_ident();
|
||||
unsigned long id = PyThread_get_thread_ident();
|
||||
|
||||
if (!keymutex)
|
||||
return NULL;
|
||||
|
@ -312,7 +312,7 @@ PyThread_get_key_value(int key)
|
|||
void
|
||||
PyThread_delete_key_value(int key)
|
||||
{
|
||||
long id = PyThread_get_thread_ident();
|
||||
unsigned long id = PyThread_get_thread_ident();
|
||||
struct key *p, **q;
|
||||
|
||||
PyThread_acquire_lock(keymutex, 1);
|
||||
|
@ -338,7 +338,7 @@ PyThread_delete_key_value(int key)
|
|||
void
|
||||
PyThread_ReInitTLS(void)
|
||||
{
|
||||
long id = PyThread_get_thread_ident();
|
||||
unsigned long id = PyThread_get_thread_ident();
|
||||
struct key *p, **q;
|
||||
|
||||
if (!keymutex)
|
||||
|
|
|
@ -9,7 +9,7 @@ PyThread__init_thread(void)
|
|||
/*
|
||||
* Thread support.
|
||||
*/
|
||||
long
|
||||
unsigned long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
int success = 0; /* init not needed when SOLARIS_THREADS and */
|
||||
|
@ -18,10 +18,10 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
return success < 0 ? -1 : 0;
|
||||
return success < 0 ? PYTHREAD_INVALID_THREAD_ID : 0;
|
||||
}
|
||||
|
||||
long
|
||||
unsigned long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
if (!initialized)
|
||||
|
|
|
@ -140,7 +140,7 @@ LeaveNonRecursiveMutex(PNRMUTEX mutex)
|
|||
}
|
||||
#endif /* _PY_USE_CV_LOCKS */
|
||||
|
||||
long PyThread_get_thread_ident(void);
|
||||
unsigned long PyThread_get_thread_ident(void);
|
||||
|
||||
/*
|
||||
* Initialization of the C package, should not be needed.
|
||||
|
@ -172,21 +172,21 @@ bootstrap(void *call)
|
|||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
unsigned long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
HANDLE hThread;
|
||||
unsigned threadID;
|
||||
callobj *obj;
|
||||
|
||||
dprintf(("%ld: PyThread_start_new_thread called\n",
|
||||
dprintf(("%lu: PyThread_start_new_thread called\n",
|
||||
PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
|
||||
if (!obj)
|
||||
return -1;
|
||||
return PYTHREAD_INVALID_THREAD_ID;
|
||||
obj->func = func;
|
||||
obj->arg = arg;
|
||||
hThread = (HANDLE)_beginthreadex(0,
|
||||
|
@ -199,24 +199,24 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
* too many threads".
|
||||
*/
|
||||
int e = errno;
|
||||
dprintf(("%ld: PyThread_start_new_thread failed, errno %d\n",
|
||||
dprintf(("%lu: PyThread_start_new_thread failed, errno %d\n",
|
||||
PyThread_get_thread_ident(), e));
|
||||
threadID = (unsigned)-1;
|
||||
HeapFree(GetProcessHeap(), 0, obj);
|
||||
}
|
||||
else {
|
||||
dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n",
|
||||
dprintf(("%lu: PyThread_start_new_thread succeeded: %p\n",
|
||||
PyThread_get_thread_ident(), (void*)hThread));
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
return (long) threadID;
|
||||
return threadID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the thread Id instead of a handle. The Id is said to uniquely identify the
|
||||
* thread in the system
|
||||
*/
|
||||
long
|
||||
unsigned long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
if (!initialized)
|
||||
|
@ -228,7 +228,7 @@ PyThread_get_thread_ident(void)
|
|||
void
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
|
||||
dprintf(("%lu: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
_endthreadex(0);
|
||||
|
@ -250,7 +250,7 @@ PyThread_allocate_lock(void)
|
|||
|
||||
aLock = AllocNonRecursiveMutex() ;
|
||||
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
|
||||
dprintf(("%lu: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
|
||||
|
||||
return (PyThread_type_lock) aLock;
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ PyThread_allocate_lock(void)
|
|||
void
|
||||
PyThread_free_lock(PyThread_type_lock aLock)
|
||||
{
|
||||
dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
dprintf(("%lu: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
|
||||
FreeNonRecursiveMutex(aLock) ;
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock,
|
|||
else
|
||||
milliseconds = INFINITE;
|
||||
|
||||
dprintf(("%ld: PyThread_acquire_lock_timed(%p, %lld) called\n",
|
||||
dprintf(("%lu: PyThread_acquire_lock_timed(%p, %lld) called\n",
|
||||
PyThread_get_thread_ident(), aLock, microseconds));
|
||||
|
||||
if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock,
|
||||
|
@ -300,7 +300,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock,
|
|||
success = PY_LOCK_FAILURE;
|
||||
}
|
||||
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %lld) -> %d\n",
|
||||
dprintf(("%lu: PyThread_acquire_lock(%p, %lld) -> %d\n",
|
||||
PyThread_get_thread_ident(), aLock, microseconds, success));
|
||||
|
||||
return success;
|
||||
|
@ -314,10 +314,10 @@ PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
|
|||
void
|
||||
PyThread_release_lock(PyThread_type_lock aLock)
|
||||
{
|
||||
dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
|
||||
if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
|
||||
dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
|
||||
}
|
||||
|
||||
/* minimum/maximum thread stack sizes supported */
|
||||
|
|
|
@ -184,7 +184,7 @@ PyThread__init_thread(void)
|
|||
*/
|
||||
|
||||
|
||||
long
|
||||
unsigned long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
pthread_t th;
|
||||
|
@ -202,7 +202,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
|
||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
|
||||
if (pthread_attr_init(&attrs) != 0)
|
||||
return -1;
|
||||
return PYTHREAD_INVALID_THREAD_ID;
|
||||
#endif
|
||||
#if defined(THREAD_STACK_SIZE)
|
||||
tss = (_pythread_stacksize != 0) ? _pythread_stacksize
|
||||
|
@ -210,7 +210,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
if (tss != 0) {
|
||||
if (pthread_attr_setstacksize(&attrs, tss) != 0) {
|
||||
pthread_attr_destroy(&attrs);
|
||||
return -1;
|
||||
return PYTHREAD_INVALID_THREAD_ID;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -232,31 +232,31 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
pthread_attr_destroy(&attrs);
|
||||
#endif
|
||||
if (status != 0)
|
||||
return -1;
|
||||
return PYTHREAD_INVALID_THREAD_ID;
|
||||
|
||||
pthread_detach(th);
|
||||
|
||||
#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
|
||||
return (long) th;
|
||||
return (unsigned long) th;
|
||||
#else
|
||||
return (long) *(long *) &th;
|
||||
return (unsigned long) *(unsigned long *) &th;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX This implementation is considered (to quote Tim Peters) "inherently
|
||||
hosed" because:
|
||||
- It does not guarantee the promise that a non-zero integer is returned.
|
||||
- The cast to long is inherently unsafe.
|
||||
- The cast to unsigned long is inherently unsafe.
|
||||
- It is not clear that the 'volatile' (for AIX?) are any longer necessary.
|
||||
*/
|
||||
long
|
||||
unsigned long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
volatile pthread_t threadid;
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
threadid = pthread_self();
|
||||
return (long) threadid;
|
||||
return (unsigned long) threadid;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -731,7 +731,7 @@ write_thread_id(int fd, PyThreadState *tstate, int is_current)
|
|||
else
|
||||
PUTS(fd, "Thread 0x");
|
||||
_Py_DumpHexadecimal(fd,
|
||||
(unsigned long)tstate->thread_id,
|
||||
tstate->thread_id,
|
||||
sizeof(unsigned long) * 2);
|
||||
PUTS(fd, " (most recent call first):\n");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue