Go to file
Marc Siegel 11a6a2e9fe Add workaround for
This defect in Rubygems 2.2.0 breaks all 1.8.x builds on Travis CI.

Workaround until the fix is deployed is to pin builds to latest 2.1.x
build of Rubygems.
2013-12-30 11:05:38 -05:00
ext/helper Don't include compiled extension in gem; configure extconf.rb to compile and install into the correct location. Fixes . 2013-02-19 13:56:53 -06:00
lib Merge pull request from ms-ati/fix-cond-var-signal-when-no-waiters 2013-12-27 14:49:04 -08:00
spec Merge pull request from ms-ati/fix-cond-var-signal-when-no-waiters 2013-12-27 14:49:04 -08:00
.gitignore Add target dir to .gitignore. 2012-03-24 13:35:08 -05:00
.travis.yml Add workaround for 2013-12-30 11:05:38 -05:00
COPYING Initial commit. 2011-12-11 21:39:55 -06:00
ChangeLog Initial commit. 2011-12-11 21:39:55 -06:00
Gemfile Initial commit. 2011-12-11 21:39:55 -06:00
README.rdoc Rdoc formatting. 2012-03-04 10:29:43 -06:00
Rakefile Don't include compiled extension in gem; configure extconf.rb to compile and install into the correct location. Fixes . 2013-02-19 13:56:53 -06:00
VERSION Version bump to 0.1.11a 2013-12-27 16:51:31 -06:00
process_shared.gemspec Don't include compiled extension in gem; configure extconf.rb to compile and install into the correct location. Fixes . 2013-02-19 13:56:53 -06:00

README.rdoc

== Description

Concurrency primitives that may be used in a cross-process way to
coordinate share memory between processes.

FFI is used to access POSIX semaphore on Linux or Mach semaphores on
Mac.  Atop these semaphores are implemented ProcessShared::Semaphore,
ProcessShared::Mutex.  POSIX shared memory is used to implement
ProcessShared::SharedMemory.

On Linux, POSIX semaphores support <tt>sem_timedwait()</tt> which can wait on
a semaphore but stop waiting after a timeout.

Mac OS X's implementation of POSIX semaphores does not support
timeouts.  But, the Mach layer in Mac OS X has its own semaphores that
do support timeouts.  Thus, process_shared implements a moderate
subset of the Mach API, which is quite a bit different from POSIX.
Namely, semaphores created in one process are not available in child
processes created via <tt>fork()</tt>.  Mach does provide the means to copy
capabilities between tasks (Mach equivalent to processes).
process_shared overrides Ruby's <tt>fork</tt> methods so that semaphores are
copied from parent to child to emulate the POSIX behavior.

This is an incomplete work in progress.

== License

MIT

== Install
Install the gem with:

    gem install process_shared

== Usage

    require 'process_shared'

    mutex = ProcessShared::Mutex.new
    mem = ProcessShared::SharedMemory.new(:int)  # extends FFI::Pointer
    mem.put_int(0, 0)

    pid1 = fork do
      puts "in process 1 (#{Process.pid})"
      10.times do
        sleep 0.01
        mutex.synchronize do
          value = mem.get_int(0)
          sleep 0.01
          puts "process 1 (#{Process.pid}) incrementing"
          mem.put_int(0, value + 1)
        end
      end
    end

    pid2 = fork do
      puts "in process 2 (#{Process.pid})"
      10.times do
        sleep 0.01
        mutex.synchronize do
          value = mem.get_int(0)
          sleep 0.01
          puts "process 2 (#{Process.pid}) decrementing"
          mem.put_int(0, value - 1)
        end
      end
    end

    Process.wait(pid1)
    Process.wait(pid2)

    puts "value should be zero: #{mem.get_int(0)}"

== Transfer Objects Across Processes

    # allocate a sufficient memory block
    mem = ProcessShared::SharedMemory.new(1024)

    # sub process can write (serialize) object to memory (with bounds checking)
    pid = fork do
      mem.write_object(['a', 'b'])
    end

    Process.wait(pid)

    # parent process can read the object back (synchronizing access
    # with a Mutex left as an excercie to reader)

    mem.read_object.must_equal ['a', 'b']

== Todo

* Test ConditionVariable
* Implement optional override of core Thread/Mutex classes
* Extend to win32?  (See Python's processing library)
* Add finalizer to Mutex? (finalizer on Semaphore objects may be enough) or a method to
  explicitly close and release resources?
* Test semantics of crashing processes who still hold locks, etc.
* Is SharedArray with Enumerable mixing sufficient Array-like interface?