concurrent-ruby-ext-1.0.5/0000755000175000017500000000000013147302606014502 5ustar pravipraviconcurrent-ruby-ext-1.0.5/CHANGELOG.md0000644000175000017500000004673013147302606016325 0ustar pravipravi## Release v1.0.5, edge v0.3.1 (26 Feb 2017) concurrent-ruby: * Documentation for Event and Semaphore * Use Unsafe#fullFence and #loadFence directly since the shortcuts were removed in JRuby * Do not depend on org.jruby.util.unsafe.UnsafeHolder concurrent-ruby-edge: * (#620) Actors on Pool raise an error * (#624) Delayed promises did not interact correctly with flatting * Fix arguments yielded by callback methods * Overridable default executor in promises factory methods * Asking actor to terminate will always resolve to `true` ## Release v1.0.4, edge v0.3.0 (27 Dec 2016) concurrent-ruby: * Nothing concurrent-ruby-edge: * New promises' API renamed, lots of improvements, edge bumped to 0.3.0 * **Incompatible** with previous 0.2.3 version * see https://github.com/ruby-concurrency/concurrent-ruby/pull/522 ## Release v1.0.3 (17 Dec 2016) * Trigger execution of flattened delayed futures * Avoid forking for processor_count if possible * Semaphore Mutex and JRuby parity * Adds Map#each as alias to Map#each_pair * Fix uninitialized instance variables * Make Fixnum, Bignum merger ready * Allows Promise#then to receive an executor * TimerSet now survives a fork * Reject promise on any exception * Allow ThreadLocalVar to be initialized with a block * Support Alpha with `Concurrent::processor_count` * Fixes format-security error when compiling ruby_193_compatible.h * Concurrent::Atom#swap fixed: reraise the exceptions from block ## Release v1.0.2 (2 May 2016) * Fix bug with `Concurrent::Map` MRI backend `#inspect` method * Fix bug with `Concurrent::Map` MRI backend using `Hash#value?` * Improved documentation and examples * Minor updates to Edge ## Release v1.0.1 (27 February 2016) * Fix "uninitialized constant Concurrent::ReentrantReadWriteLock" error. * Better handling of `autoload` vs. `require`. * Improved API for Edge `Future` zipping. * Fix reference leak in Edge `Future` constructor . * Fix bug which prevented thread pools from surviving a `fork`. * Fix bug in which `TimerTask` did not correctly specify all its dependencies. * Improved support for JRuby+Truffle * Improved error messages. * Improved documentation. * Updated README and CONTRIBUTING. ## Release v1.0.0 (13 November 2015) * Rename `attr_volatile_with_cas` to `attr_atomic` * Add `clear_each` to `LockFreeStack` * Update `AtomicReference` documentation * Further updates and improvements to the synchronization layer. * Performance and memory usage performance with `Actor` logging. * Fixed `ThreadPoolExecutor` task count methods. * Improved `Async` performance for both short and long-lived objects. * Fixed bug in `LockFreeLinkedSet`. * Fixed bug in which `Agent#await` triggered a validation failure. * Further `Channel` updates. * Adopted a project Code of Conduct * Cleared interpreter warnings * Fixed bug in `ThreadPoolExecutor` task count methods * Fixed bug in 'LockFreeLinkedSet' * Improved Java extension loading * Handle Exception children in Edge::Future * Continued improvements to channel * Removed interpreter warnings. * Shared constants now in `lib/concurrent/constants.rb` * Refactored many tests. * Improved synchronization layer/memory model documentation. * Bug fix in Edge `Future#flat` * Brand new `Channel` implementation in Edge gem. * Simplification of `RubySingleThreadExecutor` * `Async` improvements - Each object uses its own `SingleThreadExecutor` instead of the global thread pool. - No longers supports executor injection - Much better documentation * `Atom` updates - No longer `Dereferenceable` - Now `Observable` - Added a `#reset` method * Brand new `Agent` API and implementation. Now functionally equivalent to Clojure. * Continued improvements to the synchronization layer * Merged in the `thread_safe` gem - `Concurrent::Array` - `Concurrent::Hash` - `Concurrent::Map` (formerly ThreadSafe::Cache) - `Concurrent::Tuple` * Minor improvements to Concurrent::Map * Complete rewrite of `Exchanger` * Removed all deprecated code (classes, methods, constants, etc.) * Updated Agent, MutexAtomic, and BufferedChannel to inherit from Synchronization::Object. * Many improved tests * Some internal reorganization ## Release v0.9.1 (09 August 2015) * Fixed a Rubiniux bug in synchronization object * Fixed all interpreter warnings (except circular references) * Fixed require statements when requiring `Atom` alone * Significantly improved `ThreadLocalVar` on non-JRuby platforms * Fixed error handling in Edge `Concurrent.zip` * `AtomicFixnum` methods `#increment` and `#decrement` now support optional delta * New `AtomicFixnum#update` method * Minor optimizations in `ReadWriteLock` * New `ReentrantReadWriteLock` class * `ThreadLocalVar#bind` method is now public * Refactored many tests ## Release v0.9.0 (10 July 2015) * Updated `AtomicReference` - `AtomicReference#try_update` now simply returns instead of raising exception - `AtomicReference#try_update!` was added to raise exceptions if an update fails. Note: this is the same behavior as the old `try_update` * Pure Java implementations of - `AtomicBoolean` - `AtomicFixnum` - `Semaphore` * Fixed bug when pruning Ruby thread pools * Fixed bug in time calculations within `ScheduledTask` * Default `count` in `CountDownLatch` to 1 * Use monotonic clock for all timers via `Concurrent.monotonic_time` - Use `Process.clock_gettime(Process::CLOCK_MONOTONIC)` when available - Fallback to `java.lang.System.nanoTime()` on unsupported JRuby versions - Pure Ruby implementation for everything else - Effects `Concurrent.timer`, `Concurrent.timeout`, `TimerSet`, `TimerTask`, and `ScheduledTask` * Deprecated all clock-time based timer scheduling - Only support scheduling by delay - Effects `Concurrent.timer`, `TimerSet`, and `ScheduledTask` * Added new `ReadWriteLock` class * Consistent `at_exit` behavior for Java and Ruby thread pools. * Added `at_exit` handler to Ruby thread pools (already in Java thread pools) - Ruby handler stores the object id and retrieves from `ObjectSpace` - JRuby disables `ObjectSpace` by default so that handler stores the object reference * Added a `:stop_on_exit` option to thread pools to enable/disable `at_exit` handler * Updated thread pool docs to better explain shutting down thread pools * Simpler `:executor` option syntax for all abstractions which support this option * Added `Executor#auto_terminate?` predicate method (for thread pools) * Added `at_exit` handler to `TimerSet` * Simplified auto-termination of the global executors - Can now disable auto-termination of global executors - Added shutdown/kill/wait_for_termination variants for global executors * Can now disable auto-termination for *all* executors (the nuclear option) * Simplified auto-termination of the global executors * Deprecated terms "task pool" and "operation pool" - New terms are "io executor" and "fast executor" - New functions added with new names - Deprecation warnings added to functions referencing old names * Moved all thread pool related functions from `Concurrent::Configuration` to `Concurrent` - Old functions still exist with deprecation warnings - New functions have updated names as appropriate * All high-level abstractions default to the "io executor" * Fixed bug in `Actor` causing it to prematurely warm global thread pools on gem load - This also fixed a `RejectedExecutionError` bug when running with minitest/autorun via JRuby * Moved global logger up to the `Concurrent` namespace and refactored the code * Optimized the performance of `Delay` - Fixed a bug in which no executor option on construction caused block execution on a global thread pool * Numerous improvements and bug fixes to `TimerSet` * Fixed deadlock of `Future` when the handler raises Exception * Added shared specs for more classes * New concurrency abstractions including: - `Atom` - `Maybe` - `ImmutableStruct` - `MutableStruct` - `SettableStruct` * Created an Edge gem for unstable abstractions including - `Actor` - `Agent` - `Channel` - `Exchanger` - `LazyRegister` - **new Future Framework** - unified implementation of Futures and Promises which combines Features of previous `Future`, `Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`. It offers better performance and does not block threads when not required. * Actor framework changes: - fixed reset loop in Pool - Pool can use any actor as a worker, abstract worker class is no longer needed. - Actor events not have format `[:event_name, *payload]` instead of just the Symbol. - Actor now uses new Future/Promise Framework instead of `IVar` for better interoperability - Behaviour definition array was simplified to `[BehaviourClass1, [BehaviourClass2, *initialization_args]]` - Linking behavior responds to :linked message by returning array of linked actors - Supervised behavior is removed in favour of just Linking - RestartingContext is supervised by default now, `supervise: true` is not required any more - Events can be private and public, so far only difference is that Linking will pass to linked actors only public messages. Adding private :restarting and :resetting events which are send before the actor restarts or resets allowing to add callbacks to cleanup current child actors. - Print also object_id in Reference to_s - Add AbstractContext#default_executor to be able to override executor class wide - Add basic IO example - Documentation somewhat improved - All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and be sure that both jobs are processed first. * Refactored `Channel` to use newer synchronization objects * Added `#reset` and `#cancel` methods to `TimerSet` * Added `#cancel` method to `Future` and `ScheduledTask` * Refactored `TimerSet` to use `ScheduledTask` * Updated `Async` with a factory that initializes the object * Deprecated `Concurrent.timer` and `Concurrent.timeout` * Reduced max threads on pure-Ruby thread pools (abends around 14751 threads) * Moved many private/internal classes/modules into "namespace" modules * Removed brute-force killing of threads in tests * Fixed a thread pool bug when the operating system cannot allocate more threads ## Release v0.8.0 (25 January 2015) * C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem. Please see the README for more detail. * Better variable isolation in `Promise` and `Future` via an `:args` option * Continued to update intermittently failing tests ## Release v0.7.2 (24 January 2015) * New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html) * New `Promise.all?` and `Promise.any?` class methods * Renamed `:overflow_policy` on thread pools to `:fallback_policy` * Thread pools still accept the `:overflow_policy` option but display a warning * Thread pools now implement `fallback_policy` behavior when not running (rather than universally rejecting tasks) * Fixed minor `set_deref_options` constructor bug in `Promise` class * Fixed minor `require` bug in `ThreadLocalVar` class * Fixed race condition bug in `TimerSet` class * Fixed race condition bug in `TimerSet` class * Fixed signal bug in `TimerSet#post` method * Numerous non-functional updates to clear warning when running in debug mode * Fixed more intermittently failing tests * Tests now run on new Travis build environment * Multiple documentation updates ## Release v0.7.1 (4 December 2014) Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release. * Added `flat_map` method to `Promise` * Added `zip` method to `Promise` * Fixed bug with logging in `Actor` * Improvements to `Promise` tests * Removed actor-experimental warning * Added an `IndirectImmediateExecutor` class * Allow disabling auto termination of global executors * Fix thread leaking in `ThreadLocalVar` (uses `Ref` gem on non-JRuby systems) * Fix thread leaking when pruning pure-Ruby thread pools * Prevent `Actor` from using an `ImmediateExecutor` (causes deadlock) * Added missing synchronizations to `TimerSet` * Fixed bug with return value of `Concurrent::Actor::Utils::Pool#ask` * Fixed timing bug in `TimerTask` * Fixed bug when creating a `JavaThreadPoolExecutor` with minimum pool size of zero * Removed confusing warning when not using native extenstions * Improved documentation ## Release v0.7.0 (13 August 2014) * Merge the [atomic](https://github.com/ruby-concurrency/atomic) gem - Pure Ruby `MutexAtomic` atomic reference class - Platform native atomic reference classes `CAtomic`, `JavaAtomic`, and `RbxAtomic` - Automated [build process](https://github.com/ruby-concurrency/rake-compiler-dev-box) - Fat binary releases for [multiple platforms](https://rubygems.org/gems/concurrent-ruby/versions) including Windows (32/64), Linux (32/64), OS X (64-bit), Solaris (64-bit), and JRuby * C native `CAtomicBoolean` * C native `CAtomicFixnum` * Refactored intermittently failing tests * Added `dataflow!` and `dataflow_with!` methods to match `Future#value!` method * Better handling of timeout in `Agent` * Actor Improvements - Fine-grained implementation using chain of behaviors. Each behavior is responsible for single aspect like: `Termination`, `Pausing`, `Linking`, `Supervising`, etc. Users can create custom Actors easily based on their needs. - Supervision was added. `RestartingContext` will pause on error waiting on its supervisor to decide what to do next ( options are `:terminate!`, `:resume!`, `:reset!`, `:restart!`). Supervising behavior also supports strategies `:one_for_one` and `:one_for_all`. - Linking was added to be able to monitor actor's events like: `:terminated`, `:paused`, `:restarted`, etc. - Dead letter routing added. Rejected envelopes are collected in a configurable actor (default: `Concurrent::Actor.root.ask!(:dead_letter_routing)`) - Old `Actor` class removed and replaced by new implementation previously called `Actress`. `Actress` was kept as an alias for `Actor` to keep compatibility. - `Utils::Broadcast` actor which allows Publish–subscribe pattern. * More executors for managing serialized operations - `SerializedExecution` mixin module - `SerializedExecutionDelegator` for serializing *any* executor * Updated `Async` with serialized execution * Updated `ImmediateExecutor` and `PerThreadExecutor` with full executor service lifecycle * Added a `Delay` to root `Actress` initialization * Minor bug fixes to thread pools * Refactored many intermittently failing specs * Removed Java interop warning `executor.rb:148 warning: ambiguous Java methods found, using submit(java.lang.Runnable)` * Fixed minor bug in `RubyCachedThreadPool` overflow policy * Updated tests to use [RSpec 3.0](http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3) * Removed deprecated `Actor` class * Better support for Rubinius ## Release v0.6.1 (14 June 2014) * Many improvements to `Concurrent::Actress` * Bug fixes to `Concurrent::RubyThreadPoolExecutor` * Fixed several brittle tests * Moved documentation to http://ruby-concurrency.github.io/concurrent-ruby/frames.html ## Release v0.6.0 (25 May 2014) * Added `Concurrent::Observable` to encapsulate our thread safe observer sets * Improvements to new `Channel` * Major improvements to `CachedThreadPool` and `FixedThreadPool` * Added `SingleThreadExecutor` * Added `Current::timer` function * Added `TimerSet` executor * Added `AtomicBoolean` * `ScheduledTask` refactoring * Pure Ruby and JRuby-optimized `PriorityQueue` classes * Updated `Agent` behavior to more closely match Clojure * Observer sets support block callbacks to the `add_observer` method * New algorithm for thread creation in `RubyThreadPoolExecutor` * Minor API updates to `Event` * Rewritten `TimerTask` now an `Executor` instead of a `Runnable` * Fixed many brittle specs * Renamed `FixedThreadPool` and `CachedThreadPool` to `RubyFixedThreadPool` and `RubyCachedThreadPool` * Created JRuby optimized `JavaFixedThreadPool` and `JavaCachedThreadPool` * Consolidated fixed thread pool tests into `spec/concurrent/fixed_thread_pool_shared.rb` and `spec/concurrent/cached_thread_pool_shared.rb` * `FixedThreadPool` now subclasses `RubyFixedThreadPool` or `JavaFixedThreadPool` as appropriate * `CachedThreadPool` now subclasses `RubyCachedThreadPool` or `JavaCachedThreadPool` as appropriate * New `Delay` class * `Concurrent::processor_count` helper function * New `Async` module * Renamed `NullThreadPool` to `PerThreadExecutor` * Deprecated `Channel` (we are planning a new implementation based on [Go](http://golangtutorials.blogspot.com/2011/06/channels-in-go.html)) * Added gem-level [configuration](http://robots.thoughtbot.com/mygem-configure-block) * Deprecated `$GLOBAL_THREAD_POOL` in lieu of gem-level configuration * Removed support for Ruby [1.9.2](https://www.ruby-lang.org/en/news/2013/12/17/maintenance-of-1-8-7-and-1-9-2/) * New `RubyThreadPoolExecutor` and `JavaThreadPoolExecutor` classes * All thread pools now extend the appropriate thread pool executor classes * All thread pools now support `:overflow_policy` (based on Java's [reject policies](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html)) * Deprecated `UsesGlobalThreadPool` in lieu of explicit `:executor` option (dependency injection) on `Future`, `Promise`, and `Agent` * Added `Concurrent::dataflow_with(executor, *inputs)` method to support executor dependency injection for dataflow * Software transactional memory with `TVar` and `Concurrent::atomically` * First implementation of [new, high-performance](https://github.com/ruby-concurrency/concurrent-ruby/pull/49) `Channel` * `Actor` is deprecated in favor of new experimental actor implementation [#73](https://github.com/ruby-concurrency/concurrent-ruby/pull/73). To avoid namespace collision it is living in `Actress` namespace until `Actor` is removed in next release. ## Release v0.5.0 This is the most significant release of this gem since its inception. This release includes many improvements and optimizations. It also includes several bug fixes. The major areas of focus for this release were: * Stability improvements on Ruby versions with thread-level parallelism ([JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) * Creation of new low-level concurrency abstractions * Internal refactoring to use the new low-level abstractions Most of these updates had no effect on the gem API. There are a few notable exceptions which were unavoidable. Please read the [release notes](API-Updates-in-v0.5.0) for more information. Specific changes include: * New class `IVar` * New class `MVar` * New class `ThreadLocalVar` * New class `AtomicFixnum` * New class method `dataflow` * New class `Condition` * New class `CountDownLatch` * New class `DependencyCounter` * New class `SafeTaskExecutor` * New class `CopyOnNotifyObserverSet` * New class `CopyOnWriteObserverSet` * `Future` updated with `execute` API * `ScheduledTask` updated with `execute` API * New `Promise` API * `Future` now extends `IVar` * `Postable#post?` now returns an `IVar` * Thread safety fixes to `Dereferenceable` * Thread safety fixes to `Obligation` * Thread safety fixes to `Supervisor` * Thread safety fixes to `Event` * Various other thread safety (race condition) fixes * Refactored brittle tests * Implemented pending tests * Added JRuby and Rubinius as Travis CI build targets * Added [CodeClimate](https://codeclimate.com/) code review * Improved YARD documentation concurrent-ruby-ext-1.0.5/README.md0000644000175000017500000003726213147302606015773 0ustar pravipravi# Concurrent Ruby [![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby) [![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby) [![Build status](https://ci.appveyor.com/api/projects/status/iq8aboyuu3etad4w?svg=true)](https://ci.appveyor.com/project/rubyconcurrency/concurrent-ruby) [![Code Climate](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby.svg)](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby) [![Inline docs](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby.svg)](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby) [![Dependency Status](https://gemnasium.com/ruby-concurrency/concurrent-ruby.svg)](https://gemnasium.com/ruby-concurrency/concurrent-ruby) [![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT) [![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby) Modern concurrency tools for Ruby. Inspired by [Erlang](http://www.erlang.org/doc/reference_manual/processes.html), [Clojure](http://clojure.org/concurrent_programming), [Scala](http://akka.io/), [Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell), [F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx), [C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx), [Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html), and classic concurrency patterns. The design goals of this gem are: * Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why * Remain free of external gem dependencies * Stay true to the spirit of the languages providing inspiration * But implement in a way that makes sense for Ruby * Keep the semantics as idiomatic Ruby as possible * Support features that make sense in Ruby * Exclude features that don't make sense in Ruby * Be small, lean, and loosely coupled ### Supported Ruby versions MRI 1.9.3, 2.0 and above, JRuby 1.7x in 1.9 mode, JRuby 9000, and Rubinius 2.x are supported. This gem should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer. Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs is supported. ## Thread Safety *Concurrent Ruby makes the strongest thread safety guarantees of any Ruby concurrency library. We are the only library with a published [memory model](https://github.com/ruby-concurrency/concurrent-ruby/blob/master/doc/synchronization.md) which provides consistent behavior and guarantees on all three of the main Ruby interpreters (MRI/CRuby, JRuby, and Rubinius).* Every abstraction in this library is thread safe. Similarly, all are deadlock free and many are fully lock free. Specific thread safety guarantees are documented with each abstraction. It is critical to remember, however, that Ruby is a language of mutable references. *No* concurrency library for Ruby can ever prevent the user from making thread safety mistakes (such as sharing a mutable object between threads and modifying it on both threads) or from creating deadlocks through incorrect use of locks. All the library can do is provide safe abstractions which encourage safe practices. Concurrent Ruby provides more safe concurrency abstractions than any other Ruby library, many of which support the mantra of ["Do not communicate by sharing memory; instead, share memory by communicating"](https://blog.golang.org/share-memory-by-communicating). Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and immutable variable types and data structures. ## Features & Documentation The primary site for documentation is the automatically generated [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html) We also have a [mailing list](http://groups.google.com/group/concurrent-ruby) and [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby). #### General-purpose Concurrency Abstractions * [Async](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Async.html): A mixin module that provides simple asynchronous behavior to a class. Loosely based on Erlang's [gen_server](http://www.erlang.org/doc/man/gen_server.html). * [Future](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Future.html): An asynchronous operation that produces a value. * [Dataflow](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#dataflow-class_method): Built on Futures, Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available. * [Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html): Similar to Futures, with more features. * [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ScheduledTask.html): Like a Future scheduled for a specific future time. * [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html): A Thread that periodically wakes up to perform work at regular intervals. #### Thread-safe Value Objects, Structures, and Collections Collection classes that were originally part of the (deprecated) `thread_safe` gem: * [Array](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Array.html) A thread-safe subclass of Ruby's standard [Array](http://ruby-doc.org/core-2.2.0/Array.html). * [Hash](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Hash.html) A thread-safe subclass of Ruby's standard [Hash](http://ruby-doc.org/core-2.2.0/Hash.html). * [Map](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Map.html) A hash-like object that should have much better performance characteristics, especially under high concurrency, than `Concurrent::Hash`. * [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Tuple.html) A fixed size array with volatile (synchronized, thread safe) getters/setters. Value objects inspired by other languages: * [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Maybe.html) A thread-safe, immutable object representing an optional value, based on [Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html). * [Delay](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Delay.html) Lazy evaluation of a block yielding an immutable result. Based on Clojure's [delay](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Delay.html). Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html): * [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ImmutableStruct.html) Immutable struct where values are set at construction and cannot be changed later. * [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutableStruct.html) Synchronized, mutable struct where values can be safely changed at any time. * [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/SettableStruct.html) Synchronized, write-once struct where values can be set at most once, either at construction or any time thereafter. Thread-safe variables: * [Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html): A way to manage shared, mutable, *asynchronous*, independent state. Based on Clojure's [Agent](http://clojure.org/agents). * [Atom](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Atom.html): A way to manage shared, mutable, *synchronous*, independent state. Based on Clojure's [Atom](http://clojure.org/atoms). * [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicBoolean.html) A boolean value that can be updated atomically. * [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicFixnum.html) A numeric value that can be updated atomically. * [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutexAtomic.html) An object reference that may be updated atomically. * [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html) A synchronization point at which threads can pair and swap elements within pairs. Based on Java's [Exchanger](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html). * [MVar](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html) A synchronized single element container. Based on Haskell's [MVar](https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent-MVar.html) and Scala's [MVar](http://docs.typelevel.org/api/scalaz/nightly/index.html#scalaz.concurrent.MVar$). * [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html) A variable where the value is different for each thread. * [TVar](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TVar.html) A transactional variable implementing software transactional memory (STM). Based on Clojure's [Ref](http://clojure.org/refs). #### Java-inspired ThreadPools and Other Executors * See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/file.thread_pools.html) overview, which also contains a list of other Executors available. #### Thread Synchronization Classes and Algorithms * [CountDownLatch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html) A synchronization object that allows one thread to wait on multiple other threads. * [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html) A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. * [Event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html) Old school kernel-style event. * [IVar](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html) Similar to a "future" but can be manually assigned once, after which it becomes immutable. * [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReadWriteLock.html) A lock that supports multiple readers but only one writer. * [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReentrantReadWriteLock.html) A read/write lock with reentrant and upgrade features. * [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Semaphore.html) A counting-based locking mechanism that uses permits. ### Edge Features These are available in the `concurrent-ruby-edge` companion gem. These features are under active development and may change frequently. They are expected not to keep backward compatibility (there may also lack tests and documentation). Semantic versions will be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to `concurrent-ruby` when final. * [Promises Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promises.html): Unified implementation of futures and promises which combines features of previous `Future`, `Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and `TimerTask` into a single framework. It extensively uses the new synchronization layer to make all the features **non-blocking** and **lock-free**, with the exception of obviously blocking operations like `#wait`, `#value`. It also offers better performance. * [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html): Implements the Actor Model, where concurrent actors exchange messages. * [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/Channel.html): Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)). Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional inspiration from Clojure [core.async](https://clojure.github.io/core.async/). * [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LazyRegister.html) * [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/AtomicMarkableReference.html) * [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeLinkedSet.html) * [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LockFreeStack.html) #### Statuses: *Why are these not in core?* - **Promises Framework** - They are being finalized to be able to be moved to core. They'll deprecate old implementation. - **Actor** - Partial documentation and tests; depends on new future/promise framework; stability is good. - **Channel** - Brand new implementation; partial documentation and tests; stability is good. - **LazyRegister** - Missing documentation and tests. - **AtomicMarkableReference, LockFreeLinkedSet, LockFreeStack** - Need real world battle testing. ## Usage Everything within this gem can be loaded simply by requiring it: ```ruby require 'concurrent' ``` To use the tools in the Edge gem it must be required separately: ```ruby require 'concurrent-edge' ``` If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could help to reveal the problem. ## Installation ```shell gem install concurrent-ruby ``` or add the following line to Gemfile: ```ruby gem 'concurrent-ruby', require: 'concurrent' ``` and run `bundle install` from your shell. ### Edge Gem Installation The Edge gem must be installed separately from the core gem: ```shell gem install concurrent-ruby-edge ``` or add the following line to Gemfile: ```ruby gem 'concurrent-ruby-edge', require: 'concurrent-edge' ``` and run `bundle install` from your shell. ### C Extensions for MRI Potential performance improvements may be achieved under MRI by installing optional C extensions. To minimize installation errors the C extensions are available in the `concurrent-ruby-ext` extension gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same version. Simply install the extension gem too: ```ruby gem install concurrent-ruby-ext ``` or add the following line to Gemfile: ```ruby gem 'concurrent-ruby-ext' ``` and run `bundle install` from your shell. In code it is only necessary to ```ruby require 'concurrent' ``` The `concurrent-ruby` gem will automatically detect the presence of the `concurrent-ruby-ext` gem and load the appropriate C extensions. #### Note For gem developers No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions. ## Maintainers * [Petr Chalupa](https://github.com/pitr-ch) (lead maintainer) * [Jerry D'Antonio](https://github.com/jdantonio) (creator) * [Michele Della Torre](https://github.com/mighe) * [Chris Seaton](https://github.com/chrisseaton) * [PaweÅ‚ Obrok](https://github.com/obrok) * [Lucas Allan](https://github.com/lucasallan) ### Special Thanks * [Brian Durand](https://github.com/bdurand) for the `ref` gem * [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems * [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem ## License and Copyright *Concurrent Ruby* is free software released under the [MIT License](http://www.opensource.org/licenses/MIT). The *Concurrent Ruby* [logo](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Logo) was designed by [David Jones](https://twitter.com/zombyboy). It is Copyright © 2014 [Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved. concurrent-ruby-ext-1.0.5/lib/0000755000175000017500000000000013147302606015250 5ustar pravipraviconcurrent-ruby-ext-1.0.5/lib/concurrent/0000755000175000017500000000000013147302606017432 5ustar pravipraviconcurrent-ruby-ext-1.0.5/lib/concurrent/atomic_reference/0000755000175000017500000000000013147302606022724 5ustar pravipraviconcurrent-ruby-ext-1.0.5/lib/concurrent/atomic_reference/concurrent_update_error.rb0000644000175000017500000000037113147302606030207 0ustar pravipravimodule Concurrent # @!macro atomic_reference class ConcurrentUpdateError < ThreadError # frozen pre-allocated backtrace to speed ConcurrentUpdateError CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze end end concurrent-ruby-ext-1.0.5/lib/concurrent/atomic_reference/direct_update.rb0000644000175000017500000000540613147302606026072 0ustar pravipravirequire 'concurrent/atomic_reference/concurrent_update_error' module Concurrent # Define update methods that use direct paths # # @!visibility private # @!macro internal_implementation_note module AtomicDirectUpdate # @!macro [attach] atomic_reference_method_update # # Pass the current value to the given block, replacing it # with the block's result. May retry if the value changes # during the block's execution. # # @yield [Object] Calculate a new value for the atomic reference using # given (old) value # @yieldparam [Object] old_value the starting value of the atomic reference # # @return [Object] the new value def update true until compare_and_set(old_value = get, new_value = yield(old_value)) new_value end # @!macro [attach] atomic_reference_method_try_update # # Pass the current value to the given block, replacing it # with the block's result. Return nil if the update fails. # # @yield [Object] Calculate a new value for the atomic reference using # given (old) value # @yieldparam [Object] old_value the starting value of the atomic reference # # @note This method was altered to avoid raising an exception by default. # Instead, this method now returns `nil` in case of failure. For more info, # please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 # # @return [Object] the new value, or nil if update failed def try_update old_value = get new_value = yield old_value return unless compare_and_set old_value, new_value new_value end # @!macro [attach] atomic_reference_method_try_update! # # Pass the current value to the given block, replacing it # with the block's result. Raise an exception if the update # fails. # # @yield [Object] Calculate a new value for the atomic reference using # given (old) value # @yieldparam [Object] old_value the starting value of the atomic reference # # @note This behavior mimics the behavior of the original # `AtomicReference#try_update` API. The reason this was changed was to # avoid raising exceptions (which are inherently slow) by default. For more # info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 # # @return [Object] the new value # # @raise [Concurrent::ConcurrentUpdateError] if the update fails def try_update! old_value = get new_value = yield old_value unless compare_and_set(old_value, new_value) if $VERBOSE raise ConcurrentUpdateError, "Update failed" else raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE end end new_value end end end concurrent-ruby-ext-1.0.5/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb0000644000175000017500000000130013147302606027273 0ustar pravipravimodule Concurrent # Special "compare and set" handling of numeric values. # # @!visibility private # @!macro internal_implementation_note module AtomicNumericCompareAndSetWrapper # @!macro atomic_reference_method_compare_and_set def compare_and_set(old_value, new_value) if old_value.kind_of? Numeric while true old = get return false unless old.kind_of? Numeric return false unless old == old_value result = _compare_and_set(old, new_value) return result if result end else _compare_and_set(old_value, new_value) end end alias_method :compare_and_swap, :compare_and_set end end concurrent-ruby-ext-1.0.5/ext/0000755000175000017500000000000013147302606015302 5ustar pravipraviconcurrent-ruby-ext-1.0.5/ext/concurrent/0000755000175000017500000000000013147302606017464 5ustar pravipraviconcurrent-ruby-ext-1.0.5/ext/concurrent/extconf.rb0000644000175000017500000000243413147302606021462 0ustar pravipravirequire 'fileutils' $:.unshift(File.expand_path('../../../lib', __FILE__)) require 'concurrent/utility/native_extension_loader' EXTENSION_NAME = 'extension' def create_dummy_makefile File.open('Makefile', 'w') do |f| f.puts 'all:' f.puts 'install:' end end if Concurrent.on_jruby? || ! Concurrent.allow_c_extensions? create_dummy_makefile warn 'C optimizations are not supported on this version of Ruby.' else begin require 'mkmf' dir_config(EXTENSION_NAME) have_header "libkern/OSAtomic.h" def compiler_is_gcc if CONFIG["GCC"] && CONFIG["GCC"] != "" return true elsif ( # This could stand to be more generic... but I am afraid. CONFIG["CC"] =~ /\bgcc\b/ ) return true end return false end if compiler_is_gcc case CONFIG["arch"] when /mswin32|mingw|solaris/ $CFLAGS += " -march=native" when 'i686-linux' $CFLAGS += " -march=i686" end end try_run(< #include "atomic_reference.h" #include "atomic_boolean.h" #include "atomic_fixnum.h" // module and class definitions static VALUE rb_mConcurrent; static VALUE rb_cAtomicReference; static VALUE rb_cAtomicBoolean; static VALUE rb_cAtomicFixnum; // Init_extension void Init_extension() { // define modules and classes rb_mConcurrent = rb_define_module("Concurrent"); rb_cAtomicReference = rb_define_class_under(rb_mConcurrent, "CAtomicReference", rb_cObject); rb_cAtomicBoolean = rb_define_class_under(rb_mConcurrent, "CAtomicBoolean", rb_cObject); rb_cAtomicFixnum = rb_define_class_under(rb_mConcurrent, "CAtomicFixnum", rb_cObject); // CAtomicReference rb_define_alloc_func(rb_cAtomicReference, ir_alloc); rb_define_method(rb_cAtomicReference, "initialize", ir_initialize, -1); rb_define_method(rb_cAtomicReference, "get", ir_get, 0); rb_define_method(rb_cAtomicReference, "set", ir_set, 1); rb_define_method(rb_cAtomicReference, "get_and_set", ir_get_and_set, 1); rb_define_method(rb_cAtomicReference, "_compare_and_set", ir_compare_and_set, 2); rb_define_alias(rb_cAtomicReference, "value", "get"); rb_define_alias(rb_cAtomicReference, "value=", "set"); rb_define_alias(rb_cAtomicReference, "swap", "get_and_set"); // CAtomicBoolean rb_define_alloc_func(rb_cAtomicBoolean, atomic_boolean_allocate); rb_define_method(rb_cAtomicBoolean, "initialize", method_atomic_boolean_initialize, -1); rb_define_method(rb_cAtomicBoolean, "value", method_atomic_boolean_value, 0); rb_define_method(rb_cAtomicBoolean, "value=", method_atomic_boolean_value_set, 1); rb_define_method(rb_cAtomicBoolean, "true?", method_atomic_boolean_true_question, 0); rb_define_method(rb_cAtomicBoolean, "false?", method_atomic_boolean_false_question, 0); rb_define_method(rb_cAtomicBoolean, "make_true", method_atomic_boolean_make_true, 0); rb_define_method(rb_cAtomicBoolean, "make_false", method_atomic_boolean_make_false, 0); // CAtomicFixnum rb_define_const(rb_cAtomicFixnum, "MIN_VALUE", LL2NUM(LLONG_MIN)); rb_define_const(rb_cAtomicFixnum, "MAX_VALUE", LL2NUM(LLONG_MAX)); rb_define_alloc_func(rb_cAtomicFixnum, atomic_fixnum_allocate); rb_define_method(rb_cAtomicFixnum, "initialize", method_atomic_fixnum_initialize, -1); rb_define_method(rb_cAtomicFixnum, "value", method_atomic_fixnum_value, 0); rb_define_method(rb_cAtomicFixnum, "value=", method_atomic_fixnum_value_set, 1); rb_define_method(rb_cAtomicFixnum, "increment", method_atomic_fixnum_increment, -1); rb_define_method(rb_cAtomicFixnum, "decrement", method_atomic_fixnum_decrement, -1); rb_define_method(rb_cAtomicFixnum, "compare_and_set", method_atomic_fixnum_compare_and_set, 2); rb_define_method(rb_cAtomicFixnum, "update", method_atomic_fixnum_update, 0); rb_define_alias(rb_cAtomicFixnum, "up", "increment"); rb_define_alias(rb_cAtomicFixnum, "down", "decrement"); } concurrent-ruby-ext-1.0.5/ext/concurrent/atomic_reference.c0000644000175000017500000000463713147302606023134 0ustar pravipravi#include /*#if defined(__sun)*/ /*#include */ /*#endif*/ /*#ifdef HAVE_LIBKERN_OSATOMIC_H*/ /*#include */ /*#endif*/ #include "atomic_reference.h" void ir_mark(void *value) { rb_gc_mark_maybe((VALUE) value); } VALUE ir_alloc(VALUE klass) { return rb_data_object_alloc(klass, (void *) Qnil, ir_mark, NULL); } VALUE ir_initialize(int argc, VALUE* argv, VALUE self) { VALUE value = Qnil; if (rb_scan_args(argc, argv, "01", &value) == 1) { value = argv[0]; } DATA_PTR(self) = (void *) value; return Qnil; } VALUE ir_get(VALUE self) { #if HAVE_GCC_SYNC __sync_synchronize(); #elif defined _MSC_VER MemoryBarrier(); #elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 OSMemoryBarrier(); #endif return (VALUE) DATA_PTR(self); } VALUE ir_set(VALUE self, VALUE new_value) { DATA_PTR(self) = (void *) new_value; #if HAVE_GCC_SYNC __sync_synchronize(); #elif defined _MSC_VER MemoryBarrier(); #elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 OSMemoryBarrier(); #endif return new_value; } VALUE ir_get_and_set(VALUE self, VALUE new_value) { VALUE old_value; for (;;) { old_value = ir_get(self); if (ir_compare_and_set(self, old_value, new_value) == Qtrue) { return old_value; } } } VALUE ir_compare_and_set(volatile VALUE self, VALUE expect_value, VALUE new_value) { #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 if (OSAtomicCompareAndSwap64(expect_value, new_value, &DATA_PTR(self))) { return Qtrue; } #elif defined(__sun) /* Assuming VALUE is uintptr_t */ /* Based on the definition of uintptr_t from /usr/include/sys/int_types.h */ #if defined(_LP64) || defined(_I32LPx) /* 64-bit: uintptr_t === unsigned long */ if (atomic_cas_ulong((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) { return Qtrue; } #else /* 32-bit: uintptr_t === unsigned int */ if (atomic_cas_uint((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) { return Qtrue; } #endif #elif defined _MSC_VER && defined _M_AMD64 if (InterlockedCompareExchange64((LONGLONG*)&DATA_PTR(self), new_value, expect_value)) { return Qtrue; } #elif defined _MSC_VER && defined _M_IX86 if (InterlockedCompareExchange((LONG*)&DATA_PTR(self), new_value, expect_value)) { return Qtrue; } #else if (__sync_bool_compare_and_swap(&DATA_PTR(self), expect_value, new_value)) { return Qtrue; } #endif return Qfalse; } concurrent-ruby-ext-1.0.5/ext/concurrent/atomic_boolean.h0000644000175000017500000000106113147302606022606 0ustar pravipravi#ifndef __ATOMIC_BOOLEAN_H__ #define __ATOMIC_BOOLEAN_H__ #define TRUTHY(value)(value == Qfalse || value == Qnil ? Qfalse : Qtrue) void atomic_boolean_mark(void*); VALUE atomic_boolean_allocate(VALUE); VALUE method_atomic_boolean_initialize(int, VALUE*, VALUE); VALUE method_atomic_boolean_value(VALUE); VALUE method_atomic_boolean_value_set(VALUE, VALUE); VALUE method_atomic_boolean_true_question(VALUE); VALUE method_atomic_boolean_false_question(VALUE); VALUE method_atomic_boolean_make_true(VALUE); VALUE method_atomic_boolean_make_false(VALUE); #endif concurrent-ruby-ext-1.0.5/ext/concurrent/ruby_193_compatible.h0000644000175000017500000000147413147302606023417 0ustar pravipravi#ifndef rb_check_arity // https://github.com/ruby/ruby/blob/ruby_2_0_0/include/ruby/intern.h // rb_check_arity was added in Ruby 2.0 #define UNLIMITED_ARGUMENTS (-1) static inline VALUE rb_error_arity(int argc, int min, int max) { VALUE err_mess = 0; if (min == max) { err_mess = rb_sprintf("wrong number of arguments (%d for %d)", argc, min); } else if (max == UNLIMITED_ARGUMENTS) { err_mess = rb_sprintf("wrong number of arguments (%d for %d+)", argc, min); } else { err_mess = rb_sprintf("wrong number of arguments (%d for %d..%d)", argc, min, max); } return rb_exc_new3(rb_eTypeError, err_mess); } #define rb_check_arity(argc, min, max) do { \ if (((argc) < (min)) || ((argc) > (max) && (max) != UNLIMITED_ARGUMENTS)) \ rb_exc_raise(rb_error_arity(argc, min, max)); \ } while(0) #endif concurrent-ruby-ext-1.0.5/ext/concurrent/atomic_reference.h0000644000175000017500000000063513147302606023133 0ustar pravipravi#ifndef __ATOMIC_REFERENCE_H__ #define __ATOMIC_REFERENCE_H__ #if defined(__sun) #include #endif #ifdef HAVE_LIBKERN_OSATOMIC_H #include #endif void ir_mark(void*); VALUE ir_alloc(VALUE); VALUE ir_initialize(int, VALUE*, VALUE); VALUE ir_get(VALUE); VALUE ir_set(VALUE, VALUE); VALUE ir_get_and_set(VALUE, VALUE); VALUE ir_compare_and_set(volatile VALUE, VALUE, VALUE); #endif concurrent-ruby-ext-1.0.5/ext/concurrent/atomic_boolean.c0000644000175000017500000000236313147302606022607 0ustar pravipravi#include #include "atomic_boolean.h" #include "atomic_reference.h" #include "ruby_193_compatible.h" void atomic_boolean_mark(void *value) { rb_gc_mark_maybe((VALUE) value); } VALUE atomic_boolean_allocate(VALUE klass) { return rb_data_object_alloc(klass, (void *) Qfalse, atomic_boolean_mark, NULL); } VALUE method_atomic_boolean_initialize(int argc, VALUE* argv, VALUE self) { VALUE value = Qfalse; rb_check_arity(argc, 0, 1); if (argc == 1) value = TRUTHY(argv[0]); DATA_PTR(self) = (void *) value; return(self); } VALUE method_atomic_boolean_value(VALUE self) { return (VALUE) DATA_PTR(self); } VALUE method_atomic_boolean_value_set(VALUE self, VALUE value) { VALUE new_value = TRUTHY(value); DATA_PTR(self) = (void *) new_value; return(new_value); } VALUE method_atomic_boolean_true_question(VALUE self) { return(method_atomic_boolean_value(self)); } VALUE method_atomic_boolean_false_question(VALUE self) { VALUE current = method_atomic_boolean_value(self); return(current == Qfalse ? Qtrue : Qfalse); } VALUE method_atomic_boolean_make_true(VALUE self) { return(ir_compare_and_set(self, Qfalse, Qtrue)); } VALUE method_atomic_boolean_make_false(VALUE self) { return(ir_compare_and_set(self, Qtrue, Qfalse)); } concurrent-ruby-ext-1.0.5/ext/concurrent/atomic_fixnum.c0000644000175000017500000000370713147302606022501 0ustar pravipravi#include #include "atomic_fixnum.h" #include "atomic_reference.h" #include "ruby_193_compatible.h" void atomic_fixnum_mark(void *value) { rb_gc_mark_maybe((VALUE) value); } VALUE atomic_fixnum_allocate(VALUE klass) { return rb_data_object_alloc(klass, (void *) Qnil, atomic_fixnum_mark, NULL); } VALUE method_atomic_fixnum_initialize(int argc, VALUE* argv, VALUE self) { VALUE value = LL2NUM(0); rb_check_arity(argc, 0, 1); if (argc == 1) { Check_Type(argv[0], T_FIXNUM); value = argv[0]; } DATA_PTR(self) = (void *) value; return(self); } VALUE method_atomic_fixnum_value(VALUE self) { return (VALUE) DATA_PTR(self); } VALUE method_atomic_fixnum_value_set(VALUE self, VALUE value) { Check_Type(value, T_FIXNUM); DATA_PTR(self) = (void *) value; return(value); } VALUE method_atomic_fixnum_increment(int argc, VALUE* argv, VALUE self) { long long value = NUM2LL((VALUE) DATA_PTR(self)); long long delta = 1; rb_check_arity(argc, 0, 1); if (argc == 1) { Check_Type(argv[0], T_FIXNUM); delta = NUM2LL(argv[0]); } return method_atomic_fixnum_value_set(self, LL2NUM(value + delta)); } VALUE method_atomic_fixnum_decrement(int argc, VALUE* argv, VALUE self) { long long value = NUM2LL((VALUE) DATA_PTR(self)); long long delta = 1; rb_check_arity(argc, 0, 1); if (argc == 1) { Check_Type(argv[0], T_FIXNUM); delta = NUM2LL(argv[0]); } return method_atomic_fixnum_value_set(self, LL2NUM(value - delta)); } VALUE method_atomic_fixnum_compare_and_set(VALUE self, VALUE rb_expect, VALUE rb_update) { Check_Type(rb_expect, T_FIXNUM); Check_Type(rb_update, T_FIXNUM); return ir_compare_and_set(self, rb_expect, rb_update); } VALUE method_atomic_fixnum_update(VALUE self) { VALUE old_value, new_value; for (;;) { old_value = method_atomic_fixnum_value(self); new_value = rb_yield(old_value); if (ir_compare_and_set(self, old_value, new_value) == Qtrue) { return new_value; } } } concurrent-ruby-ext-1.0.5/concurrent-ruby-ext.gemspec0000644000175000017500000000440213147302606022006 0ustar pravipravi######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: concurrent-ruby-ext 1.0.5 ruby libext # stub: ext/concurrent/extconf.rb Gem::Specification.new do |s| s.name = "concurrent-ruby-ext".freeze s.version = "1.0.5" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze, "ext".freeze] s.authors = ["Jerry D'Antonio".freeze, "The Ruby Concurrency Team".freeze] s.date = "2017-02-26" s.description = " C extensions to optimize the concurrent-ruby gem when running under MRI.\n Please see http://concurrent-ruby.com for more information.\n".freeze s.email = "concurrent-ruby@googlegroups.com".freeze s.extensions = ["ext/concurrent/extconf.rb".freeze] s.extra_rdoc_files = ["CHANGELOG.md".freeze, "LICENSE.txt".freeze, "README.md".freeze] s.files = ["CHANGELOG.md".freeze, "LICENSE.txt".freeze, "README.md".freeze, "ext/concurrent/atomic_boolean.c".freeze, "ext/concurrent/atomic_boolean.h".freeze, "ext/concurrent/atomic_fixnum.c".freeze, "ext/concurrent/atomic_fixnum.h".freeze, "ext/concurrent/atomic_reference.c".freeze, "ext/concurrent/atomic_reference.h".freeze, "ext/concurrent/extconf.rb".freeze, "ext/concurrent/rb_concurrent.c".freeze, "ext/concurrent/ruby_193_compatible.h".freeze, "lib/concurrent/atomic_reference/concurrent_update_error.rb".freeze, "lib/concurrent/atomic_reference/direct_update.rb".freeze, "lib/concurrent/atomic_reference/numeric_cas_wrapper.rb".freeze] s.homepage = "http://www.concurrent-ruby.com".freeze s.licenses = ["MIT".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9.3".freeze) s.rubygems_version = "2.5.2".freeze s.summary = "C extensions to optimize concurrent-ruby under MRI.".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q.freeze, ["= 1.0.5"]) else s.add_dependency(%q.freeze, ["= 1.0.5"]) end else s.add_dependency(%q.freeze, ["= 1.0.5"]) end end concurrent-ruby-ext-1.0.5/LICENSE.txt0000644000175000017500000000222613147302606016327 0ustar pravipraviCopyright (c) Jerry D'Antonio -- released under the MIT license. http://www.opensource.org/licenses/mit-license.php Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.