Skip to content

Commit

Permalink
Extract libevent implementation of Crystal::EventLoop
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota committed Jul 25, 2019
1 parent c184ab1 commit 40e31c5
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 52 deletions.
File renamed without changes.
65 changes: 65 additions & 0 deletions src/crystal/event/event_loop_libevent.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
require "./event_libevent"

module Crystal::EventLoop
@@eb = Crystal::Event::Base.new
@@dns_base : Crystal::Event::DnsBase?

# Reinitializes the event loop after a fork.
def self.after_fork
@@eb.reinit
end

# Runs the event loop.
def self.resume
loop_fiber.resume
end

private def self.loop_fiber
@@loop_fiber ||= Fiber.new { @@eb.run_loop }
end

# Create a new resume event for a fiber.
def self.create_resume_event(fiber)
@@eb.new_event(-1, LibEvent2::EventFlags::None, fiber) do |s, flags, data|
data.as(Fiber).resume
end
end

# Creates a write event for a file descriptor.
def self.create_fd_write_event(io : IO::Evented, edge_triggered : Bool = false)
flags = LibEvent2::EventFlags::Write
flags |= LibEvent2::EventFlags::Persist | LibEvent2::EventFlags::ET if edge_triggered

@@eb.new_event(io.fd, flags, io) do |s, flags, data|
io_ref = data.as(typeof(io))
if flags.includes?(LibEvent2::EventFlags::Write)
io_ref.resume_write
elsif flags.includes?(LibEvent2::EventFlags::Timeout)
io_ref.resume_write(timed_out: true)
end
end
end

# Creates a read event for a file descriptor.
def self.create_fd_read_event(io : IO::Evented, edge_triggered : Bool = false)
flags = LibEvent2::EventFlags::Read
flags |= LibEvent2::EventFlags::Persist | LibEvent2::EventFlags::ET if edge_triggered

@@eb.new_event(io.fd, flags, io) do |s, flags, data|
io_ref = data.as(typeof(io))
if flags.includes?(LibEvent2::EventFlags::Read)
io_ref.resume_read
elsif flags.includes?(LibEvent2::EventFlags::Timeout)
io_ref.resume_read(timed_out: true)
end
end
end

private def self.dns_base
@@dns_base ||= @@eb.new_dns_base
end

def self.create_dns_request(nodename, servname, hints, data, &callback : LibEvent2::DnsGetAddrinfoCallback)
dns_base.getaddrinfo(nodename, servname, hints, data, &callback)
end
end
File renamed without changes.
74 changes: 22 additions & 52 deletions src/crystal/event_loop.cr
Original file line number Diff line number Diff line change
@@ -1,60 +1,30 @@
require "./event"

module Crystal::EventLoop
@@eb = Crystal::Event::Base.new
@@dns_base : Crystal::Event::DnsBase?

def self.after_fork
@@eb.reinit
end

def self.resume
loop_fiber.resume
end

private def self.loop_fiber
@@loop_fiber ||= Fiber.new { @@eb.run_loop }
end
# Runs the event loop.
# def self.resume : Nil

def self.create_resume_event(fiber)
@@eb.new_event(-1, LibEvent2::EventFlags::None, fiber) do |s, flags, data|
data.as(Fiber).resume
end
end
# Reinitializes the event loop after a fork.
# def self.after_fork : Nil

def self.create_fd_write_event(io : IO::Evented, edge_triggered : Bool = false)
flags = LibEvent2::EventFlags::Write
flags |= LibEvent2::EventFlags::Persist | LibEvent2::EventFlags::ET if edge_triggered
# Create a new resume event for a fiber.
# def self.create_resume_event(fiber : Fiber) : Crystal::Event

@@eb.new_event(io.fd, flags, io) do |s, flags, data|
io_ref = data.as(typeof(io))
if flags.includes?(LibEvent2::EventFlags::Write)
io_ref.resume_write
elsif flags.includes?(LibEvent2::EventFlags::Timeout)
io_ref.resume_write(timed_out: true)
end
end
end
# Creates a write event for a file descriptor.
# def self.create_fd_write_event(io : IO::Evented, edge_triggered : Bool = false)

def self.create_fd_read_event(io : IO::Evented, edge_triggered : Bool = false)
flags = LibEvent2::EventFlags::Read
flags |= LibEvent2::EventFlags::Persist | LibEvent2::EventFlags::ET if edge_triggered

@@eb.new_event(io.fd, flags, io) do |s, flags, data|
io_ref = data.as(typeof(io))
if flags.includes?(LibEvent2::EventFlags::Read)
io_ref.resume_read
elsif flags.includes?(LibEvent2::EventFlags::Timeout)
io_ref.resume_read(timed_out: true)
end
end
end
# Creates a read event for a file descriptor.
# def self.create_fd_read_event(io : IO::Evented, edge_triggered : Bool = false)
end

private def self.dns_base
@@dns_base ||= @@eb.new_dns_base
end
struct Crystal::Event
# Frees the event.
# def free : Nil

def self.create_dns_request(nodename, servname, hints, data, &callback : LibEvent2::DnsGetAddrinfoCallback)
dns_base.getaddrinfo(nodename, servname, hints, data, &callback)
end
# Adds a new timeout to this event.
# def add(time_span : Time::Span?) : Nil
end

{% if flag?(:unix) %}
require "./event/event_loop_libevent"
{% else %}
{% raise "event_loop not supported" %}
{% end %}

0 comments on commit 40e31c5

Please sign in to comment.