From 5b134a8c1b457e8927087f90d6086a5a9b7a449b Mon Sep 17 00:00:00 2001 From: Philippe PITTOLI Date: Sat, 26 Oct 2019 18:12:59 +0200 Subject: [PATCH] v0.4: ipc_wait_event* functions now reveive a timeout value --- src/ipc/connection.cr | 31 ++++++++++++++++++++++++------- src/ipc/event.cr | 5 ++++- src/ipc/lowlevel.cr | 5 +++-- src/ipc/service.cr | 15 +++++++++++---- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/ipc/connection.cr b/src/ipc/connection.cr index 8492779..a583f1b 100644 --- a/src/ipc/connection.cr +++ b/src/ipc/connection.cr @@ -93,6 +93,8 @@ class IPC::StandAloneConnection end class IPC::Connections + property base_timer : Int64 = 0 + property timer : Int64 = 0 getter connections : LibIPC::Connections def initialize @@ -143,27 +145,42 @@ class IPC::Connections serverp = server.pointer end - r = LibIPC.ipc_wait_event self.pointer, serverp, pointerof(event) + r = LibIPC.ipc_wait_event self.pointer, serverp, pointerof(event), pointerof(@timer) if r != 0 m = String.new LibIPC.ipc_errors_get (r) yield IPC::Exception.new "error waiting for a new event: #{m}" end + eventtype = event.type.unsafe_as(LibIPC::EventType) + + # if event type is Timer, there is no connection nor message + case eventtype + when LibIPC::EventType::Timer + return eventtype, nil, nil + end + connection = IPC::Connection.new event.origin.unsafe_as(Pointer(LibIPC::Connection)).value - eventtype = event.type.unsafe_as(LibIPC::EventType) message = event.message.unsafe_as(Pointer(LibIPC::Message)) return eventtype, IPC::Message.new(message), connection end def loop(server : IPC::Connection | IPC::Server | ::Nil, &block : Proc(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 + yield IPC::Event::Connection.new connection.not_nil! when LibIPC::EventType::NotSet yield IPC::Exception.new "even type not set" @@ -172,13 +189,13 @@ class IPC::Connections yield IPC::Exception.new "even type indicates an error" when LibIPC::EventType::ExtraSocket - yield IPC::Event::ExtraSocket.new message, connection + yield IPC::Event::ExtraSocket.new message.not_nil!, connection.not_nil! when LibIPC::EventType::Switch - yield IPC::Event::Switch.new message, connection + yield IPC::Event::Switch.new message.not_nil!, connection.not_nil! when LibIPC::EventType::Message - yield IPC::Event::Message.new message, connection + 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 @@ -186,7 +203,7 @@ class IPC::Connections # yield IPC::Event::LookUp.new message, connection when LibIPC::EventType::Disconnection - yield IPC::Event::Disconnection.new connection + yield IPC::Event::Disconnection.new connection.not_nil! end end end diff --git a/src/ipc/event.cr b/src/ipc/event.cr index f048e93..3c793e9 100644 --- a/src/ipc/event.cr +++ b/src/ipc/event.cr @@ -3,6 +3,9 @@ require "./message" require "./connection" class IPC::Event + class Timer + end + class Connection getter connection : IPC::Connection def initialize(@connection) @@ -32,5 +35,5 @@ class IPC::Event end end -alias Events = 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::Connection | IPC::Event::Disconnection | IPC::Event::Message | IPC::Event::ExtraSocket | IPC::Event::Switch | IPC::Event::LookUp diff --git a/src/ipc/lowlevel.cr b/src/ipc/lowlevel.cr index ba9b0b4..168d034 100644 --- a/src/ipc/lowlevel.cr +++ b/src/ipc/lowlevel.cr @@ -111,6 +111,7 @@ lib LibIPC Disconnection Message LookUp + Timer end struct Event @@ -129,7 +130,7 @@ lib LibIPC fun ipc_read(Connection*, Message*) : LibC::Int fun ipc_write(Connection*, Message*) : LibC::Int - fun ipc_wait_event(Connections*, Connection*, Event*) : LibC::Int + fun ipc_wait_event(Connections*, Connection*, Event*, LibC::Long*) : LibC::Int fun ipc_add(Connections*, Connection*) : LibC::Int fun ipc_del(Connections*, Connection*) : LibC::Int @@ -148,7 +149,7 @@ lib LibIPC # networkd-related functions - fun ipc_wait_event_networkd(Connections*, Connection*, Event*, Switchings*) : LibC::Int + fun ipc_wait_event_networkd(Connections*, Connection*, Event*, Switchings*, LibC::Long*) : LibC::Int fun ipc_receive_fd (sock : LibC::Int, fd : LibC::Int*) : LibC::Int fun ipc_provide_fd (sock : LibC::Int, fd : LibC::Int) : LibC::Int diff --git a/src/ipc/service.cr b/src/ipc/service.cr index 68f07ee..6eb96ca 100644 --- a/src/ipc/service.cr +++ b/src/ipc/service.cr @@ -70,22 +70,29 @@ class IPC::SwitchingService < IPC::Service @switch.del fd end - def wait_event(server : IPC::Connection , &block) : Tuple(LibIPC::EventType, IPC::Message, IPC::Connection) + def wait_event(server : IPC::Connection , &block) : Tuple(LibIPC::EventType, IPC::Message, IPC::Connection) | Tuple(LibIPC::EventType, Nil, Nil) event = LibIPC::Event.new serverp = server.pointer - r = LibIPC.ipc_wait_event_networkd self.pointer, serverp, pointerof(event), @switch.pointer + r = LibIPC.ipc_wait_event_networkd self.pointer, serverp, pointerof(event), @switch.pointer, pointerof(@timer) + if r != 0 m = String.new LibIPC.ipc_errors_get (r) yield IPC::Exception.new "error waiting for a new event: #{m}" end + eventtype = event.type.unsafe_as(LibIPC::EventType) + + # if event type is Timer, there is no connection nor message + case eventtype + when LibIPC::EventType::Timer + return eventtype, nil, nil + end + connection = IPC::Connection.new event.origin.unsafe_as(Pointer(LibIPC::Connection)).value message = event.message.unsafe_as(Pointer(LibIPC::Message)) - eventtype = event.type.unsafe_as(LibIPC::EventType) - return eventtype, IPC::Message.new(message), connection end end