Skip to content

Commit 65893c6

Browse files
authored
gh-116738: Make syslog module thread-safe (#136760)
Make the setlogmask() function in the syslog module thread-safe. These changes are relevant for scenarios where the GIL is disabled or when using subinterpreters.
1 parent 5f9e38f commit 65893c6

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import unittest
2+
import threading
3+
4+
from test.support import import_helper, threading_helper
5+
from test.support.threading_helper import run_concurrently
6+
7+
syslog = import_helper.import_module("syslog")
8+
9+
NTHREADS = 32
10+
11+
# Similar to Lib/test/test_syslog.py, this test's purpose is to verify that
12+
# the code neither crashes nor leaks.
13+
14+
15+
@threading_helper.requires_working_threading()
16+
class TestSyslog(unittest.TestCase):
17+
def test_racing_syslog(self):
18+
def worker():
19+
"""
20+
The syslog module provides the following functions:
21+
openlog(), syslog(), closelog(), and setlogmask().
22+
"""
23+
thread_id = threading.get_ident()
24+
syslog.openlog(f"thread-id: {thread_id}")
25+
try:
26+
for _ in range(5):
27+
syslog.syslog("logline")
28+
syslog.setlogmask(syslog.LOG_MASK(syslog.LOG_INFO))
29+
syslog.syslog(syslog.LOG_INFO, "logline LOG_INFO")
30+
syslog.setlogmask(syslog.LOG_MASK(syslog.LOG_ERR))
31+
syslog.syslog(syslog.LOG_ERR, "logline LOG_ERR")
32+
syslog.setlogmask(syslog.LOG_UPTO(syslog.LOG_DEBUG))
33+
finally:
34+
syslog.closelog()
35+
36+
# Run the worker concurrently to exercise all these syslog functions
37+
run_concurrently(
38+
worker_func=worker,
39+
nthreads=NTHREADS,
40+
)
41+
42+
43+
if __name__ == "__main__":
44+
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Make functions in :mod:`syslog` thread-safe on the :term:`free threaded
2+
<free threading>` build.

Modules/syslogmodule.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,13 @@ syslog_setlogmask_impl(PyObject *module, long maskpri)
298298
return -1;
299299
}
300300

301-
return setlogmask(maskpri);
301+
static PyMutex setlogmask_mutex = {0};
302+
PyMutex_Lock(&setlogmask_mutex);
303+
// Linux man page (3): setlogmask() is MT-Unsafe race:LogMask.
304+
long previous_mask = setlogmask(maskpri);
305+
PyMutex_Unlock(&setlogmask_mutex);
306+
307+
return previous_mask;
302308
}
303309

304310
/*[clinic input]

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy