Last active
October 21, 2018 09:42
-
-
Save csmr/31639d9172274841edc7e528e2351998 to your computer and use it in GitHub Desktop.
Succintifying the POSIX named pipe comm in 3 processes of the lilgameng...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ... | |
# somewhere in class initialize | |
# create file path string | |
fpath_eng_srv = "/user/home/dir/engine2state.pipe" | |
# open a named pipe | |
@pipe_from_eng = named_pipe( fpath_eng_srv, "r", "ENG: HELO SRV" ) | |
# ... | |
# These called in the process loop | |
# get_input | |
# parse_next_message | |
# now_do_your_stuff | |
def get_input # from other processes | |
msg = read_message( @pipe_from_eng ) | |
@msg_stack.push msg unless msg.empty? | |
msg = read_message( @pipe_from_ui ) | |
@msg_stack.push msg unless msg.empty? | |
end | |
def parse_next_message | |
unless @msg_stack.empty? | |
msg = @msg_stack.shift | |
case msg[0] | |
when "GET" | |
p_dbg "got msg: #{msg}", self | |
@pipe_to_ui.puts get_state( msg[1] ) | |
@pipe_to_ui.flush | |
when "SET" | |
set_state( msg[1] ) | |
end | |
end | |
end | |
# Helpers for POSIX named pipe IPC | |
# get msg as arr | |
def read_message( pipe_handle ) | |
msg = read_line_nonblocking( pipe_handle ) | |
msg != nil ? msg = msg.split(" ") : [] | |
end | |
# Reads from a named pipe | |
# @agument timeout_secs_int - timeout for waiting on something to read | |
# @return nil if nothing to read | |
def read_line_nonblocking( pipe_handle_io, timeout_secs_int=0 ) | |
rwe = IO.select([pipe_handle_io], [], [], timeout_secs_int) | |
msg = rwe[0][0].gets unless rwe==nil || rwe[0][0]==nil | |
msg.strip if msg!=nil | |
end | |
# Open one end of named pipe | |
# @argument pipe_path - path to fifo | |
# @argument flag - r, w, w+ - open in read/write mode | |
# @argument wait_on_str - reader waits until writer puts this string in | |
# @returns named_pipe -handle | nil if cannot make pipe | |
def named_pipe( pipe_path, flag, wait_on_str=nil ) | |
pipe_handle = nil | |
unless File.pipe? pipe_path | |
raise "non-pipe path #{pipe_path} exists ̣– fail." if File.exists? pipe_path | |
status = File.mkfifo pipe_path | |
raise "cannot mkfifo #{pipe_path} – fail & exit." unless status == 0 | |
end | |
pipe_handle = open pipe_path, flag | |
# TODO implement serialization | |
pipe_handle.define_singleton_method(:put!) do |arf=nil| | |
syswrite arf + "\n" | |
# if arf != nil | |
flush | |
end | |
# TODO implement deserialization | |
pipe_handle.define_singleton_method(:get!) do |arf=nil| | |
read_line_nonblocking( pipe_handle ) | |
end | |
if wait_on_str | |
if flag.include? "w" #rite end | |
pipe_handle.put! wait_on_str | |
p_dbg "named_pipe - put str " + wait_on_str, self | |
else # read-end | |
msg = pipe_handle.gets # blocks until content | |
raise "no handshake #{msg} in #{pipe_path} - fail" unless msg.include? wait_on_str | |
p_dbg "named_pipe - gets str " + msg, self | |
end | |
end | |
pipe_handle | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment