Create dedicated class for messages.

This commit is contained in:
Patrick Mahoney 2012-01-29 22:57:13 -06:00
parent ae67dc6889
commit 13922373d6
2 changed files with 36 additions and 22 deletions

View File

@ -1,6 +1,12 @@
require 'mach/port' require 'mach/port'
require 'mach/semaphore' require 'mach/semaphore'
require 'mach/task' require 'mach/task'
require 'mach/functions'
module Mach module Mach
# @return [Port] the original bootstrap port; different from that
# affected by {get,set}_special_port
def self.bootstrap_port
@bootstrap_port ||= Mach::Port.new(:port => Mach::Functions::bootstrap_port)
end
end end

View File

@ -9,6 +9,23 @@ module Mach
class Port class Port
include Functions include Functions
class SendRightMsg < FFI::Struct
include Functions
layout(:header, MsgHeader,
:body, MsgBody,
:port, MsgPortDescriptor)
end
class ReceiveRightMsg < FFI::Struct
include Functions
layout(:header, MsgHeader,
:body, MsgBody,
:port, MsgPortDescriptor,
:trailer, MsgTrailer)
end
attr_reader :ipc_space, :port attr_reader :ipc_space, :port
# @param [Hash] opts # @param [Hash] opts
@ -21,18 +38,16 @@ module Mach
# is wrapped in a new Port object; otherwise a new port is # is wrapped in a new Port object; otherwise a new port is
# allocated according to the other options # allocated according to the other options
def initialize(opts = {}) def initialize(opts = {})
if opts.kind_of? Hash @ipc_space = opts[:ipc_space] || mach_task_self
@ipc_space = opts[:ipc_space] || mach_task_self right = opts[:right] || :receive
right = opts[:right] || :receive
@port = if opts[:port] @port = if opts[:port]
opts[:port].to_i opts[:port].to_i
else else
mem = new_memory_pointer(:mach_port_right_t) mem = new_memory_pointer(:mach_port_right_t)
mach_port_allocate(@ipc_space.to_i, right, mem) mach_port_allocate(@ipc_space.to_i, right, mem)
mem.get_uint(0) mem.get_uint(0)
end end
end
end end
# With this alias, we can call #to_i on either bare Integer ports # With this alias, we can call #to_i on either bare Integer ports
@ -81,17 +96,14 @@ module Mach
# must already have the requisite rights allowing it to send # must already have the requisite rights allowing it to send
# +right+. # +right+.
def send_right(right, remote_port) def send_right(right, remote_port)
msg = FFI::Struct.new(nil, msg = SendRightMsg.new
:header, MsgHeader,
:body, MsgBody,
:port, MsgPortDescriptor)
msg[:header].tap do |h| msg[:header].tap do |h|
h[:remote_port] = remote_port.to_i h[:remote_port] = remote_port.to_i
h[:local_port] = MACH_PORT_NULL h[:local_port] = MACH_PORT_NULL
h[:bits] = h[:bits] =
(MachMsgType[right] | (0 << 8)) | 0x80000000 # MACH_MSGH_BITS_COMPLEX (MachMsgType[right] | (0 << 8)) | 0x80000000 # MACH_MSGH_BITS_COMPLEX
h[:size] = msg.size h[:size] = 40 # msg.size
end end
msg[:body][:descriptor_count] = 1 msg[:body][:descriptor_count] = 1
@ -115,11 +127,7 @@ module Mach
# Create a new Port by receiving a port right message on this # Create a new Port by receiving a port right message on this
# port. # port.
def receive_right def receive_right
msg = FFI::Struct.new(nil, msg = ReceiveRightMsg.new
:header, MsgHeader,
:body, MsgBody,
:port, MsgPortDescriptor,
:trailer, MsgTrailer)
mach_msg(msg, mach_msg(msg,
2, # MACH_RCV_MSG, 2, # MACH_RCV_MSG,