FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-158929: Fix subinterpreter thread safety issues in `syslog` by ZeroIntensity · Pull Request #159000 · python/cpython · GitHub

Repository navigation

Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .py  (1) .rst  (1) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
23 changes: 23 additions & 0 deletions Lib/test/test_syslog.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,29 @@ def test_subinterpreter_closelog(self):
finally:
syslog.closelog()

@threading_helper.requires_working_threading()
def test_subinterpreter_concurrent_syslog(self):
# gh-158929: This used to crash.
from concurrent import interpreters

interp = interpreters.create()
try:
def in_interpreter():
import syslog

for _ in range(40000):
try:
syslog.syslog('my hovercraft is full of eels')
except RuntimeError:
pass
thread = interp.call_in_thread(in_interpreter)
for i in range(40000):
syslog.openlog(f"python{i}")
syslog.closelog()
thread.join()
finally:
interp.close()


if __name__ == "__main__":
unittest.main()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix crash when calling :func:`syslog.syslog` while a subinterpreter in
another thread calls :func:`syslog.openlog` or :func:`syslog.closelog`.
16 changes: 6 additions & 10 deletions Modules/syslogmodule.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module syslog
/* only one instance, only one syslog, so globals should be ok,
* these fields are writable from the main interpreter only. */
static PyObject *S_ident_o = NULL; // identifier, held by openlog()
static char S_log_open = 0;
static int S_log_open = 0;

static inline int
is_main_interpreter(void)
Expand Down Expand Up @@ -189,7 +189,7 @@ syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt,
}

openlog(ident_str, logopt, facility);
S_log_open = 1;
_Py_atomic_store_int(&S_log_open, 1);
Py_XSETREF(S_ident_o, ident);

Py_RETURN_NONE;
Expand Down Expand Up @@ -222,7 +222,7 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int priority,
}

/* if log is not opened, open it now */
if (!S_log_open) {
if (!_Py_atomic_load_int(&S_log_open)) {
if (!is_main_interpreter()) {
PyErr_SetString(PyExc_RuntimeError, "subinterpreter can't use syslog.syslog() "
"until the syslog is opened by the main interpreter");
Expand All @@ -235,10 +235,6 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int priority,
Py_DECREF(openlog_ret);
}

/* Incref ident, because it can be decrefed if syslog.openlog() is
* called when the GIL is released.
*/
PyObject *ident = Py_XNewRef(S_ident_o);
#ifdef __APPLE__
// gh-98178: On macOS, libc syslog() is not thread-safe
syslog(priority, "%s", message);
Expand All @@ -247,7 +243,6 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int priority,
syslog(priority, "%s", message);
Py_END_ALLOW_THREADS;
#endif
Py_XDECREF(ident);
Py_RETURN_NONE;
}

Expand All @@ -273,10 +268,11 @@ syslog_closelog_impl(PyObject *module)
if (PySys_Audit("syslog.closelog", NULL) < 0) {
return NULL;
}
if (S_log_open) {

int was_open = _Py_atomic_exchange_int(&S_log_open, 0);
if (was_open) {
closelog();
Py_CLEAR(S_ident_o);
S_log_open = 0;
}
Py_RETURN_NONE;
}
Expand Down
Loading

Back | FazBrowse Home | New Git URL