Skip to content

Commit 6ebf768

Browse files
committed
gh-99127: Port syslog module to use module state.
1 parent b5f7111 commit 6ebf768

File tree

2 files changed

+55
-11
lines changed

2 files changed

+55
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Port :mod:`syslog` to use module state. Patch by Dong-hee Na.

Modules/syslogmodule.c

+54-11
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,18 @@ module syslog
6161

6262
#include "clinic/syslogmodule.c.h"
6363

64-
/* only one instance, only one syslog, so globals should be ok */
65-
static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */
66-
static char S_log_open = 0;
64+
typedef struct {
65+
PyObject *S_ident_o; /* identifier, held by openlog() */
66+
char S_log_open;
67+
} _syslog_state;
6768

69+
static inline _syslog_state*
70+
get_syslog_state(PyObject *module)
71+
{
72+
void *state = PyModule_GetState(module);
73+
assert(state != NULL);
74+
return (_syslog_state *)state;
75+
}
6876

6977
static PyObject *
7078
syslog_get_argv(void)
@@ -162,8 +170,9 @@ syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt,
162170
}
163171

164172
openlog(ident_str, logopt, facility);
165-
S_log_open = 1;
166-
Py_XSETREF(S_ident_o, ident);
173+
_syslog_state *state = get_syslog_state(module);
174+
state->S_log_open = 1;
175+
Py_XSETREF(state->S_ident_o, ident);
167176

168177
Py_RETURN_NONE;
169178
}
@@ -193,8 +202,9 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int priority,
193202
return NULL;
194203
}
195204

205+
_syslog_state *state = get_syslog_state(module);
196206
/* if log is not opened, open it now */
197-
if (!S_log_open) {
207+
if (!state->S_log_open) {
198208
PyObject *openlog_ret = syslog_openlog_impl(module, NULL, 0, LOG_USER);
199209
if (openlog_ret == NULL) {
200210
return NULL;
@@ -205,7 +215,7 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int priority,
205215
/* Incref ident, because it can be decrefed if syslog.openlog() is
206216
* called when the GIL is released.
207217
*/
208-
PyObject *ident = S_ident_o;
218+
PyObject *ident = state->S_ident_o;
209219
Py_XINCREF(ident);
210220
#ifdef __APPLE__
211221
// gh-98178: On macOS, libc syslog() is not thread-safe
@@ -233,10 +243,12 @@ syslog_closelog_impl(PyObject *module)
233243
if (PySys_Audit("syslog.closelog", NULL) < 0) {
234244
return NULL;
235245
}
236-
if (S_log_open) {
246+
247+
_syslog_state *state = get_syslog_state(module);
248+
if (state->S_log_open) {
237249
closelog();
238-
Py_CLEAR(S_ident_o);
239-
S_log_open = 0;
250+
Py_CLEAR(state->S_ident_o);
251+
state->S_log_open = 0;
240252
}
241253
Py_RETURN_NONE;
242254
}
@@ -315,6 +327,11 @@ syslog_exec(PyObject *module)
315327
return -1; \
316328
} \
317329
} while (0)
330+
331+
_syslog_state *state = get_syslog_state(module);
332+
state->S_ident_o = NULL;
333+
state->S_log_open = 0;
334+
318335
/* Priorities */
319336
ADD_INT_MACRO(module, LOG_EMERG);
320337
ADD_INT_MACRO(module, LOG_ALERT);
@@ -380,6 +397,29 @@ syslog_exec(PyObject *module)
380397
return 0;
381398
}
382399

400+
static int
401+
_syslog_traverse(PyObject *module, visitproc visit, void *arg)
402+
{
403+
_syslog_state *state = get_syslog_state(module);
404+
Py_VISIT(state->S_ident_o);
405+
return 0;
406+
}
407+
408+
static int
409+
_syslog_clear(PyObject *module)
410+
{
411+
_syslog_state *state = get_syslog_state(module);
412+
Py_CLEAR(state->S_ident_o);
413+
state->S_log_open = 0;
414+
return 0;
415+
}
416+
417+
static void
418+
_syslog_free(void *module)
419+
{
420+
_syslog_clear((PyObject *)module);
421+
}
422+
383423
static PyModuleDef_Slot syslog_slots[] = {
384424
{Py_mod_exec, syslog_exec},
385425
{0, NULL}
@@ -390,9 +430,12 @@ static PyModuleDef_Slot syslog_slots[] = {
390430
static struct PyModuleDef syslogmodule = {
391431
PyModuleDef_HEAD_INIT,
392432
.m_name = "syslog",
393-
.m_size = 0,
433+
.m_size = sizeof(_syslog_state),
394434
.m_methods = syslog_methods,
395435
.m_slots = syslog_slots,
436+
.m_traverse = _syslog_traverse,
437+
.m_clear = _syslog_clear,
438+
.m_free = _syslog_free,
396439
};
397440

398441
PyMODINIT_FUNC

0 commit comments

Comments
 (0)