High level API: first take.

poll
Karchnu 2020-07-02 21:13:54 +02:00
parent 6f5aa676b5
commit ac7bb07d95
3 changed files with 98 additions and 91 deletions

View File

@ -3,18 +3,22 @@ require "./message"
require "./event"
class IPC::Connection
getter ctx : LibIPC::Ctx
getter connection : LibIPC::Connection
getter closed = false
# connection already established
def initialize(c : LibIPC::Connection)
@connection = c
def initialize(c : LibIPC::Ctx)
@ctx = c
end
# def initialize(c : LibIPC::Connection)
# @connection = c
# end
def initialize(service_name : String)
@connection = LibIPC::Connection.new
@ctx = LibIPC::Ctx.new
r = LibIPC.ipc_connection(LibC.environ, self.pointer, service_name)
r = LibIPC.ipc_connection(self.pointer, service_name)
if r.error_code != 0
m = String.new r.error_message.to_slice
raise Exception.new "error during connection establishment: #{m}"
@ -148,15 +152,10 @@ class IPC::Connections
end
end
def wait_event(server : IPC::Connection | Nil, &block) : Tuple(LibIPC::EventType, IPC::Message, IPC::Connection) | Tuple(LibIPC::EventType, Nil, Nil)
def wait_event(&block) : IPC::Event::Events | Exception
event = LibIPC::Event.new
serverp = nil
unless server.nil?
serverp = server.pointer
end
r = LibIPC.ipc_wait_event self.pointer, serverp, pointerof(event), pointerof(@timer)
r = LibIPC.ipc_events_loop self.pointer, pointerof(event), pointerof(@timer)
if r.error_code != 0
m = String.new r.error_message.to_slice
yield IPC::Exception.new "error waiting for a new event: #{m}"
@ -166,52 +165,41 @@ class IPC::Connections
# if event type is Timer, there is no connection nor message
case eventtype
when LibIPC::EventType::Timer
return eventtype, nil, nil
when LibIPC::EventType::NotSet
return Exception.new "'Event type: not set"
when LibIPC::EventType::Error
return IPC::Event::Error.new event.index, event.origin
when LibIPC::EventType::ExtraSocket # Message received from a non IPC socket.
return IPC::Event::ExtraSocket.new event.origin, event.index
when LibIPC::EventType::Switch # Message to send to a corresponding fd.
return IPC::Event::Switch.new event.origin, event.index
when LibIPC::EventType::Connection # New user.
return IPC::Event::Connection.new event.origin, event.index
when LibIPC::EventType::Disconnection # User disconnected.
return IPC::Event::Disconnection.new event.origin, event.index
when LibIPC::EventType::Message # New message.
message = event.message.unsafe_as(Pointer(LibIPC::Message))
return IPC::Event::MessageReceived.new event.origin, event.index, message
when LibIPC::EventType::LookUp # Client asking for a service through ipcd.
# for now, the libipc does not provide lookup events
# ipcd uses a simple LibIPC::EventType::Message
return IPC::Event::LookUp.new event.origin, event.index
when LibIPC::EventType::Timer # Timeout in the poll(2) function.
return IPC::Event::Timer.new
when LibIPC::EventType::Tx # Message sent.
return IPC::Event::Tx.new event.origin, event.index
end
connection = IPC::Connection.new event.origin.unsafe_as(Pointer(LibIPC::Connection)).value
message = event.message.unsafe_as(Pointer(LibIPC::Message))
return eventtype, IPC::Message.new(message), connection
yield Exception.new "Cannot understand the event type: #{eventtype}"
end
def loop(server : IPC::Connection | IPC::Server | ::Nil, &block : Proc(IPC::Event::Events|Exception, Nil))
def loop(&block : Proc(IPC::Event::Events|Exception, Nil))
if @base_timer > 0 && @timer == 0
@timer = @base_timer
end
::loop do
type, message, connection = wait_event server, &block
case type
when LibIPC::EventType::Timer
# reset timer
@timer = @base_timer
yield IPC::Event::Timer.new
when LibIPC::EventType::Connection
yield IPC::Event::Connection.new connection.not_nil!
when LibIPC::EventType::NotSet
yield IPC::Exception.new "even type not set"
when LibIPC::EventType::Error
yield IPC::Exception.new "even type indicates an error"
when LibIPC::EventType::ExtraSocket
yield IPC::Event::ExtraSocket.new message.not_nil!, connection.not_nil!
when LibIPC::EventType::Switch
yield IPC::Event::Switch.new message.not_nil!, connection.not_nil!
when LibIPC::EventType::Message
yield IPC::Event::Message.new message.not_nil!, connection.not_nil!
# for now, the libipc does not provide lookup events
# networkd uses a simple LibIPC::EventType::Message
# when LibIPC::EventType::LookUp
# yield IPC::Event::LookUp.new message, connection
yield wait_event &block
when LibIPC::EventType::Disconnection
yield IPC::Event::Disconnection.new connection.not_nil!
@ -221,10 +209,10 @@ class IPC::Connections
# sanitizer
def pointer
pointerof(@connections)
pointerof(@ctx)
end
def pp
LibIPC.ipc_connections_print @connections
end
# def pp
# LibIPC.ipc_connections_print @connections
# end
end

View File

@ -3,37 +3,55 @@ require "./message"
require "./connection"
class IPC::Event
alias Events = IPC::Event::Timer | IPC::Event::Connection | IPC::Event::Disconnection | IPC::Event::Message | IPC::Event::ExtraSocket | IPC::Event::Switch | IPC::Event::LookUp
alias Events = IPC::Event::Timer |
IPC::Event::Error |
IPC::Event::Connection |
IPC::Event::Disconnection |
IPC::Event::MessageReceived |
IPC::Event::ExtraSocket |
IPC::Event::Switch |
IPC::Event::LookUp |
IPC::Event::MessageSent
end
class Timer
end
class Connection
getter connection : IPC::Connection
def initialize(@connection)
end
end
class Disconnection
getter connection : IPC::Connection
def initialize(@connection)
end
end
class Message
getter message : ::IPC::Message
getter connection : IPC::Connection
def initialize(@message, @connection)
end
end
class ExtraSocket < IPC::Event::Message
end
class Switch < IPC::Event::Message
end
class LookUp < IPC::Event::Message
class IPC::Event::Timer < IPC::Event
def initialize
end
end
class IPC::Event::Base < IPC::Event
getter fd : Int
getter index : UInt64
def initialize(@fd, @index)
end
end
class IPC::Event::Connection < IPC::Event::Base
end
class IPC::Event::Disconnection < IPC::Event::Base
end
class IPC::Event::Error < IPC::Event::Base
end
class IPC::Event::MessageReceived < IPC::Event::Base
getter message : ::IPC::Message
def initialize(@fd, @index, @message)
end
end
class IPC::Event::ExtraSocket < IPC::Event::Base
end
class IPC::Event::Switch < IPC::Event::Base
end
class IPC::Event::LookUp < IPC::Event::Base
end
class IPC::Event::MessageSent < IPC::Event::Base
end

View File

@ -51,15 +51,16 @@ lib LibIPC
end
enum EventType
NotSet
Error
ExtraSocket
Switch
Connection
Disconnection
Message
LookUp
Timer
NotSet #
Error #
ExtraSocket # Message received from a non IPC socket.
Switch # Message to send to a corresponding fd.
Connection # New user.
Disconnection # User disconnected.
Message # New message.
LookUp # Client asking for a service through ipcd.
Timer # Timeout in the poll(2) function.
Tx # Message sent.
end
struct Event