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:
Serhiy Storchaka 2017-03-23 15:48:39 +02:00 committed by Victor Stinner
parent 1e2147b9d7
commit aefa7ebf0f
27 changed files with 116 additions and 88 deletions

View File

@ -830,7 +830,7 @@ been created.
the caller should assume no current thread state is available. the caller should assume no current thread state is available.
.. c:function:: int PyThreadState_SetAsyncExc(long id, PyObject *exc) .. c:function:: int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
Asynchronously raise an exception in a thread. The *id* argument is the thread Asynchronously raise an exception in a thread. The *id* argument is the thread
id of the target thread; *exc* is the exception object to be raised. This id of the target thread; *exc* is the exception object to be raised. This
@ -840,6 +840,9 @@ been created.
zero if the thread id isn't found. If *exc* is :const:`NULL`, the pending zero if the thread id isn't found. If *exc* is :const:`NULL`, the pending
exception (if any) for the thread is cleared. This raises no exceptions. exception (if any) for the thread is cleared. This raises no exceptions.
.. versionchanged:: 3.7
The type of the *id* parameter changed from :c:type:`long` to
:c:type:`unsigned long`.
.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate) .. c:function:: void PyEval_AcquireThread(PyThreadState *tstate)

View File

@ -185,6 +185,16 @@ Deprecated
(Contributed by Serhiy Storchaka in :issue:`28692`.) (Contributed by Serhiy Storchaka in :issue:`28692`.)
Changes in the C API
--------------------
- The type of results of :c:func:`PyThread_start_new_thread` and
:c:func:`PyThread_get_thread_ident`, and the *id* parameter of
:c:func:`PyThreadState_SetAsyncExc` changed from :c:type:`long` to
:c:type:`unsigned long`.
(Contributed by Serhiy Storchaka in :issue:`6532`.)
Removed Removed
======= =======

View File

@ -108,7 +108,7 @@ typedef struct _ts {
int gilstate_counter; int gilstate_counter;
PyObject *async_exc; /* Asynchronous exception to raise */ PyObject *async_exc; /* Asynchronous exception to raise */
long thread_id; /* Thread id where this tstate was created */ unsigned long thread_id; /* Thread id where this tstate was created */
int trash_delete_nesting; int trash_delete_nesting;
PyObject *trash_delete_later; PyObject *trash_delete_later;
@ -200,7 +200,7 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *);
/* Variable and macro for in-line access to current thread state */ /* Variable and macro for in-line access to current thread state */

View File

@ -17,10 +17,14 @@ typedef enum PyLockStatus {
PY_LOCK_INTR PY_LOCK_INTR
} PyLockStatus; } PyLockStatus;
#ifndef Py_LIMITED_API
#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1)
#endif
PyAPI_FUNC(void) PyThread_init_thread(void); PyAPI_FUNC(void) PyThread_init_thread(void);
PyAPI_FUNC(long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *);
PyAPI_FUNC(void) PyThread_exit_thread(void); PyAPI_FUNC(void) PyThread_exit_thread(void);
PyAPI_FUNC(long) PyThread_get_thread_ident(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void);
PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void);
PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock);

View File

@ -69,7 +69,7 @@ def get_ident():
available, it is safe to assume that the current process is the available, it is safe to assume that the current process is the
only thread. Thus a constant can be safely returned. only thread. Thus a constant can be safely returned.
""" """
return -1 return 1
def allocate_lock(): def allocate_lock():
"""Dummy implementation of _thread.allocate_lock().""" """Dummy implementation of _thread.allocate_lock()."""

View File

