Skip to content

Instantly share code, notes, and snippets.

@csmr
Last active October 21, 2018 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csmr/31639d9172274841edc7e528e2351998 to your computer and use it in GitHub Desktop.
Save csmr/31639d9172274841edc7e528e2351998 to your computer and use it in GitHub Desktop.
Succintifying the POSIX named pipe comm in 3 processes of the lilgameng...
# ...
# 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