Crystal bindings: most functions done. Can be used for real.
parent
368513bca5
commit
21ecf157d1
|
@ -18,66 +18,149 @@ lib LibIPC
|
||||||
fun service_init = ipc_service_init (Void*, LibC::Int*, LibC::Char*, LibC::UInt16T) : LibC::Int
|
fun service_init = ipc_service_init (Void*, LibC::Int*, LibC::Char*, LibC::UInt16T) : LibC::Int
|
||||||
fun connect_service = ipc_connect_service(Void*, LibC::Int*, LibC::Char*, LibC::UInt16T) : LibC::Int
|
fun connect_service = ipc_connect_service(Void*, LibC::Int*, LibC::Char*, LibC::UInt16T) : LibC::Int
|
||||||
|
|
||||||
# Context EventType index fd buffer buflen
|
# Context EventType index fd buffer buflen
|
||||||
fun wait = ipc_wait_event(Void*, UInt8*, LibC::UInt64T*, LibC::Int*, UInt8*, LibC::UInt64T*) : LibC::Int
|
fun wait = ipc_wait_event(Void*, UInt8*, LibC::UInt64T*, LibC::Int*, UInt8*, LibC::UInt64T*) : LibC::Int
|
||||||
|
|
||||||
# Sending a message NOW.
|
# Sending a message NOW.
|
||||||
# WARNING: unbuffered send do not wait the fd to become available.
|
# WARNING: doesn't wait the fd to become available.
|
||||||
fun write = ipc_write(Void*, LibC::Int, UInt8*, LibC::UInt64T) : LibC::Int
|
fun write = ipc_write(Void*, LibC::Int, UInt8*, LibC::UInt64T) : LibC::Int
|
||||||
# Sending a message (will wait the fd to become available for IO operations).
|
# Sending a message (will wait the fd to become available for IO operations).
|
||||||
fun schedule = ipc_schedule(Void*, LibC::Int, UInt8*, LibC::UInt64T) : LibC::Int
|
fun schedule = ipc_schedule(Void*, LibC::Int, UInt8*, LibC::UInt64T) : LibC::Int
|
||||||
|
|
||||||
fun read = ipc_read_fd (Void*, LibC::Int, UInt8*, LibC::UInt64T*);
|
fun read = ipc_read_fd (Void*, LibC::Int, UInt8*, LibC::UInt64T*);
|
||||||
|
|
||||||
|
fun timer = ipc_context_timer (Void*, LibC::Int)
|
||||||
|
|
||||||
# Closing connections.
|
# Closing connections.
|
||||||
fun ipc_close(Void*, index : LibC::UInt64T) : LibC::Int
|
fun ipc_close(Void*, LibC::UInt64T) : LibC::Int
|
||||||
fun ipc_close_all(Void*) : LibC::Int
|
fun ipc_close_all(Void*) : LibC::Int
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_without_wait()
|
def test_without_wait()
|
||||||
ctx : Pointer(Void) = Pointer(Void).null
|
ctx = Pointer(Void).null
|
||||||
LibIPC.init (pointerof(ctx))
|
LibIPC.init (pointerof(ctx))
|
||||||
fd : Int32 = 0
|
fd : Int32 = 0
|
||||||
LibIPC.connect_service(ctx, pointerof(fd), "pong", 4)
|
LibIPC.connect_service(ctx, pointerof(fd), "pong", 4)
|
||||||
pp! fd
|
pp! fd
|
||||||
LibIPC.write(ctx, fd, "Hello", 5)
|
LibIPC.write(ctx, fd, "Hello", 5)
|
||||||
|
|
||||||
buflen : LibC::UInt64T = 10
|
buflen : LibC::UInt64T = 10
|
||||||
buffer = uninitialized UInt8[10]
|
buffer = uninitialized UInt8[10]
|
||||||
LibIPC.read(ctx, fd, buffer.to_unsafe, pointerof(buflen))
|
LibIPC.read(ctx, fd, buffer.to_unsafe, pointerof(buflen))
|
||||||
received = String.new(buffer.to_unsafe, buflen)
|
received = String.new(buffer.to_unsafe, buflen)
|
||||||
pp! received
|
pp! received
|
||||||
|
|
||||||
LibIPC.deinit (ctx)
|
LibIPC.deinit (ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
class IPC
|
||||||
|
#class Message
|
||||||
|
# @fd : Int32
|
||||||
|
# @payload : Bytes
|
||||||
|
# def initialize(@fd, string : String)
|
||||||
|
# @payload = Bytes.new string
|
||||||
|
# end
|
||||||
|
#end
|
||||||
|
|
||||||
|
class Event
|
||||||
|
property type : LibIPC::EventType
|
||||||
|
property index : LibC::UInt64T
|
||||||
|
property fd : Int32
|
||||||
|
property buffer : Array(UInt8)
|
||||||
|
|
||||||
|
def initialize(t : UInt8, @index, @fd, buffer, buflen)
|
||||||
|
@type = LibIPC::EventType.new t
|
||||||
|
@buffer = buffer.to_a[0..buflen - 1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize()
|
||||||
|
@context = Pointer(Void).null
|
||||||
|
LibIPC.init(pointerof(@context))
|
||||||
|
at_exit { deinit }
|
||||||
|
end
|
||||||
|
|
||||||
|
def deinit
|
||||||
|
LibIPC.deinit(@context)
|
||||||
|
end
|
||||||
|
|
||||||
|
def connect(name : String) : Int
|
||||||
|
fd = uninitialized Int32
|
||||||
|
if LibIPC.connect_service(@context, pointerof(fd), name, name.size) != 0
|
||||||
|
raise "oh noes"
|
||||||
|
end
|
||||||
|
fd
|
||||||
|
end
|
||||||
|
|
||||||
|
def write(fd : Int, string : String)
|
||||||
|
self.write(fd, string.to_unsafe, string.size.to_u64)
|
||||||
|
end
|
||||||
|
|
||||||
|
def write(fd : Int, buffer : UInt8*, buflen : UInt64)
|
||||||
|
if LibIPC.write(@context, fd, buffer, buflen) != 0
|
||||||
|
raise "oh noes"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait() : IPC::Event
|
||||||
|
eventtype : UInt8 = 0
|
||||||
|
index : LibC::UInt64T = 0
|
||||||
|
fd : Int32 = 0
|
||||||
|
buflen : LibC::UInt64T = 10000
|
||||||
|
buffer = uninitialized UInt8[10000]
|
||||||
|
ret = LibIPC.wait(@context,
|
||||||
|
pointerof(eventtype),
|
||||||
|
pointerof(index),
|
||||||
|
pointerof(fd),
|
||||||
|
buffer.to_unsafe,
|
||||||
|
pointerof(buflen))
|
||||||
|
|
||||||
|
if ret != 0
|
||||||
|
raise "Oh noes, 'wait' iz brkn"
|
||||||
|
end
|
||||||
|
|
||||||
|
Event.new(eventtype, index, fd, buffer, buflen)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_with_wait()
|
def test_with_wait()
|
||||||
ctx : Pointer(Void) = Pointer(Void).null
|
ctx = Pointer(Void).null
|
||||||
LibIPC.init (pointerof(ctx))
|
LibIPC.init (pointerof(ctx))
|
||||||
fd : Int32 = 0
|
fd : Int32 = 0
|
||||||
LibIPC.connect_service(ctx, pointerof(fd), "pong", 4)
|
LibIPC.connect_service(ctx, pointerof(fd), "pong", 4)
|
||||||
pp! fd
|
pp! fd
|
||||||
LibIPC.write(ctx, fd, "Hello", 5)
|
LibIPC.write(ctx, fd, "Hello", 5)
|
||||||
|
|
||||||
buflen : LibC::UInt64T = 10
|
buflen : LibC::UInt64T = 10
|
||||||
buffer = uninitialized UInt8[10]
|
buffer = uninitialized UInt8[10]
|
||||||
eventtype : UInt8 = 0
|
eventtype : UInt8 = 0
|
||||||
index : LibC::UInt64T = 0
|
index : LibC::UInt64T = 0
|
||||||
|
|
||||||
LibIPC.wait(ctx, pointerof(eventtype), pointerof(index), pointerof(fd), buffer.to_unsafe, pointerof(buflen))
|
LibIPC.timer(ctx, 2000) # Wait at most 2 seconds.
|
||||||
|
LibIPC.wait(ctx, pointerof(eventtype), pointerof(index), pointerof(fd), buffer.to_unsafe, pointerof(buflen))
|
||||||
|
|
||||||
pp! "After waiting: ", LibIPC::EventType.new(eventtype), fd, index, buflen
|
pp! LibIPC::EventType.new(eventtype), fd, index, buflen
|
||||||
received = String.new(buffer.to_unsafe, buflen)
|
received = String.new(buffer.to_unsafe, buflen)
|
||||||
pp! received
|
pp! received
|
||||||
|
|
||||||
LibIPC.deinit (ctx)
|
LibIPC.deinit (ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_high_level
|
||||||
|
ipc = IPC.new
|
||||||
|
fd = ipc.connect("pong")
|
||||||
|
ipc.write(fd, "hello this is some value")
|
||||||
|
event = ipc.wait()
|
||||||
|
pp! event.type
|
||||||
|
pp! event.fd
|
||||||
|
pp! String.new(event.buffer.to_unsafe, event.buffer.size)
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Write documentation for `Some::Crystal::App`
|
# TODO: Write documentation for `Some::Crystal::App`
|
||||||
module Some::Crystal::App
|
module Some::Crystal::App
|
||||||
VERSION = "0.1.0"
|
VERSION = "0.1.0"
|
||||||
|
|
||||||
test_without_wait
|
test_without_wait
|
||||||
|
test_with_wait
|
||||||
test_with_wait
|
test_high_level
|
||||||
end
|
end
|
||||||
|
|
Reference in New Issue