@ -111,8 +111,7 @@ def test_exit(self):
def test_ident(self): def test_ident(self):
self.assertIsInstance(_thread.get_ident(), int, self.assertIsInstance(_thread.get_ident(), int,
"_thread.get_ident() returned a non-integer") "_thread.get_ident() returned a non-integer")
self.assertNotEqual(_thread.get_ident(), 0, self.assertGreater(_thread.get_ident(), 0)
"_thread.get_ident() returned 0")
def test_LockType(self): def test_LockType(self):
self.assertIsInstance(_thread.allocate_lock(), _thread.LockType, self.assertIsInstance(_thread.allocate_lock(), _thread.LockType,

View File

@ -393,6 +393,9 @@ def g456():
thread_id = thread_info[0] thread_id = thread_info[0]
d = sys._current_frames() d = sys._current_frames()
for tid in d:
self.assertIsInstance(tid, int)
self.assertGreater(tid, 0)
main_id = threading.get_ident() main_id = threading.get_ident()
self.assertIn(main_id, d) self.assertIn(main_id, d)

View File

@ -181,6 +181,7 @@ def test_PyThreadState_SetAsyncExc(self):
ctypes = import_module("ctypes") ctypes = import_module("ctypes")
set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc
set_async_exc.argtypes = (ctypes.c_ulong, ctypes.py_object)
class AsyncExc(Exception): class AsyncExc(Exception):
pass pass
@ -189,9 +190,11 @@ class AsyncExc(Exception):
# First check it works when setting the exception from the same thread. # First check it works when setting the exception from the same thread.
tid = threading.get_ident() tid = threading.get_ident()
self.assertIsInstance(tid, int)
self.assertGreater(tid, 0)
try: try:
result = set_async_exc(ctypes.c_long(tid), exception) result = set_async_exc(tid, exception)
# The exception is async, so we might have to keep the VM busy until # The exception is async, so we might have to keep the VM busy until
# it notices. # it notices.
while True: while True:
@ -237,7 +240,7 @@ def run(self):
# Try a thread id that doesn't make sense. # Try a thread id that doesn't make sense.
if verbose: if verbose:
print(" trying nonsensical thread id") print(" trying nonsensical thread id")
result = set_async_exc(ctypes.c_long(-1), exception) result = set_async_exc(-1, exception)
self.assertEqual(result, 0) # no thread states modified self.assertEqual(result, 0) # no thread states modified
# Now raise an exception in the worker thread. # Now raise an exception in the worker thread.
@ -250,7 +253,7 @@ def run(self):
self.assertFalse(t.finished) self.assertFalse(t.finished)
if verbose: if verbose:
print(" attempting to raise asynch exception in worker") print(" attempting to raise asynch exception in worker")
result = set_async_exc(ctypes.c_long(t.id), exception) result = set_async_exc(t.id, exception)
self.assertEqual(result, 1) # one thread state modified self.assertEqual(result, 1) # one thread state modified
if verbose: if verbose:
print(" waiting for worker to say it caught the exception") print(" waiting for worker to say it caught the exception")

View File

@ -993,14 +993,14 @@ def _delete(self):
# #
# Must take care to not raise an exception if _dummy_thread is being # Must take care to not raise an exception if _dummy_thread is being
# used (and thus this module is being used as an instance of # used (and thus this module is being used as an instance of
# dummy_threading). _dummy_thread.get_ident() always returns -1 since # dummy_threading). _dummy_thread.get_ident() always returns 1 since
# there is only one thread if _dummy_thread is being used. Thus # there is only one thread if _dummy_thread is being used. Thus
# len(_active) is always <= 1 here, and any Thread instance created # len(_active) is always <= 1 here, and any Thread instance created
# overwrites the (if any) thread currently registered in _active. # overwrites the (if any) thread currently registered in _active.
# #
# An instance of _MainThread is always created by 'threading'. This # An instance of _MainThread is always created by 'threading'. This
# gets overwritten the instant an instance of Thread is created; both # gets overwritten the instant an instance of Thread is created; both
# threads return -1 from _dummy_thread.get_ident() and thus have the # threads return 1 from _dummy_thread.get_ident() and thus have the
# same key in the dict. So when the _MainThread instance created by # same key in the dict. So when the _MainThread instance created by
# 'threading' tries to clean itself up when atexit calls this method # 'threading' tries to clean itself up when atexit calls this method
# it gets a KeyError if another Thread instance was created. # it gets a KeyError if another Thread instance was created.

View File

@ -813,6 +813,10 @@ Windows
C API C API
----- -----
- bpo-6532: The type of results of PyThread_start_new_thread() and
PyThread_get_thread_ident(), and the id parameter of
PyThreadState_SetAsyncExc() changed from "long" to "unsigned long".
- Issue #27867: Function PySlice_GetIndicesEx() is deprecated and replaced with - Issue #27867: Function PySlice_GetIndicesEx() is deprecated and replaced with
a macro if Py_LIMITED_API is not set or set to the value between 0x03050400 a macro if Py_LIMITED_API is not set or set to the value between 0x03050400
and 0x03060000 (not including) or 0x03060100 or higher. Added functions and 0x03060000 (not including) or 0x03060100 or higher. Added functions

View File

@ -239,7 +239,7 @@ typedef struct {
#ifdef WITH_THREAD #ifdef WITH_THREAD
PyThread_type_lock lock; PyThread_type_lock lock;
volatile long owner; volatile unsigned long owner;
#endif #endif
Py_ssize_t buffer_size; Py_ssize_t buffer_size;

View File

@ -14,7 +14,7 @@ enum { RECURSIVE_MUTEX, SEMAPHORE };
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
SEM_HANDLE handle; SEM_HANDLE handle;
long last_tid; unsigned long last_tid;
int count; int count;
int maxvalue; int maxvalue;
int kind; int kind;

View File

@ -1125,7 +1125,7 @@ int pysqlite_check_thread(pysqlite_Connection* self)
if (PyThread_get_thread_ident() != self->thread_ident) { if (PyThread_get_thread_ident() != self->thread_ident) {
PyErr_Format(pysqlite_ProgrammingError, PyErr_Format(pysqlite_ProgrammingError,
"SQLite objects created in a thread can only be used in that same thread." "SQLite objects created in a thread can only be used in that same thread."
"The object was created in thread id %ld and this is thread id %ld", "The object was created in thread id %lu and this is thread id %lu",
self->thread_ident, PyThread_get_thread_ident()); self->thread_ident, PyThread_get_thread_ident());
return 0; return 0;
} }

View File

@ -61,7 +61,7 @@ typedef struct
int initialized; int initialized;
/* thread identification of the thread the connection was created in */ /* thread identification of the thread the connection was created in */
long thread_ident; unsigned long thread_ident;
pysqlite_Cache* statement_cache; pysqlite_Cache* statement_cache;

View File

@ -5032,8 +5032,7 @@ static PyThread_type_lock *_ssl_locks = NULL;
static void static void
_ssl_threadid_callback(CRYPTO_THREADID *id) _ssl_threadid_callback(CRYPTO_THREADID *id)
{ {
CRYPTO_THREADID_set_numeric(id, CRYPTO_THREADID_set_numeric(id, PyThread_get_thread_ident());
(unsigned long)PyThread_get_thread_ident());
} }
#else #else
/* deprecated CRYPTO_set_id_callback() API. */ /* deprecated CRYPTO_set_id_callback() API. */

View File

@ -267,7 +267,7 @@ static PyTypeObject Locktype = {
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
PyThread_type_lock rlock_lock; PyThread_type_lock rlock_lock;
long rlock_owner; unsigned long rlock_owner;
unsigned long rlock_count; unsigned long rlock_count;
PyObject *in_weakreflist; PyObject *in_weakreflist;
} rlockobject; } rlockobject;
@ -293,7 +293,7 @@ static PyObject *
rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
{ {
_PyTime_t timeout; _PyTime_t timeout;
long tid; unsigned long tid;
PyLockStatus r = PY_LOCK_ACQUIRED; PyLockStatus r = PY_LOCK_ACQUIRED;
if (lock_acquire_parse_args(args, kwds, &timeout) < 0) if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
@ -342,7 +342,7 @@ the lock is taken and its internal counter initialized to 1.");
static PyObject * static PyObject *
rlock_release(rlockobject *self) rlock_release(rlockobject *self)
{ {
long tid = PyThread_get_thread_ident(); unsigned long tid = PyThread_get_thread_ident();
if (self->rlock_count == 0 || self->rlock_owner != tid) { if (self->rlock_count == 0 || self->rlock_owner != tid) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
@ -371,11 +371,11 @@ to be available for other threads.");
static PyObject * static PyObject *
rlock_acquire_restore(rlockobject *self, PyObject *args) rlock_acquire_restore(rlockobject *self, PyObject *args)
{ {
long owner; unsigned long owner;
unsigned long count; unsigned long count;
int r = 1; int r = 1;
if (!PyArg_ParseTuple(args, "(kl):_acquire_restore", &count, &owner)) if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
return NULL; return NULL;
if (!PyThread_acquire_lock(self->rlock_lock, 0)) { if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
@ -401,7 +401,7 @@ For internal use by `threading.Condition`.");
static PyObject * static PyObject *
rlock_release_save(rlockobject *self) rlock_release_save(rlockobject *self)
{ {
long owner; unsigned long owner;
unsigned long count; unsigned long count;
if (self->rlock_count == 0) { if (self->rlock_count == 0) {
@ -415,7 +415,7 @@ rlock_release_save(rlockobject *self)
self->rlock_count = 0; self->rlock_count = 0;
self->rlock_owner = 0; self->rlock_owner = 0;
PyThread_release_lock(self->rlock_lock); PyThread_release_lock(self->rlock_lock);
return Py_BuildValue("kl", count, owner); return Py_BuildValue("kk", count, owner);
} }
PyDoc_STRVAR(rlock_release_save_doc, PyDoc_STRVAR(rlock_release_save_doc,
@ -427,7 +427,7 @@ For internal use by `threading.Condition`.");
static PyObject * static PyObject *
rlock_is_owned(rlockobject *self) rlock_is_owned(rlockobject *self)
{ {
long tid = PyThread_get_thread_ident(); unsigned long tid = PyThread_get_thread_ident();
if (self->rlock_count > 0 && self->rlock_owner == tid) { if (self->rlock_count > 0 && self->rlock_owner == tid) {
Py_RETURN_TRUE; Py_RETURN_TRUE;
@ -1031,7 +1031,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
{ {
PyObject *func, *args, *keyw = NULL; PyObject *func, *args, *keyw = NULL;
struct bootstate *boot; struct bootstate *boot;
long ident; unsigned long ident;
if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
&func, &args, &keyw)) &func, &args, &keyw))
@ -1068,7 +1068,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Py_XINCREF(keyw); Py_XINCREF(keyw);
PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
ident = PyThread_start_new_thread(t_bootstrap, (void*) boot); ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
if (ident == -1) { if (ident == PYTHREAD_INVALID_THREAD_ID) {
PyErr_SetString(ThreadError, "can't start new thread"); PyErr_SetString(ThreadError, "can't start new thread");
Py_DECREF(func); Py_DECREF(func);
Py_DECREF(args); Py_DECREF(args);
@ -1077,7 +1077,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
PyMem_DEL(boot); PyMem_DEL(boot);
return NULL; return NULL;
} }
return PyLong_FromLong(ident); return PyLong_FromUnsignedLong(ident);
} }
PyDoc_STRVAR(start_new_doc, PyDoc_STRVAR(start_new_doc,
@ -1137,13 +1137,12 @@ information about locks.");
static PyObject * static PyObject *
thread_get_ident(PyObject *self) thread_get_ident(PyObject *self)
{ {
long ident; unsigned long ident = PyThread_get_thread_ident();
ident = PyThread_get_thread_ident(); if (ident == PYTHREAD_INVALID_THREAD_ID) {
if (ident == -1) {
PyErr_SetString(ThreadError, "no current thread ident"); PyErr_SetString(ThreadError, "no current thread ident");
return NULL; return NULL;
} }
return PyLong_FromLong(ident); return PyLong_FromUnsignedLong(ident);
} }
PyDoc_STRVAR(get_ident_doc, PyDoc_STRVAR(get_ident_doc,

View File

@ -395,16 +395,17 @@ PyDoc_STRVAR(signal_pthread_kill__doc__,
{"pthread_kill", (PyCFunction)signal_pthread_kill, METH_FASTCALL, signal_pthread_kill__doc__}, {"pthread_kill", (PyCFunction)signal_pthread_kill, METH_FASTCALL, signal_pthread_kill__doc__},
static PyObject * static PyObject *
signal_pthread_kill_impl(PyObject *module, long thread_id, int signalnum); signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
int signalnum);
static PyObject * static PyObject *
signal_pthread_kill(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) signal_pthread_kill(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
long thread_id; unsigned long thread_id;
int signalnum; int signalnum;
if (!_PyArg_ParseStack(args, nargs, "li:pthread_kill", if (!_PyArg_ParseStack(args, nargs, "ki:pthread_kill",
&thread_id, &signalnum)) { &thread_id, &signalnum)) {
goto exit; goto exit;
} }
@ -463,4 +464,4 @@ exit:
#ifndef SIGNAL_PTHREAD_KILL_METHODDEF #ifndef SIGNAL_PTHREAD_KILL_METHODDEF
#define SIGNAL_PTHREAD_KILL_METHODDEF #define SIGNAL_PTHREAD_KILL_METHODDEF
#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ #endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */
/*[clinic end generated code: output=fab3dba32c058588 input=a9049054013a1b77]*/ /*[clinic end generated code: output=c1a3f374b2c77e5d input=a9049054013a1b77]*/

View File

@ -678,7 +678,7 @@ faulthandler_dump_traceback_later(PyObject *self,
/* Arm these locks to serve as events when released */ /* Arm these locks to serve as events when released */
PyThread_acquire_lock(thread.running, 1); PyThread_acquire_lock(thread.running, 1);
if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) { if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
PyThread_release_lock(thread.running); PyThread_release_lock(thread.running);
Py_CLEAR(thread.file); Py_CLEAR(thread.file);
PyMem_Free(header); PyMem_Free(header);

View File

@ -88,7 +88,7 @@ module signal
#ifdef WITH_THREAD #ifdef WITH_THREAD
#include <sys/types.h> /* For pid_t */ #include <sys/types.h> /* For pid_t */
#include "pythread.h" #include "pythread.h"
static long main_thread; static unsigned long main_thread;
static pid_t main_pid; static pid_t main_pid;
#endif #endif
@ -1088,7 +1088,7 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset,
/*[clinic input] /*[clinic input]
signal.pthread_kill signal.pthread_kill
thread_id: long thread_id: unsigned_long(bitwise=True)
signalnum: int signalnum: int
/ /
@ -1096,8 +1096,9 @@ Send a signal to a thread.
[clinic start generated code]*/ [clinic start generated code]*/
static PyObject * static PyObject *
signal_pthread_kill_impl(PyObject *module, long thread_id, int signalnum) signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
/*[clinic end generated code: output=2a09ce41f1c4228a input=77ed6a3b6f2a8122]*/ int signalnum)
/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/
{ {
int err; int err;

View File

@ -148,7 +148,7 @@ static long dxp[256];
#include "pythread.h" #include "pythread.h"
static PyThread_type_lock pending_lock = 0; /* for pending calls */ 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 /* This single variable consolidates all requests to break out of the fast path
in the eval loop. */ in the eval loop. */
static _Py_atomic_int eval_breaker = {0}; static _Py_atomic_int eval_breaker = {0};

View File

@ -147,14 +147,14 @@ _PyImportZip_Init(void)
#include "pythread.h" #include "pythread.h"
static PyThread_type_lock import_lock = 0; 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; static int import_lock_level = 0;
void void
_PyImport_AcquireLock(void) _PyImport_AcquireLock(void)
{ {
long me = PyThread_get_thread_ident(); unsigned long me = PyThread_get_thread_ident();
if (me == -1) if (me == PYTHREAD_INVALID_THREAD_ID)
return; /* Too bad */ return; /* Too bad */
if (import_lock == NULL) { if (import_lock == NULL) {
import_lock = PyThread_allocate_lock(); import_lock = PyThread_allocate_lock();
@ -165,7 +165,8 @@ _PyImport_AcquireLock(void)
import_lock_level++; import_lock_level++;
return; 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(); PyThreadState *tstate = PyEval_SaveThread();
PyThread_acquire_lock(import_lock, 1); PyThread_acquire_lock(import_lock, 1);
@ -179,15 +180,15 @@ _PyImport_AcquireLock(void)
int int
_PyImport_ReleaseLock(void) _PyImport_ReleaseLock(void)
{ {
long me = PyThread_get_thread_ident(); unsigned long me = PyThread_get_thread_ident();
if (me == -1 || import_lock == NULL) if (me == PYTHREAD_INVALID_THREAD_ID || import_lock == NULL)
return 0; /* Too bad */ return 0; /* Too bad */
if (import_lock_thread != me) if (import_lock_thread != me)
return -1; return -1;
import_lock_level--; import_lock_level--;
assert(import_lock_level >= 0); assert(import_lock_level >= 0);
if (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); PyThread_release_lock(import_lock);
} }
return 1; return 1;
@ -209,7 +210,7 @@ _PyImport_ReInitLock(void)
} }
if (import_lock_level > 1) { if (import_lock_level > 1) {
/* Forked as a side effect of import */ /* 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 /* 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 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 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_thread = me;
import_lock_level--; import_lock_level--;
} else { } else {
import_lock_thread = -1; import_lock_thread = PYTHREAD_INVALID_THREAD_ID;
import_lock_level = 0; import_lock_level = 0;
} }
} }
@ -238,7 +239,7 @@ _imp_lock_held_impl(PyObject *module)
/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/ /*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/
{ {
#ifdef WITH_THREAD #ifdef WITH_THREAD
return PyBool_FromLong(import_lock_thread != -1); return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID);
#else #else
Py_RETURN_FALSE; Py_RETURN_FALSE;
#endif #endif

View File

@ -580,7 +580,8 @@ PyThreadState_GetDict(void)
existing async exception. This raises no exceptions. */ existing async exception. This raises no exceptions. */
int int
PyThreadState_SetAsyncExc(long id, PyObject *exc) { PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
{
PyInterpreterState *interp = GET_INTERP_STATE(); PyInterpreterState *interp = GET_INTERP_STATE();
PyThreadState *p; PyThreadState *p;
@ -668,7 +669,7 @@ _PyThread_CurrentFrames(void)
struct _frame *frame = t->frame; struct _frame *frame = t->frame;
if (frame == NULL) if (frame == NULL)
continue; continue;
id = PyLong_FromLong(t->thread_id); id = PyLong_FromUnsignedLong(t->thread_id);
if (id == NULL) if (id == NULL)
goto Fail; goto Fail;
stat = PyDict_SetItem(result, id, (PyObject *)frame); stat = PyDict_SetItem(result, id, (PyObject *)frame);

View File

@ -172,7 +172,7 @@ struct key {
struct key *next; struct key *next;
/* The thread id, according to PyThread_get_thread_ident(). */ /* The thread id, according to PyThread_get_thread_ident(). */
long id; unsigned long id;
/* The key and its associated value. */ /* The key and its associated value. */
int key; int key;
@ -208,7 +208,7 @@ static struct key *
find_key(int set_value, int key, void *value) find_key(int set_value, int key, void *value)
{ {
struct key *p, *prev_p; struct key *p, *prev_p;
long id = PyThread_get_thread_ident(); unsigned long id = PyThread_get_thread_ident();
if (!keymutex) if (!keymutex)
return NULL; return NULL;
@ -312,7 +312,7 @@ PyThread_get_key_value(int key)
void void
PyThread_delete_key_value(int key) PyThread_delete_key_value(int key)
{ {
long id = PyThread_get_thread_ident(); unsigned long id = PyThread_get_thread_ident();
struct key *p, **q; struct key *p, **q;
PyThread_acquire_lock(keymutex, 1); PyThread_acquire_lock(keymutex, 1);
@ -338,7 +338,7 @@ PyThread_delete_key_value(int key)
void void
PyThread_ReInitTLS(void) PyThread_ReInitTLS(void)
{ {
long id = PyThread_get_thread_ident(); unsigned long id = PyThread_get_thread_ident();
struct key *p, **q; struct key *p, **q;
if (!keymutex) if (!keymutex)

View File

@ -9,7 +9,7 @@ PyThread__init_thread(void)
/* /*
* Thread support. * Thread support.
*/ */
long unsigned long
PyThread_start_new_thread(void (*func)(void *), void *arg) PyThread_start_new_thread(void (*func)(void *), void *arg)
{ {
int success = 0; /* init not needed when SOLARIS_THREADS and */ 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")); dprintf(("PyThread_start_new_thread called\n"));
if (!initialized) if (!initialized)
PyThread_init_thread(); PyThread_init_thread();
return success < 0 ? -1 : 0; return success < 0 ? PYTHREAD_INVALID_THREAD_ID : 0;
} }
long unsigned long
PyThread_get_thread_ident(void) PyThread_get_thread_ident(void)
{ {
if (!initialized) if (!initialized)

View File

@ -140,7 +140,7 @@ LeaveNonRecursiveMutex(PNRMUTEX mutex)
} }
#endif /* _PY_USE_CV_LOCKS */ #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. * Initialization of the C package, should not be needed.
@ -172,21 +172,21 @@ bootstrap(void *call)
return 0; return 0;
} }
long unsigned long
PyThread_start_new_thread(void (*func)(void *), void *arg) PyThread_start_new_thread(void (*func)(void *), void *arg)
{ {
HANDLE hThread; HANDLE hThread;
unsigned threadID; unsigned threadID;
callobj *obj; callobj *obj;
dprintf(("%ld: PyThread_start_new_thread called\n", dprintf(("%lu: PyThread_start_new_thread called\n",
PyThread_get_thread_ident())); PyThread_get_thread_ident()));
if (!initialized) if (!initialized)
PyThread_init_thread(); PyThread_init_thread();
obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
if (!obj) if (!obj)
return -1; return PYTHREAD_INVALID_THREAD_ID;
obj->func = func; obj->func = func;
obj->arg = arg; obj->arg = arg;
hThread = (HANDLE)_beginthreadex(0, hThread = (HANDLE)_beginthreadex(0,
@ -199,24 +199,24 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
* too many threads". * too many threads".
*/ */
int e = errno; 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)); PyThread_get_thread_ident(), e));
threadID = (unsigned)-1; threadID = (unsigned)-1;
HeapFree(GetProcessHeap(), 0, obj); HeapFree(GetProcessHeap(), 0, obj);
} }
else { 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)); PyThread_get_thread_ident(), (void*)hThread));
CloseHandle(hThread); CloseHandle(hThread);
} }
return (long) threadID; return threadID;
} }
/* /*
* Return the thread Id instead of a handle. The Id is said to uniquely identify the * Return the thread Id instead of a handle. The Id is said to uniquely identify the
* thread in the system * thread in the system
*/ */
long unsigned long
PyThread_get_thread_ident(void) PyThread_get_thread_ident(void)
{ {
if (!initialized) if (!initialized)
@ -228,7 +228,7 @@ PyThread_get_thread_ident(void)
void void
PyThread_exit_thread(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) if (!initialized)
exit(0); exit(0);
_endthreadex(0); _endthreadex(0);
@ -250,7 +250,7 @@ PyThread_allocate_lock(void)
aLock = AllocNonRecursiveMutex() ; 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; return (PyThread_type_lock) aLock;
} }
@ -258,7 +258,7 @@ PyThread_allocate_lock(void)
void void
PyThread_free_lock(PyThread_type_lock aLock) 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) ; FreeNonRecursiveMutex(aLock) ;
} }
@ -289,7 +289,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock,
else else
milliseconds = INFINITE; 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)); PyThread_get_thread_ident(), aLock, microseconds));
if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock, if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock,
@ -300,7 +300,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock,
success = PY_LOCK_FAILURE; 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)); PyThread_get_thread_ident(), aLock, microseconds, success));
return success; return success;
@ -314,10 +314,10 @@ PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
void void
PyThread_release_lock(PyThread_type_lock aLock) 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))) 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 */ /* minimum/maximum thread stack sizes supported */

View File

@ -184,7 +184,7 @@ PyThread__init_thread(void)
*/ */
long unsigned long
PyThread_start_new_thread(void (*func)(void *), void *arg) PyThread_start_new_thread(void (*func)(void *), void *arg)
{ {
pthread_t th; 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 defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
if (pthread_attr_init(&attrs) != 0) if (pthread_attr_init(&attrs) != 0)
return -1; return PYTHREAD_INVALID_THREAD_ID;
#endif #endif
#if defined(THREAD_STACK_SIZE) #if defined(THREAD_STACK_SIZE)
tss = (_pythread_stacksize != 0) ? _pythread_stacksize tss = (_pythread_stacksize != 0) ? _pythread_stacksize
@ -210,7 +210,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
if (tss != 0) { if (tss != 0) {
if (pthread_attr_setstacksize(&attrs, tss) != 0) { if (pthread_attr_setstacksize(&attrs, tss) != 0) {
pthread_attr_destroy(&attrs); pthread_attr_destroy(&attrs);
return -1; return PYTHREAD_INVALID_THREAD_ID;
} }
} }
#endif #endif
@ -232,31 +232,31 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
pthread_attr_destroy(&attrs); pthread_attr_destroy(&attrs);
#endif #endif
if (status != 0) if (status != 0)
return -1; return PYTHREAD_INVALID_THREAD_ID;
pthread_detach(th); pthread_detach(th);
#if SIZEOF_PTHREAD_T <= SIZEOF_LONG #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
return (long) th; return (unsigned long) th;
#else #else
return (long) *(long *) &th; return (unsigned long) *(unsigned long *) &th;
#endif #endif
} }
/* XXX This implementation is considered (to quote Tim Peters) "inherently /* XXX This implementation is considered (to quote Tim Peters) "inherently
hosed" because: hosed" because:
- It does not guarantee the promise that a non-zero integer is returned. - 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. - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
*/ */
long unsigned long
PyThread_get_thread_ident(void) PyThread_get_thread_ident(void)
{ {
volatile pthread_t threadid; volatile pthread_t threadid;
if (!initialized) if (!initialized)
PyThread_init_thread(); PyThread_init_thread();
threadid = pthread_self(); threadid = pthread_self();
return (long) threadid; return (unsigned long) threadid;
} }
void void

View File

@ -731,7 +731,7 @@ write_thread_id(int fd, PyThreadState *tstate, int is_current)
else else
PUTS(fd, "Thread 0x"); PUTS(fd, "Thread 0x");
_Py_DumpHexadecimal(fd, _Py_DumpHexadecimal(fd,
(unsigned long)tstate->thread_id, tstate->thread_id,
sizeof(unsigned long) * 2); sizeof(unsigned long) * 2);
PUTS(fd, " (most recent call first):\n"); PUTS(fd, " (most recent call first):\n");
} }