Skip to content

Commit 0be4ebe

Browse files
committed
add a docker compose to compile the code
release gil before sending a log to journald and release afterwards Readme builder updates make wheel clean
1 parent cb50f8b commit 0be4ebe

8 files changed

Lines changed: 92 additions & 3 deletions

File tree

Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM python:3.11-slim
2+
3+
# Install compilation dependencies
4+
RUN apt-get update && apt-get install -y \
5+
gcc \
6+
pkg-config \
7+
libsystemd-dev \
8+
make \
9+
git \
10+
meson \
11+
jq \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
RUN pip install --no-cache-dir wheel build
15+
16+
WORKDIR /src
17+
18+
# Fix git ownership issue
19+
RUN git config --global --add safe.directory /src

Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ all: build
1414
build:
1515
$(PYTHON) -m build -Cbuild-dir=$(BUILD_DIR)
1616

17+
wheel:
18+
rm -rf $(BUILD_DIR)
19+
$(PYTHON) -m build --wheel -Cbuild-dir=$(BUILD_DIR) -Csetup-args="-Djournal_unlock_gil=1"
20+
21+
wheel_gil:
22+
rm -rf $(BUILD_DIR)
23+
$(PYTHON) -m build --wheel -Cbuild-dir=$(BUILD_DIR) -Csetup-args="-Djournal_unlock_gil=0"
24+
1725
install:
1826
$(PYTHON) -m pip install .
1927

@@ -24,7 +32,7 @@ sign: dist/systemd-python-$(VERSION).tar.gz
2432
gpg --detach-sign -a dist/systemd-python-$(VERSION).tar.gz
2533

2634
clean:
27-
rm -rf $(BUILD_DIR) systemd/*.so systemd/*.py[co] *.py[co] systemd/__pycache__
35+
rm -rf $(BUILD_DIR) systemd/*.so systemd/*.py[co] *.py[co] systemd/__pycache__ dist
2836

2937
distclean: clean
3038
rm -rf dist MANIFEST

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@ is separated into a number of modules:
1212
- `systemd.login` wraps parts of `libsystemd` used to query logged in users
1313
and available seats and machines.
1414

15+
Build
16+
============
17+
18+
make is mirrored into docker-compose, to turn the build independent of packages installed (at least for debian systems)
19+
20+
mkdir dist
21+
mkdir build
22+
23+
to run make all:
24+
25+
docker compose run --rm make
26+
27+
to run any make command
28+
29+
docker compose run --rm make $command
30+
31+
for example
32+
33+
docker compose run --rm make wheel
34+
docker compose run --rm make clean
35+
docker compose run --rm make build
36+
docker compose run --rm make check
37+
1538
Installation
1639
============
1740

@@ -133,7 +156,7 @@ Show kernel ring buffer (`journalctl -k`):
133156
print(entry['MESSAGE'])
134157

135158
Read entries in reverse (`journalctl _EXE=/usr/bin/vim -r`):
136-
159+
137160
from systemd import journal
138161
class ReverseReader(journal.Reader):
139162
def __next__(self):

docker-compose.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
make:
3+
build: .
4+
volumes:
5+
- .:/src
6+
- ./build:/build
7+
- ./dist:/dist
8+
entrypoint: /usr/bin/make
9+
command: all

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_project_arguments(
2121
'-D_GNU_SOURCE=1',
2222
'-DPACKAGE_VERSION="@0@"'.format(meson.project_version()),
2323
'-DLIBSYSTEMD_VERSION=@0@'.format(libsystemd_dep.version()),
24+
'-DSD_JOURNAL_SENDV_UNLOCK_GIL=@0@'.format(get_option('journal_unlock_gil')),
2425
language : 'c',
2526
)
2627

meson.options

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: LGPL-2.1-or-later
22

33
option('docs', type : 'boolean', value : false)
4+
option('journal_unlock_gil', type: 'integer', value: 1, description: 'unlock gil before sending log to journal')

src/systemd/_journal.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88
#include "macro.h"
99
#include "pyutil.h"
1010

11+
12+
#if defined(SD_JOURNAL_SENDV_UNLOCK_GIL) && (SD_JOURNAL_SENDV_UNLOCK_GIL == 1)
13+
#define JOURNAL_SENDV_UNLOCK_GIL 1
14+
#else
15+
#define JOURNAL_SENDV_UNLOCK_GIL 0
16+
#endif
17+
18+
1119
PyDoc_STRVAR(journal_sendv__doc__,
1220
"sendv('FIELD=value', 'FIELD=value', ...) -> None\n\n"
1321
"Send an entry to the journal."
@@ -43,8 +51,14 @@ static PyObject* journal_sendv(PyObject *self _unused_, PyObject *args) {
4351
iov[i].iov_len = length;
4452
}
4553

54+
#if (JOURNAL_SENDV_UNLOCK_GIL == 1)
55+
Py_BEGIN_ALLOW_THREADS
56+
#endif
4657
/* Send the iovector to the journal. */
4758
r = sd_journal_sendv(iov, argc);
59+
#if (JOURNAL_SENDV_UNLOCK_GIL == 1)
60+
Py_END_ALLOW_THREADS
61+
#endif
4862
if (r < 0) {
4963
errno = -r;
5064
PyErr_SetFromErrno(PyExc_OSError);
@@ -111,6 +125,11 @@ PyMODINIT_FUNC PyInit__journal(void) {
111125
return NULL;
112126
}
113127

128+
if (PyModule_AddIntConstant(m, "__sendv_unlock_gil__", JOURNAL_SENDV_UNLOCK_GIL)) {
129+
Py_DECREF(m);
130+
return NULL;
131+
}
132+
114133
return m;
115134
}
116135
REENABLE_WARNING;

src/systemd/journal.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
1010
LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG)
1111

12-
from ._journal import __version__, sendv, stream_fd
12+
from ._journal import __version__, sendv, stream_fd, __sendv_unlock_gil__
1313
from ._reader import (_Reader, NOP, APPEND, INVALIDATE,
1414
LOCAL_ONLY, RUNTIME_ONLY,
1515
SYSTEM, SYSTEM_ONLY, CURRENT_USER,
@@ -538,6 +538,15 @@ def __init__(self, level=_logging.NOTSET, sender_function=send, **kwargs):
538538
self.send = sender_function
539539
self._extra = kwargs
540540

541+
@staticmethod
542+
def gil_unlocked():
543+
"""Return whether the journal send function is configured to unlock the GIL.
544+
545+
This is useful for logging handlers to determine whether they can safely
546+
call the send function without risking deadlocks.
547+
"""
548+
return __sendv_unlock_gil__ == 1
549+
541550
@classmethod
542551
def with_args(cls, config=None):
543552
"""Create a JournalHandler with a configuration dictionary

0 commit comments

Comments
 (0)