Visitar URL original
gh-104341: Minor Fixes in the _thread Module by ericsnowcurrently · Pull Request #104595 · python/cpython · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add module_thread.daemonic.
  • Loading branch information
ericsnowcurrently committed May 17, 2023
commit d10a24f17c98152d97a0a36c5a30639b72d2680f
2 changes: 1 addition & 1 deletion Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def run(self):

def test_limbo_cleanup(self):
# Issue 7481: Failure to start thread should cleanup the limbo map.
def fail_new_thread(*args):
def fail_new_thread(*args, **kwargs):
raise threading.ThreadError()
_start_new_thread = threading._start_new_thread
threading._start_new_thread = fail_new_thread
Expand Down
2 changes: 1 addition & 1 deletion Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ def start(self):
with _active_limbo_lock:
_limbo[self] = self
try:
_start_new_thread(self._bootstrap, ())
_start_new_thread(self._bootstrap, (), daemonic=self._daemonic)
except Exception:
with _active_limbo_lock:
del _limbo[self]
Expand Down
25 changes: 16 additions & 9 deletions Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ static struct PyModuleDef thread_module;

struct module_thread {
PyThreadState *tstate;
int daemonic;
};

static struct module_thread *
new_module_thread(PyInterpreterState *interp)
new_module_thread(PyInterpreterState *interp, int daemonic)
{
PyThreadState *tstate = _PyThreadState_New(interp);
if (tstate == NULL) {
Expand All @@ -51,6 +52,7 @@ new_module_thread(PyInterpreterState *interp)

*mt = (struct module_thread){
.tstate = tstate,
.daemonic = daemonic,
};
return mt;
}
Expand Down Expand Up @@ -1167,13 +1169,18 @@ Return True if daemon threads are allowed in the current interpreter,\n\
and False otherwise.\n");

static PyObject *
thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
thread_PyThread_start_new_thread(PyObject *self,
PyObject *fargs, PyObject *fkwargs)
{
char *kwlist[] = {"", "", "", "daemonic", NULL};
PyObject *func, *args, *kwargs = NULL;

if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
&func, &args, &kwargs))
int daemonic = 0;
if (!PyArg_ParseTupleAndKeywords(fargs, fkwargs,
"OO|Op:start_new_thread", kwlist,
&func, &args, &kwargs, &daemonic))
{
return NULL;
}
if (!PyCallable_Check(func)) {
PyErr_SetString(PyExc_TypeError,
"first arg must be callable");
Expand Down Expand Up @@ -1202,7 +1209,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
return NULL;
}

struct module_thread *mt = new_module_thread(interp);
struct module_thread *mt = new_module_thread(interp, daemonic);
if (mt == NULL) {
return NULL;
}
Expand All @@ -1227,7 +1234,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
}

PyDoc_STRVAR(start_new_doc,
"start_new_thread(function, args[, kwargs])\n\
"start_new_thread(function, args[, kwargs], daemonic=0)\n\
(start_new() is an obsolete synonym)\n\
\n\
Start a new thread and return its identifier. The thread will call the\n\
Expand Down Expand Up @@ -1607,9 +1614,9 @@ Handle uncaught Thread.run() exception.");

static PyMethodDef thread_methods[] = {
{"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
METH_VARARGS, start_new_doc},
METH_VARARGS | METH_KEYWORDS, start_new_doc},
{"start_new", (PyCFunction)thread_PyThread_start_new_thread,
METH_VARARGS, start_new_doc},
METH_VARARGS | METH_KEYWORDS, start_new_doc},
{"daemon_threads_allowed", (PyCFunction)thread_daemon_threads_allowed,
METH_NOARGS, daemon_threads_allowed_doc},
{"allocate_lock", thread_PyThread_allocate_lock,
Expand Down