Class: ProcessShared::SharedMemory
- Inherits:
-
FFI::Pointer
- Object
- FFI::Pointer
- ProcessShared::SharedMemory
- Includes:
- WithSelf
- Defined in:
- lib/process_shared/shared_memory.rb
Overview
Memory block shared across processes.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#count ⇒ Object
readonly
Returns the value of attribute count.
-
#fd ⇒ Object
readonly
Returns the value of attribute fd.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
-
#type_size ⇒ Object
readonly
Returns the value of attribute type_size.
Class Method Summary collapse
Instance Method Summary collapse
- #close ⇒ Object
-
#get_object(offset) ⇒ Object
Read the serialized object at
offset
(in bytes) using Marshal.load. -
#initialize(type_or_count = 1, count = 1) ⇒ SharedMemory
constructor
A new instance of SharedMemory.
-
#put_object(offset, obj) ⇒ Object
Write the serialization of
obj
(using Marshal.dump) to this shared memory object atoffset
(in bytes). -
#read_object ⇒ Object
Equivalent to obj).
-
#write_object(obj) ⇒ Object
Equivalent to obj).
Methods included from WithSelf
Constructor Details
#initialize(type_or_count = 1, count = 1) ⇒ SharedMemory
Returns a new instance of SharedMemory.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/process_shared/shared_memory.rb', line 25 def initialize(type_or_count = 1, count = 1) @type, @count = case type_or_count when Symbol [type_or_count, count] else [:uchar, type_or_count] end @type_size = FFI.type_size(@type) @size = @type_size * @count name = "/ps-shm#{rand(10000)}" @fd = RT.shm_open(name, LibC::O_CREAT | LibC::O_RDWR | LibC::O_EXCL, 0777) RT.shm_unlink(name) LibC.ftruncate(@fd, @size) @pointer = LibC.mmap(nil, @size, LibC::PROT_READ | LibC::PROT_WRITE, LibC::MAP_SHARED, @fd, 0). slice(0, size) # slice to get FFI::Pointer that knows its size # (and thus does bounds checking) @finalize = self.class.make_finalizer(@pointer.address, @size, @fd) ObjectSpace.define_finalizer(self, @finalize) super(@pointer) end |
Instance Attribute Details
#count ⇒ Object (readonly)
Returns the value of attribute count.
11 12 13 |
# File 'lib/process_shared/shared_memory.rb', line 11 def count @count end |
#fd ⇒ Object (readonly)
Returns the value of attribute fd.
11 12 13 |
# File 'lib/process_shared/shared_memory.rb', line 11 def fd @fd end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
11 12 13 |
# File 'lib/process_shared/shared_memory.rb', line 11 def size @size end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
11 12 13 |
# File 'lib/process_shared/shared_memory.rb', line 11 def type @type end |
#type_size ⇒ Object (readonly)
Returns the value of attribute type_size.
11 12 13 |
# File 'lib/process_shared/shared_memory.rb', line 11 def type_size @type_size end |
Class Method Details
.make_finalizer(addr, size, fd) ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/process_shared/shared_memory.rb', line 17 def self.make_finalizer(addr, size, fd) proc do pointer = FFI::Pointer.new(addr) LibC.munmap(pointer, size) LibC.close(fd) end end |
.open(size, &block) ⇒ Object
13 14 15 |
# File 'lib/process_shared/shared_memory.rb', line 13 def self.open(size, &block) new(size).with_self(&block) end |
Instance Method Details
#close ⇒ Object
102 103 104 105 |
# File 'lib/process_shared/shared_memory.rb', line 102 def close ObjectSpace.undefine_finalizer(self) @finalize.call end |
#get_object(offset) ⇒ Object
Read the serialized object at offset
(in bytes) using Marshal.load.
84 85 86 87 88 |
# File 'lib/process_shared/shared_memory.rb', line 84 def get_object(offset) io = to_shm_io io.seek(offset) Marshal.load(io) end |
#put_object(offset, obj) ⇒ Object
Write the serialization of obj
(using Marshal.dump) to this shared memory object at offset
(in bytes).
Raises IndexError if there is insufficient space.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/process_shared/shared_memory.rb', line 62 def put_object(offset, obj) # FIXME: This is a workaround to an issue I'm seeing in # 1.8.7-p352 (not tested in other 1.8's). If I used the code # below that works in 1.9, then inside SharedMemoryIO#write, the # passed string object is 'terminated' (garbage collected?) and # won't respond to any methods... This way is less efficient # since it involves the creation of an intermediate string, but # it works in 1.8.7-p352. if RUBY_VERSION =~ /^1.8/ str = Marshal.dump(obj) return put_bytes(offset, str, 0, str.size) end io = SharedMemoryIO.new(self) io.seek(offset) Marshal.dump(obj, io) end |
#read_object ⇒ Object
Equivalent to obj)
98 99 100 |
# File 'lib/process_shared/shared_memory.rb', line 98 def read_object Marshal.load(to_shm_io) end |
#write_object(obj) ⇒ Object
Equivalent to obj)
91 92 93 |
# File 'lib/process_shared/shared_memory.rb', line 91 def write_object(obj) put_object(0, obj) end |