volt 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +56 -0
- data/CHANGELOG.md +4 -0
- data/Rakefile +0 -1
- data/app/volt/models/user.rb +1 -3
- data/app/volt/tasks/live_query/live_query.rb +1 -1
- data/app/volt/tasks/store_tasks.rb +4 -5
- data/app/volt/tasks/user_tasks.rb +1 -1
- data/lib/volt.rb +2 -6
- data/lib/volt/boot.rb +0 -2
- data/lib/volt/cli.rb +0 -1
- data/lib/volt/cli/asset_compile.rb +0 -2
- data/lib/volt/cli/console.rb +3 -4
- data/lib/volt/cli/generate.rb +3 -4
- data/lib/volt/cli/new_gem.rb +1 -3
- data/lib/volt/controllers/actions.rb +6 -6
- data/lib/volt/controllers/model_controller.rb +4 -8
- data/lib/volt/data_stores/base.rb +1 -2
- data/lib/volt/data_stores/data_store.rb +2 -2
- data/lib/volt/data_stores/mongo_driver.rb +3 -3
- data/lib/volt/extra_core/hash.rb +1 -1
- data/lib/volt/extra_core/inflector/inflections.rb +10 -2
- data/lib/volt/extra_core/logger.rb +1 -4
- data/lib/volt/extra_core/object.rb +1 -1
- data/lib/volt/models.rb +2 -4
- data/lib/volt/models/array_model.rb +3 -7
- data/lib/volt/models/associations.rb +5 -4
- data/lib/volt/models/buffer.rb +1 -2
- data/lib/volt/models/dirty.rb +2 -2
- data/lib/volt/models/errors.rb +1 -1
- data/lib/volt/models/listener_tracker.rb +1 -3
- data/lib/volt/models/model.rb +16 -20
- data/lib/volt/models/permissions.rb +15 -18
- data/lib/volt/models/persistors/array_store.rb +5 -10
- data/lib/volt/models/persistors/cookies.rb +2 -2
- data/lib/volt/models/persistors/model_store.rb +3 -9
- data/lib/volt/models/persistors/params.rb +1 -3
- data/lib/volt/models/persistors/query/normalizer.rb +3 -3
- data/lib/volt/models/persistors/query/query_listener.rb +1 -1
- data/lib/volt/models/persistors/store.rb +2 -2
- data/lib/volt/models/state_helpers.rb +1 -1
- data/lib/volt/models/state_manager.rb +4 -4
- data/lib/volt/models/url.rb +2 -6
- data/lib/volt/models/validations.rb +8 -13
- data/lib/volt/models/validators/numericality_validator.rb +2 -6
- data/lib/volt/models/validators/unique_validator.rb +1 -1
- data/lib/volt/models/validators/user_validation.rb +0 -1
- data/lib/volt/page/bindings/attribute_binding.rb +9 -19
- data/lib/volt/page/bindings/content_binding.rb +1 -1
- data/lib/volt/page/bindings/each_binding.rb +3 -4
- data/lib/volt/page/bindings/if_binding.rb +1 -1
- data/lib/volt/page/bindings/view_binding.rb +15 -22
- data/lib/volt/page/bindings/view_binding/controller_handler.rb +5 -7
- data/lib/volt/page/bindings/view_binding/view_lookup_for_path.rb +1 -2
- data/lib/volt/page/bindings/yield_binding.rb +1 -2
- data/lib/volt/page/channel.rb +3 -3
- data/lib/volt/page/document_events.rb +1 -1
- data/lib/volt/page/page.rb +3 -6
- data/lib/volt/page/path_string_renderer.rb +7 -8
- data/lib/volt/page/sub_context.rb +1 -3
- data/lib/volt/page/targets/binding_document/component_node.rb +1 -3
- data/lib/volt/page/tasks.rb +3 -5
- data/lib/volt/reactive/class_eventable.rb +2 -2
- data/lib/volt/reactive/computation.rb +7 -7
- data/lib/volt/reactive/dependency.rb +1 -1
- data/lib/volt/reactive/eventable.rb +3 -4
- data/lib/volt/reactive/reactive_accessors.rb +0 -1
- data/lib/volt/reactive/reactive_array.rb +4 -12
- data/lib/volt/router/routes.rb +1 -3
- data/lib/volt/server.rb +6 -6
- data/lib/volt/server/component_handler.rb +1 -1
- data/lib/volt/server/component_templates.rb +2 -2
- data/lib/volt/server/forking_server.rb +6 -9
- data/lib/volt/server/html_parser/component_view_scope.rb +2 -2
- data/lib/volt/server/html_parser/each_scope.rb +1 -1
- data/lib/volt/server/html_parser/sandlebars_parser.rb +2 -6
- data/lib/volt/server/html_parser/view_handler.rb +1 -1
- data/lib/volt/server/html_parser/view_parser.rb +1 -1
- data/lib/volt/server/html_parser/view_scope.rb +2 -4
- data/lib/volt/server/rack/asset_files.rb +1 -3
- data/lib/volt/server/rack/component_paths.rb +1 -3
- data/lib/volt/server/rack/http_request.rb +1 -3
- data/lib/volt/server/rack/http_resource.rb +1 -3
- data/lib/volt/server/rack/http_response_renderer.rb +2 -2
- data/lib/volt/server/rack/index_files.rb +1 -1
- data/lib/volt/server/rack/opal_files.rb +1 -3
- data/lib/volt/server/socket_connection_handler.rb +1 -3
- data/lib/volt/server/websocket/rack_server_adaptor.rb +1 -1
- data/lib/volt/server/websocket/websocket_handler.rb +1 -2
- data/lib/volt/spec/capybara.rb +1 -1
- data/lib/volt/spec/setup.rb +18 -12
- data/lib/volt/tasks/dispatcher.rb +1 -2
- data/lib/volt/tasks/task_handler.rb +1 -3
- data/lib/volt/utils/boolean_patch.rb +1 -1
- data/lib/volt/utils/event_counter.rb +2 -2
- data/lib/volt/utils/generic_pool.rb +5 -9
- data/lib/volt/utils/logging/task_argument_filterer.rb +4 -4
- data/lib/volt/utils/logging/task_logger.rb +2 -2
- data/lib/volt/utils/modes.rb +2 -2
- data/lib/volt/utils/promise_patch.rb +1 -2
- data/lib/volt/utils/read_write_lock.rb +21 -23
- data/lib/volt/utils/tilt_patch.rb +1 -1
- data/lib/volt/utils/timers.rb +3 -7
- data/lib/volt/utils/volt_user_error.rb +1 -1
- data/lib/volt/version.rb +2 -2
- data/lib/volt/volt/app.rb +4 -6
- data/lib/volt/volt/users.rb +4 -3
- data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/controllers/server/simple_http_controller.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/controllers/todos_controller.rb +5 -5
- data/spec/apps/kitchen_sink/app/main/controllers/upload_controller.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/controllers/yield_component_controller.rb +1 -1
- data/spec/controllers/actions_spec.rb +9 -10
- data/spec/controllers/model_controller_spec.rb +1 -1
- data/spec/extra_core/blank_spec.rb +2 -2
- data/spec/extra_core/logger_spec.rb +6 -8
- data/spec/extra_core/string_transformations_spec.rb +3 -3
- data/spec/integration/bindings_spec.rb +3 -9
- data/spec/integration/first_last_spec.rb +1 -1
- data/spec/integration/missing_spec.rb +1 -2
- data/spec/integration/raw_html_binding.rb +2 -2
- data/spec/integration/todos_spec.rb +22 -0
- data/spec/integration/yield_spec.rb +2 -2
- data/spec/models/associations_spec.rb +4 -4
- data/spec/models/buffer_spec.rb +2 -2
- data/spec/models/dirty_spec.rb +10 -11
- data/spec/models/model_spec.rb +19 -13
- data/spec/models/model_state_spec.rb +1 -1
- data/spec/models/permissions_spec.rb +8 -12
- data/spec/models/url_spec.rb +1 -1
- data/spec/models/user_spec.rb +17 -10
- data/spec/models/user_validation_spec.rb +2 -3
- data/spec/models/validations_spec.rb +7 -10
- data/spec/models/validators/email_validator_spec.rb +5 -7
- data/spec/models/validators/format_validator_spec.rb +21 -3
- data/spec/models/validators/length_validator_spec.rb +12 -22
- data/spec/models/validators/shared_examples_for_validators.rb +1 -1
- data/spec/models/validators/unique_validator_spec.rb +1 -2
- data/spec/page/bindings/content_binding_spec.rb +1 -1
- data/spec/page/bindings/template_binding/view_lookup_for_path_spec.rb +0 -1
- data/spec/page/path_string_renderer_spec.rb +2 -3
- data/spec/reactive/class_eventable_spec.rb +1 -1
- data/spec/reactive/computation_spec.rb +30 -31
- data/spec/reactive/reactive_hash_spec.rb +1 -1
- data/spec/router/routes_spec.rb +14 -16
- data/spec/server/html_parser/view_handler_spec.rb +1 -1
- data/spec/server/html_parser/view_parser_spec.rb +0 -1
- data/spec/server/rack/quite_common_logger_spec.rb +3 -3
- data/spec/tasks/dispatcher_spec.rb +1 -1
- data/spec/tasks/query_tracker_spec.rb +1 -3
- data/spec/utils/task_argument_filtererer_spec.rb +5 -5
- data/templates/project/app/main/controllers/main_controller.rb +1 -1
- data/templates/project/spec/app/main/models/sample_model_spec.rb +2 -2
- data/templates/project/spec/app/main/tasks/sample_task_spec.rb +2 -2
- data/volt.gemspec +3 -5
- metadata +19 -4
@@ -48,7 +48,7 @@ module Volt
|
|
48
48
|
def close_scope
|
49
49
|
binding_number = @handler.scope[-2].binding_number
|
50
50
|
@handler.scope[-2].binding_number += 1
|
51
|
-
@path
|
51
|
+
@path += "/__template/#{binding_number}"
|
52
52
|
|
53
53
|
super
|
54
54
|
|
@@ -56,4 +56,4 @@ module Volt
|
|
56
56
|
@handler.scope.last.save_binding(binding_number, "lambda { |__p, __t, __c, __id| Volt::ComponentBinding.new(__p, __t, __c, __id, #{@binding_in_path.inspect}, Proc.new { [#{@arguments}] }, #{@path.inspect}) }")
|
57
57
|
end
|
58
58
|
end
|
59
|
-
end
|
59
|
+
end
|
@@ -156,16 +156,12 @@ module Volt
|
|
156
156
|
|
157
157
|
# Some tags close themselves when a new one of themselves is reached.
|
158
158
|
# ex, a tr will close the previous tr
|
159
|
-
if CLOSE_SELF[tag_name] && last == tag_name
|
160
|
-
end_tag(nil, tag_name)
|
161
|
-
end
|
159
|
+
end_tag(nil, tag_name) if CLOSE_SELF[tag_name] && last == tag_name
|
162
160
|
|
163
161
|
unary = EMPTY[tag_name] || !unary.blank?
|
164
162
|
|
165
163
|
# Section tag's are also unary
|
166
|
-
unless unary || section_tag
|
167
|
-
@stack.push(tag_name)
|
168
|
-
end
|
164
|
+
@stack.push(tag_name) unless unary || section_tag
|
169
165
|
|
170
166
|
if @handler.respond_to?(:start_tag)
|
171
167
|
attributes = {}
|
@@ -99,7 +99,7 @@ module Volt
|
|
99
99
|
@binding_number += 1
|
100
100
|
end
|
101
101
|
|
102
|
-
def add_yield(content=nil)
|
102
|
+
def add_yield(content = nil)
|
103
103
|
# Strip ( and ) from the outsides
|
104
104
|
content ||= ''
|
105
105
|
content = content.strip.gsub(/^\(/, '').gsub(/\)$/, '')
|
@@ -115,9 +115,7 @@ module Volt
|
|
115
115
|
def parent_fetcher(getter)
|
116
116
|
parent = getter.strip.gsub(/[.][^.]+$/, '')
|
117
117
|
|
118
|
-
if parent.blank? || !getter.index('.')
|
119
|
-
parent = 'self'
|
120
|
-
end
|
118
|
+
parent = 'self' if parent.blank? || !getter.index('.')
|
121
119
|
|
122
120
|
parent
|
123
121
|
end
|
@@ -71,9 +71,7 @@ module Volt
|
|
71
71
|
|
72
72
|
def add_assets(path)
|
73
73
|
asset_folder = File.join(path, 'assets')
|
74
|
-
if File.directory?(asset_folder)
|
75
|
-
@assets << [:folder, asset_folder]
|
76
|
-
end
|
74
|
+
@assets << [:folder, asset_folder] if File.directory?(asset_folder)
|
77
75
|
end
|
78
76
|
|
79
77
|
def javascript_files(opal_files)
|
@@ -14,7 +14,7 @@ module Volt
|
|
14
14
|
component_paths.components.values.flatten.uniq.each do |component_path|
|
15
15
|
routes_path = "#{component_path}/config/routes.rb"
|
16
16
|
|
17
|
-
if File.
|
17
|
+
if File.exist?(routes_path)
|
18
18
|
route_file = File.read(routes_path)
|
19
19
|
instance_eval(route_file, routes_path, 0)
|
20
20
|
end
|
@@ -21,9 +21,7 @@ module Volt
|
|
21
21
|
def self.send_message_all(skip_channel = nil, *args)
|
22
22
|
return unless defined?(@@channels)
|
23
23
|
@@channels.each do |channel|
|
24
|
-
if skip_channel && channel == skip_channel
|
25
|
-
next
|
26
|
-
end
|
24
|
+
next if skip_channel && channel == skip_channel
|
27
25
|
channel.send_message(*args)
|
28
26
|
end
|
29
27
|
end
|
@@ -2,7 +2,6 @@ require 'faye/websocket'
|
|
2
2
|
require 'volt/server/socket_connection_handler'
|
3
3
|
require 'volt/server/websocket/rack_server_adaptor'
|
4
4
|
|
5
|
-
|
6
5
|
module Volt
|
7
6
|
# Setup the dispatcher for the socket connection handler.
|
8
7
|
# SocketConnectionHandler.dispatcher = Dispatcher.new
|
@@ -39,4 +38,4 @@ module Volt
|
|
39
38
|
end
|
40
39
|
end
|
41
40
|
end
|
42
|
-
end
|
41
|
+
end
|
data/lib/volt/spec/capybara.rb
CHANGED
data/lib/volt/spec/setup.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
if RUBY_PLATFORM != 'opal'
|
2
|
-
require 'volt/volt/core'
|
3
|
-
end
|
1
|
+
require 'volt/volt/core' if RUBY_PLATFORM != 'opal'
|
4
2
|
|
5
3
|
module Volt
|
6
4
|
class << self
|
@@ -28,7 +26,7 @@ module Volt
|
|
28
26
|
|
29
27
|
unless ENV['BROWSER']
|
30
28
|
# Not running integration tests with ENV['BROWSER']
|
31
|
-
RSpec.configuration.filter_run_excluding :
|
29
|
+
RSpec.configuration.filter_run_excluding type: :feature
|
32
30
|
end
|
33
31
|
|
34
32
|
# Setup the spec collection accessors
|
@@ -44,18 +42,26 @@ module Volt
|
|
44
42
|
$page.store
|
45
43
|
end
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
def cleanup_after
|
46
|
+
Volt::DataStore.fetch.drop_database
|
47
|
+
|
48
|
+
$page.instance_variable_set('@store', nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
if RUBY_PLATFORM != 'opal'
|
52
|
+
after do
|
53
|
+
if @__store_accessed
|
54
|
+
# Clear the database after each spec where we use store
|
55
|
+
cleanup_after
|
56
|
+
end
|
57
|
+
end
|
53
58
|
|
54
|
-
|
59
|
+
# Cleanup after integration tests also.
|
60
|
+
after(:example, {type: :feature}) do
|
61
|
+
cleanup_after
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
58
|
-
|
59
65
|
end
|
60
66
|
end
|
61
67
|
end
|
@@ -59,7 +59,7 @@ module Volt
|
|
59
59
|
Volt.logger.log_dispatch(class_name, method_name, run_time, args, error)
|
60
60
|
end
|
61
61
|
|
62
|
-
|
62
|
+
# Run the promise and pass the return value/error back to the client
|
63
63
|
promise.then do |result|
|
64
64
|
channel.send_message('response', callback_id, result, nil)
|
65
65
|
|
@@ -91,4 +91,3 @@ module Volt
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
-
|
@@ -9,7 +9,7 @@ module Volt
|
|
9
9
|
# all of the items at a sub-path with #lookup_all
|
10
10
|
#
|
11
11
|
# TODO: make the lookup/create threadsafe
|
12
|
-
class GenericPoolDeleteException < StandardError
|
12
|
+
class GenericPoolDeleteException < StandardError; end
|
13
13
|
|
14
14
|
class GenericPool
|
15
15
|
attr_reader :pool
|
@@ -26,9 +26,7 @@ module Volt
|
|
26
26
|
section = @pool
|
27
27
|
|
28
28
|
# TODO: This is to work around opal issue #500
|
29
|
-
if RUBY_PLATFORM == 'opal'
|
30
|
-
args.pop if args.last.nil?
|
31
|
-
end
|
29
|
+
args.pop if args.last.nil? if RUBY_PLATFORM == 'opal'
|
32
30
|
|
33
31
|
args.each_with_index do |arg, index|
|
34
32
|
last = (args.size - 1) == index
|
@@ -96,7 +94,7 @@ module Volt
|
|
96
94
|
|
97
95
|
if args.size - 1 == index
|
98
96
|
unless section
|
99
|
-
|
97
|
+
fail GenericPoolDeleteException, "An attempt was made to delete at #{arg}, full path: #{args.inspect} in #{inspect}"
|
100
98
|
end
|
101
99
|
|
102
100
|
section.delete(arg)
|
@@ -109,14 +107,12 @@ module Volt
|
|
109
107
|
node = stack[index]
|
110
108
|
parent = stack[index - 1]
|
111
109
|
|
112
|
-
if node.size == 0
|
113
|
-
parent.delete(args[index - 1])
|
114
|
-
end
|
110
|
+
parent.delete(args[index - 1]) if node.size == 0
|
115
111
|
end
|
116
112
|
end
|
117
113
|
|
118
114
|
def inspect
|
119
|
-
"<#{self.class
|
115
|
+
"<#{self.class} #{@pool.inspect}>"
|
120
116
|
end
|
121
117
|
|
122
118
|
def print
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# more with Volt.config.filter_keys
|
4
4
|
class TaskArgumentFilterer
|
5
5
|
def self.filter(args)
|
6
|
-
|
6
|
+
new(args).run
|
7
7
|
end
|
8
8
|
|
9
9
|
def initialize(args)
|
@@ -24,9 +24,9 @@ class TaskArgumentFilterer
|
|
24
24
|
|
25
25
|
def filter_args(args)
|
26
26
|
if args.is_a?(Array)
|
27
|
-
args.map {|v| filter_args(v) }
|
27
|
+
args.map { |v| filter_args(v) }
|
28
28
|
elsif args.is_a?(Hash)
|
29
|
-
args.map do |k,v|
|
29
|
+
args.map do |k, v|
|
30
30
|
if @@filter_args.include?(k.to_sym)
|
31
31
|
# filter
|
32
32
|
[k, '[FILTERED]']
|
@@ -39,4 +39,4 @@ class TaskArgumentFilterer
|
|
39
39
|
return args
|
40
40
|
end
|
41
41
|
end
|
42
|
-
end
|
42
|
+
end
|
@@ -5,10 +5,10 @@ module Volt
|
|
5
5
|
def self.task_dispatch_message(logger, args)
|
6
6
|
msg = "task #{logger.class_name}##{logger.method_name} in #{logger.run_time}\n"
|
7
7
|
if args.size > 0
|
8
|
-
arg_str = TaskArgumentFilterer.filter(args).map
|
8
|
+
arg_str = TaskArgumentFilterer.filter(args).map(&:inspect).join(', ')
|
9
9
|
msg += "with args: #{arg_str}\n"
|
10
10
|
end
|
11
11
|
msg
|
12
12
|
end
|
13
13
|
end
|
14
|
-
end
|
14
|
+
end
|
data/lib/volt/utils/modes.rb
CHANGED
@@ -41,7 +41,7 @@ module Volt
|
|
41
41
|
|
42
42
|
# Check to see if we are in the specified mode
|
43
43
|
def in_mode?(mode_name)
|
44
|
-
|
44
|
+
defined?(Thread) && Thread.current[mode_name]
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -49,4 +49,4 @@ module Volt
|
|
49
49
|
base.send :extend, ClassMethods
|
50
50
|
end
|
51
51
|
end
|
52
|
-
end
|
52
|
+
end
|
@@ -68,9 +68,9 @@ class ReadWriteLock
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def acquire_read_lock
|
71
|
-
|
71
|
+
loop do
|
72
72
|
c = @counter.value
|
73
|
-
|
73
|
+
fail 'Too many reader threads!' if (c & MAX_READERS) == MAX_READERS
|
74
74
|
|
75
75
|
# If a writer is waiting when we first queue up, we need to wait
|
76
76
|
if c >= WAITING_WRITER
|
@@ -82,26 +82,26 @@ class ReadWriteLock
|
|
82
82
|
|
83
83
|
# after a reader has waited once, they are allowed to "barge" ahead of waiting writers
|
84
84
|
# but if a writer is *running*, the reader still needs to wait (naturally)
|
85
|
-
|
85
|
+
loop do
|
86
86
|
c = @counter.value
|
87
87
|
if c >= RUNNING_WRITER
|
88
88
|
@reader_mutex.synchronize do
|
89
89
|
@reader_q.wait(@reader_mutex) if @counter.value >= RUNNING_WRITER
|
90
90
|
end
|
91
91
|
else
|
92
|
-
return if @counter.compare_and_swap(c,c+1)
|
92
|
+
return if @counter.compare_and_swap(c, c + 1)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
else
|
96
|
-
break if @counter.compare_and_swap(c,c+1)
|
96
|
+
break if @counter.compare_and_swap(c, c + 1)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
def release_read_lock
|
102
|
-
|
102
|
+
loop do
|
103
103
|
c = @counter.value
|
104
|
-
if @counter.compare_and_swap(c,c-1)
|
104
|
+
if @counter.compare_and_swap(c, c - 1)
|
105
105
|
# If one or more writers were waiting, and we were the last reader, wake a writer up
|
106
106
|
if c >= WAITING_WRITER && (c & MAX_READERS) == 1
|
107
107
|
@writer_mutex.synchronize { @writer_q.signal }
|
@@ -112,15 +112,15 @@ class ReadWriteLock
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def acquire_write_lock
|
115
|
-
|
115
|
+
loop do
|
116
116
|
c = @counter.value
|
117
|
-
|
117
|
+
fail 'Too many writers!' if (c & MAX_WRITERS) == MAX_WRITERS
|
118
118
|
|
119
119
|
if c == 0 # no readers OR writers running
|
120
120
|
# if we successfully swap the RUNNING_WRITER bit on, then we can go ahead
|
121
|
-
break if @counter.compare_and_swap(0,RUNNING_WRITER)
|
122
|
-
elsif @counter.compare_and_swap(c,c+WAITING_WRITER)
|
123
|
-
|
121
|
+
break if @counter.compare_and_swap(0, RUNNING_WRITER)
|
122
|
+
elsif @counter.compare_and_swap(c, c + WAITING_WRITER)
|
123
|
+
loop do
|
124
124
|
# Now we have successfully incremented, so no more readers will be able to increment
|
125
125
|
# (they will wait instead)
|
126
126
|
# However, readers OR writers could decrement right here, OR another writer could increment
|
@@ -138,7 +138,7 @@ class ReadWriteLock
|
|
138
138
|
c = @counter.value
|
139
139
|
break if (c < RUNNING_WRITER) &&
|
140
140
|
((c & MAX_READERS) == 0) &&
|
141
|
-
@counter.compare_and_swap(c,c+RUNNING_WRITER-WAITING_WRITER)
|
141
|
+
@counter.compare_and_swap(c, c + RUNNING_WRITER - WAITING_WRITER)
|
142
142
|
end
|
143
143
|
break
|
144
144
|
end
|
@@ -146,13 +146,11 @@ class ReadWriteLock
|
|
146
146
|
end
|
147
147
|
|
148
148
|
def release_write_lock
|
149
|
-
|
149
|
+
loop do
|
150
150
|
c = @counter.value
|
151
|
-
if @counter.compare_and_swap(c,c-RUNNING_WRITER)
|
151
|
+
if @counter.compare_and_swap(c, c - RUNNING_WRITER)
|
152
152
|
@reader_mutex.synchronize { @reader_q.broadcast }
|
153
|
-
if (c & MAX_WRITERS) > 0 # if any writers are waiting...
|
154
|
-
@writer_mutex.synchronize { @writer_q.signal }
|
155
|
-
end
|
153
|
+
@writer_mutex.synchronize { @writer_q.signal } if (c & MAX_WRITERS) > 0 # if any writers are waiting...
|
156
154
|
break
|
157
155
|
end
|
158
156
|
end
|
@@ -161,11 +159,11 @@ class ReadWriteLock
|
|
161
159
|
def to_s
|
162
160
|
c = @counter.value
|
163
161
|
s = if c >= RUNNING_WRITER
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
162
|
+
'1 writer running, '
|
163
|
+
elsif (c & MAX_READERS) > 0
|
164
|
+
"#{c & MAX_READERS} readers running, "
|
165
|
+
else
|
166
|
+
''
|
169
167
|
end
|
170
168
|
|
171
169
|
"#<ReadWriteLock:#{object_id.to_s(16)} #{s}#{(c & MAX_WRITERS) / WAITING_WRITER} writers waiting>"
|