From aefa7ebf0ff0f73feee7ab24f4cdcb2014d83ee5 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 23 Mar 2017 15:48:39 +0200 Subject: [PATCH] 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(). --- Doc/c-api/init.rst | 5 ++++- Doc/whatsnew/3.7.rst | 10 ++++++++++ Include/pystate.h | 4 ++-- Include/pythread.h | 8 ++++++-- Lib/_dummy_thread.py | 2 +- Lib/test/test_dummy_thread.py | 3 +-- Lib/test/test_sys.py | 3 +++ Lib/test/test_threading.py | 9 ++++++--- Lib/threading.py | 4 ++-- Misc/NEWS | 4 ++++ Modules/_io/bufferedio.c | 2 +- Modules/_multiprocessing/semaphore.c | 2 +- Modules/_sqlite/connection.c | 2 +- Modules/_sqlite/connection.h | 2 +- Modules/_ssl.c | 3 +-- Modules/_threadmodule.c | 29 +++++++++++++-------------- Modules/clinic/signalmodule.c.h | 9 +++++---- Modules/faulthandler.c | 2 +- Modules/signalmodule.c | 9 +++++---- Python/ceval.c | 2 +- Python/import.c | 21 +++++++++---------- Python/pystate.c | 5 +++-- Python/thread.c | 8 ++++---- Python/thread_foobar.h | 6 +++--- Python/thread_nt.h | 30 ++++++++++++++-------------- Python/thread_pthread.h | 18 ++++++++--------- Python/traceback.c | 2 +- 27 files changed, 116 insertions(+), 88 deletions(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 7d9eefb1ead..56cf77affe6 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -830,7 +830,7 @@ been created. 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 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 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) diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 4f84e6df28d..882d6a27f7e 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -185,6 +185,16 @@ Deprecated (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 ======= diff --git a/Include/pystate.h b/Include/pystate.h index afc3c0c6d1d..62254fab963 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -108,7 +108,7 @@ typedef struct _ts { int gilstate_counter; 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; PyObject *trash_delete_later; @@ -200,7 +200,7 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); 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 */ diff --git a/Include/pythread.h b/Include/pythread.h index 88c4873a557..dbacb8bbbcd 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -17,10 +17,14 @@ typedef enum PyLockStatus { PY_LOCK_INTR } PyLockStatus; +#ifndef Py_LIMITED_API +#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) +#endif + 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(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(void) PyThread_free_lock(PyThread_type_lock); diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py index 36e5f38ae0e..a2cae54b058 100644 --- a/Lib/_dummy_thread.py +++ b/Lib/_dummy_thread.py @@ -69,7 +69,7 @@ def get_ident(): available, it is safe to assume that the current process is the only thread. Thus a constant can be safely returned. """ - return -1 + return 1 def allocate_lock(): """Dummy implementation of _thread.allocate_lock().""" diff --git a/Lib/test/test_dummy_thread.py b/Lib/test/test_dummy_thread.py index bb4bfe7a4d3..0840be67d56 100644 --- a/Lib/test/test_dummy_thread.py +++ b/Lib/test/test_dummy_thread.py @@ -111,8 +111,7 @@ class MiscTests(unittest.TestCase): def test_ident(self): self.assertIsInstance(_thread.get_ident(), int, "_thread.get_ident() returned a non-integer") - self.assertNotEqual(_thread.get_ident(), 0, - "_thread.get_ident() returned 0") + self.assertGreater(_thread.get_ident(), 0) def test_LockType(self): self.assertIsInstance(_thread.allocate_lock(), _thread.LockType, diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index e6d8e5082ff..9aeb28a8985 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -393,6 +393,9 @@ class SysModuleTest(unittest.TestCase): thread_id = thread_info[0] d = sys._current_frames() + for tid in d: + self.assertIsInstance(tid, int) + self.assertGreater(tid, 0) main_id = threading.get_ident() self.assertIn(main_id, d) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 6b6c4d220a3..5f7c0a8801c 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -181,6 +181,7 @@ class ThreadTests(BaseTestCase): ctypes = import_module("ctypes") set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc + set_async_exc.argtypes = (ctypes.c_ulong, ctypes.py_object) class AsyncExc(Exception): pass @@ -189,9 +190,11 @@ class ThreadTests(BaseTestCase): # First check it works when setting the exception from the same thread. tid = threading.get_ident() + self.assertIsInstance(tid, int) + self.assertGreater(tid, 0) 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 # it notices. while True: @@ -237,7 +240,7 @@ class ThreadTests(BaseTestCase): # Try a thread id that doesn't make sense. if verbose: 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 # Now raise an exception in the worker thread. @@ -250,7 +253,7 @@ class ThreadTests(BaseTestCase): self.assertFalse(t.finished) if verbose: 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 if verbose: print(" waiting for worker to say it caught the exception") diff --git a/Lib/threading.py b/Lib/threading.py index 95978d310a2..929a4b00666 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -993,14 +993,14 @@ class Thread: # # 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 - # 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 # len(_active) is always <= 1 here, and any Thread instance created # overwrites the (if any) thread currently registered in _active. # # An instance of _MainThread is always created by 'threading'. This # 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 # 'threading' tries to clean itself up when atexit calls this method # it gets a KeyError if another Thread instance was created. diff --git a/Misc/NEWS b/Misc/NEWS index aac10a6bef7..97c45d4776b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -813,6 +813,10 @@ Windows 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 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 diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 4f6dddb3a31..b30d229bb6d 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -239,7 +239,7 @@ typedef struct { #ifdef WITH_THREAD PyThread_type_lock lock; - volatile long owner; + volatile unsigned long owner; #endif Py_ssize_t buffer_size; diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index cea962ab26c..9614329d1bb 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -14,7 +14,7 @@ enum { RECURSIVE_MUTEX, SEMAPHORE }; typedef struct { PyObject_HEAD SEM_HANDLE handle; - long last_tid; + unsigned long last_tid; int count; int maxvalue; int kind; diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 774399933ee..72156b91a4d 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1125,7 +1125,7 @@ int pysqlite_check_thread(pysqlite_Connection* self) if (PyThread_get_thread_ident() != self->thread_ident) { PyErr_Format(pysqlite_ProgrammingError, "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()); return 0; } diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 2860a0c6f9f..5fb410a62e5 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -61,7 +61,7 @@ typedef struct int initialized; /* thread identification of the thread the connection was created in */ - long thread_ident; + unsigned long thread_ident; pysqlite_Cache* statement_cache; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 421e0b67166..327fb37ebad 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5032,8 +5032,7 @@ static PyThread_type_lock *_ssl_locks = NULL; static void _ssl_threadid_callback(CRYPTO_THREADID *id) { - CRYPTO_THREADID_set_numeric(id, - (unsigned long)PyThread_get_thread_ident()); + CRYPTO_THREADID_set_numeric(id, PyThread_get_thread_ident()); } #else /* deprecated CRYPTO_set_id_callback() API. */ diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index bf25a19eb25..da750c01cd9 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -267,7 +267,7 @@ static PyTypeObject Locktype = { typedef struct { PyObject_HEAD PyThread_type_lock rlock_lock; - long rlock_owner; + unsigned long rlock_owner; unsigned long rlock_count; PyObject *in_weakreflist; } rlockobject; @@ -293,7 +293,7 @@ static PyObject * rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) { _PyTime_t timeout; - long tid; + unsigned long tid; PyLockStatus r = PY_LOCK_ACQUIRED; 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 * 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) { PyErr_SetString(PyExc_RuntimeError, @@ -371,11 +371,11 @@ to be available for other threads."); static PyObject * rlock_acquire_restore(rlockobject *self, PyObject *args) { - long owner; + unsigned long owner; unsigned long count; int r = 1; - if (!PyArg_ParseTuple(args, "(kl):_acquire_restore", &count, &owner)) + if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner)) return NULL; if (!PyThread_acquire_lock(self->rlock_lock, 0)) { @@ -401,7 +401,7 @@ For internal use by `threading.Condition`."); static PyObject * rlock_release_save(rlockobject *self) { - long owner; + unsigned long owner; unsigned long count; if (self->rlock_count == 0) { @@ -415,7 +415,7 @@ rlock_release_save(rlockobject *self) self->rlock_count = 0; self->rlock_owner = 0; PyThread_release_lock(self->rlock_lock); - return Py_BuildValue("kl", count, owner); + return Py_BuildValue("kk", count, owner); } PyDoc_STRVAR(rlock_release_save_doc, @@ -427,7 +427,7 @@ For internal use by `threading.Condition`."); static PyObject * 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) { Py_RETURN_TRUE; @@ -1031,7 +1031,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) { PyObject *func, *args, *keyw = NULL; struct bootstate *boot; - long ident; + unsigned long ident; if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, &func, &args, &keyw)) @@ -1068,7 +1068,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) Py_XINCREF(keyw); PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ 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"); Py_DECREF(func); Py_DECREF(args); @@ -1077,7 +1077,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) PyMem_DEL(boot); return NULL; } - return PyLong_FromLong(ident); + return PyLong_FromUnsignedLong(ident); } PyDoc_STRVAR(start_new_doc, @@ -1137,13 +1137,12 @@ information about locks."); static PyObject * thread_get_ident(PyObject *self) { - long ident; - ident = PyThread_get_thread_ident(); - if (ident == -1) { + unsigned long ident = PyThread_get_thread_ident(); + if (ident == PYTHREAD_INVALID_THREAD_ID) { PyErr_SetString(ThreadError, "no current thread ident"); return NULL; } - return PyLong_FromLong(ident); + return PyLong_FromUnsignedLong(ident); } PyDoc_STRVAR(get_ident_doc, diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 9e16f322914..2a4e935e43e 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -395,16 +395,17 @@ PyDoc_STRVAR(signal_pthread_kill__doc__, {"pthread_kill", (PyCFunction)signal_pthread_kill, METH_FASTCALL, signal_pthread_kill__doc__}, 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 * signal_pthread_kill(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - long thread_id; + unsigned long thread_id; int signalnum; - if (!_PyArg_ParseStack(args, nargs, "li:pthread_kill", + if (!_PyArg_ParseStack(args, nargs, "ki:pthread_kill", &thread_id, &signalnum)) { goto exit; } @@ -463,4 +464,4 @@ exit: #ifndef SIGNAL_PTHREAD_KILL_METHODDEF #define 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]*/ diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 4fc8ebd4e39..4a03eaf96a8 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -678,7 +678,7 @@ faulthandler_dump_traceback_later(PyObject *self, /* Arm these locks to serve as events when released */ 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); Py_CLEAR(thread.file); PyMem_Free(header); diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index bc36d41648e..ed036832957 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -88,7 +88,7 @@ module signal #ifdef WITH_THREAD #include /* For pid_t */ #include "pythread.h" -static long main_thread; +static unsigned long main_thread; static pid_t main_pid; #endif @@ -1088,7 +1088,7 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, /*[clinic input] signal.pthread_kill - thread_id: long + thread_id: unsigned_long(bitwise=True) signalnum: int / @@ -1096,8 +1096,9 @@ Send a signal to a thread. [clinic start generated code]*/ static PyObject * -signal_pthread_kill_impl(PyObject *module, long thread_id, int signalnum) -/*[clinic end generated code: output=2a09ce41f1c4228a input=77ed6a3b6f2a8122]*/ +signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, + int signalnum) +/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/ { int err; diff --git a/Python/ceval.c b/Python/ceval.c index fd60b7344a2..e7ee772d9f6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -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}; diff --git a/Python/import.c b/Python/import.c index 0fc4d1da547..17a320b122a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -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 diff --git a/Python/pystate.c b/Python/pystate.c index 65c244e6f73..8e81707c7cc 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -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); diff --git a/Python/thread.c b/Python/thread.c index 63eeb1e123f..3a52e1e8923 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -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) diff --git a/Python/thread_foobar.h b/Python/thread_foobar.h index ea96f9c9d79..45cfd1bb6fd 100644 --- a/Python/thread_foobar.h +++ b/Python/thread_foobar.h @@ -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) diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 74a6ee80298..8158ff82487 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -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 */ diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index ba7393f03de..b95840ce2d7 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -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 diff --git a/Python/traceback.c b/Python/traceback.c index 9f8c568b08a..b52385ef12f 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -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"); }