Skip to content

Fixes SIGSEGV and improve thread safety of journal.Reader class #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

sebres
Copy link

@sebres sebres commented Apr 1, 2025

This PR fixes threaded issues of journal.Reader class and improves its thread-safety, using simple protection with ref-counter;
It would avoid segfault by closing journal across threads.

The algorithm is simple, here short explanation illustrating the approach on an example of #143:

TH Action ref_count j_handle
... Reader created and has initial ref-count 1 1 valid
A Enter Reader_wait(), increment ref-count, release the lock (GIL), enter sd_journal_wait() 2 valid
A Leave sd_journal_wait(), acquiring the lock (GIL), decrement ref-count, not calling sd_journal_close() because of ref_count == 1, leave Reader_wait() 1 valid
- ... now thread A repeats the wait() however thread B invokes close() in-between ... - -
A Enter Reader_wait(), increment ref-count, release the lock (GIL), enter sd_journal_wait() 2 valid
B Enter Reader_close(), set closed flag, decrement ref-count, but don't close it because of ref_count > 0 1 valid
A Leave sd_journal_wait(), acquiring the lock (GIL), decrement ref-count, calling sd_journal_close() because of ref_count == 0, leave Reader_wait() 0 NULL

If thread B manages to close the handle before A enters wait mode, it is also safe, because then sd_journal_wait() would generate EINVARG and Reader.wait() raises an error ([Errno 22] Invalid argument).

Anyway, no segfault happens anymore and it is more or less thread-safe.

closes gh-143

sebres added 2 commits April 1, 2025 16:33
…th ref-counter; avoid segfault by closing journal across threads (closes systemdgh-143)
…ids unexpected states on repeated Reader.close)
@sebres sebres force-pushed the gh-143-sf-fix branch 2 times, most recently from 5a7719b to 03eec9d Compare April 2, 2025 16:31
@sebres
Copy link
Author

sebres commented Apr 2, 2025

7c99a39 seems to fix the GHA flows now (completely different issue), so can be cherry-picked to main branch as it is (or I could make a separate PR if necessary).

@sebres
Copy link
Author

sebres commented Jun 4, 2025

Ping.
Is this repository alive?

concurrency:
group: ${{ github.workflow }}-${{ matrix.python }}-${{ github.ref }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
python: [
"3.7",
"3.8",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should probably be dropped as well, since it is EOL or in other words: with 3.7 dropped I see no reason not to drop 3.8

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dropped 3.7 only because of switch to ubuntu-latest, which doesn't have it.
I don't see any reason to drop 3.8. at least as long as it is compatible and running yet.
Anyway has nothing to do with the PR as is, I made the changes just in order to repair the GHA flow.

@@ -43,6 +44,9 @@ jobs:
run: |
sudo apt -y update
sudo apt -y install gcc libsystemd-dev
if dpkg --compare-versions "${{ matrix.python }}" ge 3.12; then
python -m pip install setuptools || echo "can't install setuptools"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might make sense to always install setuptools, so that all versions are tested with the same?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dunno... IMHO, only 3.12+ missing it as package, but I am unsure the attempt to install with pip for previous versions would be always successful (and not fail due to conflict with preinstalled package).
I can imagine it could.

@hongquan
Copy link

The PR #147 will help fix the GH Action headache for this PR.

@sebres
Copy link
Author

sebres commented Jun 30, 2025

The PR #147 will help fix the GH Action headache for this PR.

Hmm... There is basically no problem to fix "for this PR" - as you can see all GHA checks are passed.
Nothing about #147 (maybe it solves more, no time to review), just... actually everything work here in this PR as expected.

Copy link
Member

@keszybz keszybz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the thread-safety stuff is confused. The last commit seems useful, it might be worth submitting it as a separate PR.

Note we also have #148 which tries to update the build system.

@@ -64,6 +64,8 @@
typedef struct {
PyObject_HEAD
sd_journal *j;
unsigned closed;
unsigned ref_count;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, please explain the reasoning behind a patch in the commit message. For something like thread safety, this is particularly important. Without that, the reader is left to guess.

I don't understand how this is supposed to help. This is a python object, and PyObject_HEAD above already embeds a reference counter. A second reference counter in the same struct is unexpected.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you did provide an explanation, but in the pull request ticket. I was looking at the patches and missed that. Sorry. (The explanation still belongs in the commit message, not on a pull request.)

I'll reply further in #143, because you make some good points there.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explanation still belongs in the commit message, not on a pull request.

Well, matter of taste either (many repo-owners like to hold the commit messages as short as possible)...
But it can be added to the merge commit, can not it?
Or do you rather want that the PR branch gets rebased instead (with details in the commit)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

SIGSEGV using journal.Reader, thread safety issue?
4 participants
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