volt 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- 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>"
|