Skip to content
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

Handle signals with kqueue #112

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Handle signals with kqueue #112

wants to merge 2 commits into from

Conversation

nirs
Copy link
Member

@nirs nirs commented Dec 15, 2024

We used sigsetjmp() and siglogjmp() for signal handling, which is very
hard to use correctly and too magical. Replace it with the kqueue(),
which can notify events on sockets and signals.

The get signals with kqueue, we need to block them. This has the nice
property that no function in any thread will fail with EINTR when we
receive a signal, which simplifies the code.

We setup signal handling before we open the pidfile, so receiving a
signal after the pidfile was created will always remove the pidfile.
Before this change we has a small window when receiving a signal would
terminate the process without removing the pidfile.

To wait for connection or signal, we wait for kqueue events. If we
receiving a signal we break the loop and exit normally, since
termination by signal is normal. This can help programs running
socket_vment that may be confused by exit code 1.

Notes:

  • Keeping listen_fd in blocking mode to simplify the code. accept()
    should not block when we receive a EVFILT_READ event. We can change to
    non-blocking mode later if this assumption is wrong.

We initialized some variables at the top of main(), and some before the
first use. Since these variables are used during cleanup it makes sense
to initialize all of them at the top.

Use one variable per line to make the code easier to read.

Signed-off-by: Nir Soffer <[email protected]>
@nirs nirs closed this Dec 15, 2024
@nirs nirs reopened this Dec 15, 2024
@AkihiroSuda AkihiroSuda added this to the v1.2.2 milestone Dec 15, 2024
We used sigsetjmp() and siglogjmp() for signal handling, which is very
hard to use correctly and too magical. Replace it with the kqueue(),
which can notify events on sockets and signals.

The get signals with kqueue, we need to block them. This has the nice
property that no function in any thread will fail with EINTR when we
receive a signal, which simplifies the code.

We setup signal handling before we open the pidfile, so receiving a
signal after the pidfile was created will always remove the pidfile.
Before this change we has a small window when receiving a signal would
terminate the process without removing the pidfile.

To wait for connection or signal, we wait for kqueue events. If we
receiving a signal we break the loop and exit normally, since
termination by signal is normal. This can help programs running
socket_vment that may be confused by exit code 1.

Notes:

- Keeping listen_fd in blocking mode to simplify the code. accept()
  should not block when we receive a EVFILT_READ event. We can change to
  non-blocking mode later if this assumption is wrong.

Signed-off-by: Nir Soffer <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants