Skip to content

Commit

Permalink
Fix: EventLoop#interrupt for kqueue evloop
Browse files Browse the repository at this point in the history
  • Loading branch information
ysbaddaden committed Oct 15, 2024
1 parent 5e7f1aa commit 375253c
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 18 deletions.
7 changes: 7 additions & 0 deletions src/crystal/system/unix/kqueue.cr
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ struct Crystal::System::Kqueue
yield if ret == -1
end

# Helper to register a single event. Returns immediately.
def kevent(ident, filter, flags, fflags = 0, data = 0, udata = nil) : Nil
kevent(ident, filter, flags, fflags, data, udata) do
raise RuntimeError.from_errno("kevent")
end
end

# Helper to register multiple *changes*. Returns immediately.
def kevent(changes : Slice(LibC::Kevent), &) : Nil
ret = LibC.kevent(@kq, changes.to_unsafe, changes.size, nil, 0, nil)
Expand Down
30 changes: 17 additions & 13 deletions src/crystal/system/unix/kqueue/event_loop.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ class Crystal::Kqueue::EventLoop < Crystal::Evented::EventLoop

# notification to interrupt a run
@interrupted = Atomic::Flag.new
{% unless LibC.has_constant?(:EVFILT_USER) %}

{% if LibC.has_constant?(:EVFILT_USER) %}
@kqueue.kevent(
INTERRUPT_IDENTIFIER,
LibC::EVFILT_USER,
LibC::EV_ADD | LibC::EV_ENABLE | LibC::EV_CLEAR)
{% else %}
@pipe = System::FileDescriptor.system_pipe
@kqueue.kevent(@pipe[0], LibC::EVFILT_READ, LibC::EV_ADD) do
raise RuntimeError.from_errno("kevent")
end
@kqueue.kevent(@pipe[0], LibC::EVFILT_READ, LibC::EV_ADD)
{% end %}
end

Expand All @@ -47,12 +51,16 @@ class Crystal::Kqueue::EventLoop < Crystal::Evented::EventLoop
@kqueue = System::Kqueue.new

@interrupted.clear
{% unless LibC.has_constant?(:EVFILT_USER) %}

{% if LibC.has_constant?(:EVFILT_USER) %}
@kqueue.kevent(
INTERRUPT_IDENTIFIER,
LibC::EVFILT_USER,
LibC::EV_ADD | LibC::EV_ENABLE | LibC::EV_CLEAR)
{% else %}
@pipe.each { |fd| LibC.close(fd) }
@pipe = System::FileDescriptor.system_pipe
@kqueue.kevent(@pipe[0], LibC::EVFILT_READ, LibC::EV_ADD) do
raise RuntimeError.from_errno("kevent")
end
@kqueue.kevent(@pipe[0], LibC::EVFILT_READ, LibC::EV_ADD)
{% end %}

system_set_timer(@timers.next_ready?)
Expand Down Expand Up @@ -150,11 +158,7 @@ class Crystal::Kqueue::EventLoop < Crystal::Evented::EventLoop
return unless @interrupted.test_and_set

{% if LibC.has_constant?(:EVFILT_USER) %}
@kqueue.kevent(
INTERRUPT_IDENTIFIER,
LibC::EVFILT_USER,
LibC::EV_ADD | LibC::EV_ONESHOT,
LibC::NOTE_FFCOPY | LibC::NOTE_TRIGGER | 1_u16)
@kqueue.kevent(INTERRUPT_IDENTIFIER, LibC::EVFILT_USER, 0, LibC::NOTE_TRIGGER)
{% else %}
ident = INTERRUPT_IDENTIFIER
ret = LibC.write(@pipe[1], pointerof(ident), sizeof(Int32))
Expand Down
2 changes: 1 addition & 1 deletion src/lib_c/aarch64-darwin/c/sys/event.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ lib LibC

EV_ADD = 0x0001_u16
EV_DELETE = 0x0002_u16
EV_ENABLE = 0x0004_u16
EV_ONESHOT = 0x0010_u16
EV_CLEAR = 0x0020_u16
EV_EOF = 0x8000_u16
EV_ERROR = 0x4000_u16

NOTE_NSECONDS = 0x00000004_u32
NOTE_FFCOPY = 0xc0000000_u32
NOTE_TRIGGER = 0x01000000_u32

struct Kevent
Expand Down
2 changes: 1 addition & 1 deletion src/lib_c/x86_64-darwin/c/sys/event.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ lib LibC

EV_ADD = 0x0001_u16
EV_DELETE = 0x0002_u16
EV_ENABLE = 0x0004_u16
EV_ONESHOT = 0x0010_u16
EV_CLEAR = 0x0020_u16
EV_EOF = 0x8000_u16
EV_ERROR = 0x4000_u16

NOTE_NSECONDS = 0x00000004_u32
NOTE_FFCOPY = 0xc0000000_u32
NOTE_TRIGGER = 0x01000000_u32

struct Kevent
Expand Down
2 changes: 1 addition & 1 deletion src/lib_c/x86_64-dragonfly/c/sys/event.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ lib LibC

EV_ADD = 0x0001_u16
EV_DELETE = 0x0002_u16
EV_ENABLE = 0x0004_u16
EV_ONESHOT = 0x0010_u16
EV_CLEAR = 0x0020_u16
EV_EOF = 0x8000_u16
EV_ERROR = 0x4000_u16

NOTE_FFCOPY = 0xc0000000_u32
NOTE_TRIGGER = 0x01000000_u32

struct Kevent
Expand Down
2 changes: 1 addition & 1 deletion src/lib_c/x86_64-freebsd/c/sys/event.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ lib LibC

EV_ADD = 0x0001_u16
EV_DELETE = 0x0002_u16
EV_ENABLE = 0x0004_u16
EV_ONESHOT = 0x0010_u16
EV_CLEAR = 0x0020_u16
EV_EOF = 0x8000_u16
EV_ERROR = 0x4000_u16

NOTE_NSECONDS = 0x00000008_u32
NOTE_FFCOPY = 0xc0000000_u32
NOTE_TRIGGER = 0x01000000_u32

struct Kevent
Expand Down
2 changes: 1 addition & 1 deletion src/lib_c/x86_64-netbsd/c/sys/event.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ lib LibC

EV_ADD = 0x0001_u32
EV_DELETE = 0x0002_u32
EV_ENABLE = 0x0004_u16
EV_ONESHOT = 0x0010_u32
EV_CLEAR = 0x0020_u32
EV_EOF = 0x8000_u32
EV_ERROR = 0x4000_u32

NOTE_NSECONDS = 0x00000003_u32
NOTE_FFCOPY = 0xc0000000_u32
NOTE_TRIGGER = 0x01000000_u32

struct Kevent
Expand Down

0 comments on commit 375253c

Please sign in to comment.