From ac7bb07d95fafb2525eb8b6680cdae1079908f5b Mon Sep 17 00:00:00 2001 From: Karchnu Date: Thu, 2 Jul 2020 21:13:54 +0200 Subject: [PATCH] High level API: first take. --- src/ipc/connection.cr | 92 +++++++++++++++++++------------------------ src/ipc/event.cr | 78 ++++++++++++++++++++++-------------- src/ipc/lowlevel.cr | 19 ++++----- 3 files changed, 98 insertions(+), 91 deletions(-) diff --git a/src/ipc/connection.cr b/src/ipc/connection.cr index 87e1ffb..49fadb1 100644 --- a/src/ipc/connection.cr +++ b/src/ipc/connection.cr @@ -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 diff --git a/src/ipc/event.cr b/src/ipc/event.cr index 4d655d0..2d763c2 100644 --- a/src/ipc/event.cr +++ b/src/ipc/event.cr @@ -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 + diff --git a/src/ipc/lowlevel.cr b/src/ipc/lowlevel.cr index ed483d6..aef0da8 100644 --- a/src/ipc/lowlevel.cr +++ b/src/ipc/lowlevel.cr @@ -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