File: atomic_reference.rb

package info (click to toggle)
ruby-concurrent 1.3.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,136 kB
  • sloc: ruby: 30,875; java: 6,128; ansic: 265; makefile: 26; sh: 19
file content (135 lines) | stat: -rw-r--r-- 5,988 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
require 'concurrent/utility/native_extension_loader' # load native parts first

require 'concurrent/atomic_reference/atomic_direct_update'
require 'concurrent/atomic_reference/numeric_cas_wrapper'
require 'concurrent/atomic_reference/mutex_atomic'

# Shim for TruffleRuby::AtomicReference
if Concurrent.on_truffleruby? && !defined?(TruffleRuby::AtomicReference)
  # @!visibility private
  module TruffleRuby
    AtomicReference = Truffle::AtomicReference
  end
end

module Concurrent

  # @!macro internal_implementation_note
  AtomicReferenceImplementation = case
                                  when Concurrent.on_cruby? && Concurrent.c_extensions_loaded?
                                    # @!visibility private
                                    # @!macro internal_implementation_note
                                    class CAtomicReference
                                      include AtomicDirectUpdate
                                      include AtomicNumericCompareAndSetWrapper
                                      alias_method :compare_and_swap, :compare_and_set
                                    end
                                    CAtomicReference
                                  when Concurrent.on_jruby?
                                    # @!visibility private
                                    # @!macro internal_implementation_note
                                    class JavaAtomicReference
                                      include AtomicDirectUpdate
                                    end
                                    JavaAtomicReference
                                  when Concurrent.on_truffleruby?
                                    class TruffleRubyAtomicReference < TruffleRuby::AtomicReference
                                      include AtomicDirectUpdate
                                      alias_method :value, :get
                                      alias_method :value=, :set
                                      alias_method :compare_and_swap, :compare_and_set
                                      alias_method :swap, :get_and_set
                                    end
                                    TruffleRubyAtomicReference
                                  else
                                    MutexAtomicReference
                                  end
  private_constant :AtomicReferenceImplementation

  # An object reference that may be updated atomically. All read and write
  # operations have java volatile semantic.
  #
  # @!macro thread_safe_variable_comparison
  #
  # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html
  # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html
  #
  # @!method initialize(value = nil)
  #   @!macro atomic_reference_method_initialize
  #     @param [Object] value The initial value.
  #
  # @!method get
  #   @!macro atomic_reference_method_get
  #     Gets the current value.
  #     @return [Object] the current value
  #
  # @!method set(new_value)
  #   @!macro atomic_reference_method_set
  #     Sets to the given value.
  #     @param [Object] new_value the new value
  #     @return [Object] the new value
  #
  # @!method get_and_set(new_value)
  #   @!macro atomic_reference_method_get_and_set
  #     Atomically sets to the given value and returns the old value.
  #     @param [Object] new_value the new value
  #     @return [Object] the old value
  #
  # @!method compare_and_set(old_value, new_value)
  #   @!macro atomic_reference_method_compare_and_set
  #
  #     Atomically sets the value to the given updated value if
  #     the current value == the expected value.
  #
  #     @param [Object] old_value the expected value
  #     @param [Object] new_value the new value
  #
  #     @return [Boolean] `true` if successful. A `false` return indicates
  #     that the actual value was not equal to the expected value.
  #
  # @!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
  #
  # @!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
  #
  # @!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
  class AtomicReference < AtomicReferenceImplementation

    # @return [String] Short string representation.
    def to_s
      format '%s value:%s>', super[0..-2], get
    end

    alias_method :inspect, :to_s
  end
end