File: volatile.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 (101 lines) | stat: -rw-r--r-- 2,652 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
require 'concurrent/utility/native_extension_loader' # load native parts first
require 'concurrent/utility/engine'
require 'concurrent/synchronization/full_memory_barrier'

module Concurrent
  module Synchronization

    # Volatile adds the attr_volatile class method when included.
    #
    # @example
    #   class Foo
    #     include Concurrent::Synchronization::Volatile
    #
    #     attr_volatile :bar
    #
    #     def initialize
    #       self.bar = 1
    #     end
    #   end
    #
    #  foo = Foo.new
    #  foo.bar
    #  => 1
    #  foo.bar = 2
    #  => 2
    #
    # @!visibility private
    module Volatile
      def self.included(base)
        base.extend(ClassMethods)
      end

      def full_memory_barrier
        Synchronization.full_memory_barrier
      end

      module ClassMethods
        if Concurrent.on_cruby?
          def attr_volatile(*names)
            names.each do |name|
              ivar = :"@volatile_#{name}"
              class_eval <<-RUBY, __FILE__, __LINE__ + 1
                def #{name}
                  #{ivar}
                end

                def #{name}=(value)
                  #{ivar} = value
                end
              RUBY
            end
            names.map { |n| [n, :"#{n}="] }.flatten
          end

        elsif Concurrent.on_jruby?
          def attr_volatile(*names)
            names.each do |name|
              ivar = :"@volatile_#{name}"

              class_eval <<-RUBY, __FILE__, __LINE__ + 1
                def #{name}
                  ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_get_volatile(self, :#{ivar})
                end

                def #{name}=(value)
                  ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_set_volatile(self, :#{ivar}, value)
                end
              RUBY

            end
            names.map { |n| [n, :"#{n}="] }.flatten
          end

        else
          warn 'Possibly unsupported Ruby implementation' unless Concurrent.on_truffleruby?

          def attr_volatile(*names)
            names.each do |name|
              ivar = :"@volatile_#{name}"

              class_eval <<-RUBY, __FILE__, __LINE__ + 1
                def #{name}
                  ::Concurrent::Synchronization.full_memory_barrier
                  #{ivar}
                end

                def #{name}=(value)
                  #{ivar} = value
                  ::Concurrent::Synchronization.full_memory_barrier
                end
              RUBY
            end

            names.map { |n| [n, :"#{n}="] }.flatten
          end
        end
      end

    end
  end
end