Skip to content

Commit 1d3ec86

Browse files
committed
Clean up comments; add a final PyErr_Clear warning
1 parent 2854473 commit 1d3ec86

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

Modules/posixmodule.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6739,10 +6739,13 @@ os_register_at_fork_impl(PyObject *module, PyObject *before,
67396739
}
67406740
#endif /* HAVE_FORK */
67416741

6742-
// Common code to raise a warning if we know there is more than one thread
6743-
// running in the process. Best effort, silent if unable to count threads.
6744-
// Constraint: Avoids locks. Quick. Never leaves an error set.
6742+
// Common code to raise a warning if we detect there is more than one thread
6743+
// running in the process. Best effort, silent if unable to count threads.
6744+
// Constraint: Quick. Never overcounts. Never leaves an error set.
67456745
static void warn_about_fork_with_threads(const char* name) {
6746+
// TODO: Consider making an `os` module API to return the current number
6747+
// of threads in the process. That'd presumably use this platform code but
6748+
// raise an error rather than using the inaccurate fallback.
67466749
Py_ssize_t num_python_threads = 0;
67476750
#if defined(__APPLE__) && defined(HAVE_GETPID)
67486751
mach_port_t macos_self = mach_task_self();
@@ -6760,6 +6763,8 @@ static void warn_about_fork_with_threads(const char* name) {
67606763
FILE* proc_stat = fopen("/proc/self/stat", "r");
67616764
if (proc_stat) {
67626765
size_t n;
6766+
// Size chosen arbitrarily. ~60% more bytes than a 20th column index
6767+
// observed on the author's workstation.
67636768
char stat_line[160];
67646769
n = fread(&stat_line, 1, 159, proc_stat);
67656770
stat_line[n] = '\0';
@@ -6777,7 +6782,8 @@ static void warn_about_fork_with_threads(const char* name) {
67776782
}
67786783
#endif
67796784
if (num_python_threads <= 0) {
6780-
// Fall back to just the number of threads this CPython runtime knows about.
6785+
// Fall back to just the number of threads our threading module knows about.
6786+
// An incomplete view of the world, but better than nothing for our purpose.
67816787
PyObject *threading = PyImport_GetModule(&_Py_ID(threading));
67826788
if (!threading) {
67836789
PyErr_Clear();
@@ -6796,19 +6802,16 @@ static void warn_about_fork_with_threads(const char* name) {
67966802
Py_XDECREF(threading_active);
67976803
return;
67986804
}
6799-
// Worst case if someone replaced threading._active or threading._limbo
6800-
// with non-dicts, we get -1 from *Length() below and undercount.
6801-
// Whatever. That shouldn't happen, we're best effort so we clear errors
6802-
// and move on.
6803-
assert(PyMapping_Check(threading_active));
6804-
assert(PyMapping_Check(threading_limbo));
6805+
Py_DECREF(threading);
68056806
// Duplicating what threading.active_count() does but without holding
68066807
// threading._active_limbo_lock so our count could be inaccurate if these
68076808
// dicts are mid-update from another thread. Not a big deal.
6809+
// Worst case if someone replaced threading._active or threading._limbo
6810+
// with non-dicts, we get -1 from *Length() below and undercount.
6811+
// Nobody should, but we're best effort so we clear errors and move on.
68086812
num_python_threads = (PyMapping_Length(threading_active)
68096813
+ PyMapping_Length(threading_limbo));
68106814
PyErr_Clear();
6811-
Py_DECREF(threading);
68126815
Py_DECREF(threading_active);
68136816
Py_DECREF(threading_limbo);
68146817
}
@@ -6817,6 +6820,7 @@ static void warn_about_fork_with_threads(const char* name) {
68176820
PyExc_DeprecationWarning, 1,
68186821
"multi-threaded process detected, "
68196822
"use of %s() may lead to deadlocks in the child.", name);
6823+
PyErr_Clear();
68206824
}
68216825
}
68226826

0 commit comments

Comments
 (0)