New C function, fix a memory leak, more error cases covered.
This commit is contained in:
parent
89125d8338
commit
30dbf2e85b
@ -4,6 +4,11 @@ class IPC::Context
|
|||||||
property timer : Int32 = LibIPC::INFTIM
|
property timer : Int32 = LibIPC::INFTIM
|
||||||
getter context : LibIPC::Ctx
|
getter context : LibIPC::Ctx
|
||||||
|
|
||||||
|
# On message reception, the message is contained into the event structure.
|
||||||
|
# This message is automatically deallocated on the next ipc_wait_event call.
|
||||||
|
# Therefore, we must keep this structure.
|
||||||
|
property event = LibIPC::Event.new
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@context = LibIPC::Ctx.new
|
@context = LibIPC::Ctx.new
|
||||||
end
|
end
|
||||||
@ -41,45 +46,56 @@ class IPC::Context
|
|||||||
end
|
end
|
||||||
|
|
||||||
def wait_event : IPC::Event::Events | Exception
|
def wait_event : IPC::Event::Events | Exception
|
||||||
event = LibIPC::Event.new
|
r = LibIPC.ipc_wait_event self.pointer, pointerof(@event), pointerof(@timer)
|
||||||
|
|
||||||
|
event_type = @event.type.unsafe_as(LibIPC::EventType)
|
||||||
|
|
||||||
r = LibIPC.ipc_wait_event self.pointer, pointerof(event), pointerof(@timer)
|
|
||||||
if r.error_code != 0
|
if r.error_code != 0
|
||||||
m = String.new r.error_message.to_slice
|
m = String.new r.error_message.to_slice
|
||||||
|
case event_type
|
||||||
|
when LibIPC::EventType::Disconnection # User disconnected.
|
||||||
|
# In this case, error_code may not be 0, disconnections can happen at any time.
|
||||||
|
return IPC::Event::Disconnection.new @event.origin, @event.index
|
||||||
|
end
|
||||||
|
# Special case where the fd is closed.
|
||||||
|
if r.error_code == 107
|
||||||
|
# Baguette::Log.error "ERROR 107: fd #{@event.origin}"
|
||||||
|
return IPC::Event::Disconnection.new @event.origin, @event.index
|
||||||
|
else
|
||||||
|
# Baguette::Log.error "ERROR #{r.error_code}: fd #{@event.origin}"
|
||||||
|
end
|
||||||
return IPC::Exception.new "error waiting for a new event: #{m}"
|
return IPC::Exception.new "error waiting for a new event: #{m}"
|
||||||
end
|
end
|
||||||
|
|
||||||
eventtype = event.type.unsafe_as(LibIPC::EventType)
|
# if event type is Timer, there is no file descriptor nor message
|
||||||
|
case event_type
|
||||||
# if event type is Timer, there is no connection nor message
|
|
||||||
case eventtype
|
|
||||||
when LibIPC::EventType::NotSet
|
when LibIPC::EventType::NotSet
|
||||||
return Exception.new "'Event type: not set"
|
return IPC::Event::EventNotSet.new @event.origin, @event.index
|
||||||
when LibIPC::EventType::Error
|
when LibIPC::EventType::Error
|
||||||
return IPC::Event::Error.new event.origin, event.index
|
return IPC::Event::Error.new @event.origin, @event.index
|
||||||
when LibIPC::EventType::ExtraSocket # Message received from a non IPC socket.
|
when LibIPC::EventType::ExtraSocket # Message received from a non IPC socket.
|
||||||
return IPC::Event::ExtraSocket.new event.origin, event.index
|
return IPC::Event::ExtraSocket.new @event.origin, @event.index
|
||||||
when LibIPC::EventType::Switch # Message to send to a corresponding fd.
|
when LibIPC::EventType::Switch # Message to send to a corresponding fd.
|
||||||
return IPC::Event::Switch.new event.origin, event.index
|
return IPC::Event::Switch.new @event.origin, @event.index
|
||||||
when LibIPC::EventType::Connection # New user.
|
when LibIPC::EventType::Connection # New user.
|
||||||
return IPC::Event::Connection.new event.origin, event.index
|
return IPC::Event::Connection.new @event.origin, @event.index
|
||||||
when LibIPC::EventType::Disconnection # User disconnected.
|
when LibIPC::EventType::Disconnection # User disconnected.
|
||||||
return IPC::Event::Disconnection.new event.origin, event.index
|
return IPC::Event::Disconnection.new @event.origin, @event.index
|
||||||
when LibIPC::EventType::Message # New message.
|
when LibIPC::EventType::Message # New message.
|
||||||
lowlevel_message = event.message.unsafe_as(Pointer(LibIPC::Message))
|
lowlevel_message = @event.message.unsafe_as(Pointer(LibIPC::Message))
|
||||||
ipc_message = IPC::Message.new lowlevel_message
|
ipc_message = IPC::Message.new lowlevel_message
|
||||||
return IPC::Event::MessageReceived.new event.origin, event.index, ipc_message
|
return IPC::Event::MessageReceived.new @event.origin, @event.index, ipc_message
|
||||||
when LibIPC::EventType::LookUp # Client asking for a service through ipcd.
|
when LibIPC::EventType::LookUp # Client asking for a service through ipcd.
|
||||||
# for now, the libipc does not provide lookup events
|
# for now, the libipc does not provide lookup events
|
||||||
# ipcd uses a simple LibIPC::EventType::Message
|
# ipcd uses a simple LibIPC::EventType::Message
|
||||||
return IPC::Event::LookUp.new event.origin, event.index
|
return IPC::Event::LookUp.new @event.origin, @event.index
|
||||||
when LibIPC::EventType::Timer # Timeout in the poll(2) function.
|
when LibIPC::EventType::Timer # Timeout in the poll(2) function.
|
||||||
return IPC::Event::Timer.new
|
return IPC::Event::Timer.new
|
||||||
when LibIPC::EventType::Tx # Message sent.
|
when LibIPC::EventType::Tx # Message sent.
|
||||||
return IPC::Event::MessageSent.new event.origin, event.index
|
return IPC::Event::MessageSent.new @event.origin, @event.index
|
||||||
end
|
end
|
||||||
|
|
||||||
return Exception.new "Cannot understand the event type: #{eventtype}"
|
return Exception.new "Cannot understand the event type: #{event_type}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def loop(&block : Proc(IPC::Event::Events|Exception, Nil))
|
def loop(&block : Proc(IPC::Event::Events|Exception, Nil))
|
||||||
@ -159,6 +175,7 @@ class IPC::Context
|
|||||||
|
|
||||||
def close
|
def close
|
||||||
return if @closed
|
return if @closed
|
||||||
|
|
||||||
r = LibIPC.ipc_close_all(self.pointer)
|
r = LibIPC.ipc_close_all(self.pointer)
|
||||||
if r.error_code != 0
|
if r.error_code != 0
|
||||||
m = String.new r.error_message.to_slice
|
m = String.new r.error_message.to_slice
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
class IPC::Event
|
class IPC::Event
|
||||||
alias Events = IPC::Event::Timer |
|
alias Events = IPC::Event::Timer |
|
||||||
|
IPC::Event::EventNotSet |
|
||||||
IPC::Event::Error |
|
IPC::Event::Error |
|
||||||
IPC::Event::Connection |
|
IPC::Event::Connection |
|
||||||
IPC::Event::Disconnection |
|
IPC::Event::Disconnection |
|
||||||
@ -52,3 +53,6 @@ end
|
|||||||
class IPC::Event::MessageSent < IPC::Event::Base
|
class IPC::Event::MessageSent < IPC::Event::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class IPC::Event::EventNotSet < IPC::Event::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
@ -151,6 +151,7 @@ lib LibIPC
|
|||||||
(LibC::Int, LibIPC::Message* -> LibIPC::IPCCB))
|
(LibC::Int, LibIPC::Message* -> LibIPC::IPCCB))
|
||||||
|
|
||||||
fun ipc_ctx_switching_add (ctx : Ctx*, fd1 : LibC::Int, fd2 : LibC::Int) # Void
|
fun ipc_ctx_switching_add (ctx : Ctx*, fd1 : LibC::Int, fd2 : LibC::Int) # Void
|
||||||
|
fun ipc_ctx_switching_del (ctx : Ctx*, fd : LibC::Int) : LibC::Int
|
||||||
fun ipc_switching_add (switch : Switchings*, fd1 : LibC::Int, fd2 : LibC::Int) # Void
|
fun ipc_switching_add (switch : Switchings*, fd1 : LibC::Int, fd2 : LibC::Int) # Void
|
||||||
fun ipc_switching_del (switch : Switchings*, fd : LibC::Int ) : LibC::Int
|
fun ipc_switching_del (switch : Switchings*, fd : LibC::Int ) : LibC::Int
|
||||||
fun ipc_switching_get (switch : Switchings*, fd : LibC::Int ) : LibC::Int
|
fun ipc_switching_get (switch : Switchings*, fd : LibC::Int ) : LibC::Int
|
||||||
|
@ -11,7 +11,8 @@ class IPC::Server < IPC::Context
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Very important as there are filesystem side-effects.
|
# Very important as there are filesystem side-effects.
|
||||||
at_exit { close }
|
# FIXME: for now, let's forget that.
|
||||||
|
# at_exit { close }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user