Skip to content

File tree

1 file changed

+59
-17
lines changed

1 file changed

+59
-17
lines changed
 

‎logstash-core/lib/logstash/config/config_ast.rb

+59-17
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,60 @@
77
module LogStash; module Config; module AST
88
PROCESS_ESCAPE_SEQUENCES = :process_escape_sequences
99

10-
def self.deferred_conditionals=(val)
11-
@deferred_conditionals = val
12-
end
10+
class << self
11+
# @api private
12+
MUTEX = Mutex.new
1313

14-
def self.deferred_conditionals
15-
@deferred_conditionals
16-
end
14+
# Executes the given block with exclusive access to the AST global variables
15+
#
16+
# @yieldreturn [Object]: the object that is returned from the block is returned by this method
17+
#
18+
# @return [Object]
19+
def exclusive
20+
MUTEX.synchronize { yield }
21+
end
1722

18-
def self.deferred_conditionals_index
19-
@deferred_conditionals_index
20-
end
23+
def deferred_conditionals=(val)
24+
ensure_exclusive!
25+
@deferred_conditionals = val
26+
end
2127

22-
def self.deferred_conditionals_index=(val)
23-
@deferred_conditionals_index = val
24-
end
28+
def deferred_conditionals
29+
ensure_exclusive!
30+
@deferred_conditionals
31+
end
2532

26-
def self.plugin_instance_index
27-
@plugin_instance_index
28-
end
33+
def deferred_conditionals_index
34+
ensure_exclusive!
35+
@deferred_conditionals_index
36+
end
37+
38+
def deferred_conditionals_index=(val)
39+
ensure_exclusive!
40+
@deferred_conditionals_index = val
41+
end
2942

30-
def self.plugin_instance_index=(val)
31-
@plugin_instance_index = val
43+
def plugin_instance_index
44+
ensure_exclusive!
45+
@plugin_instance_index
46+
end
47+
48+
def plugin_instance_index=(val)
49+
ensure_exclusive!
50+
@plugin_instance_index = val
51+
end
52+
53+
private
54+
55+
# Raises a descriptive error if the thread in which it is invoked does
56+
# not have exclusive access.
57+
#
58+
# @raise [RuntimeError]
59+
def ensure_exclusive!
60+
return if MUTEX.owned?
61+
62+
raise "Illegal access without exclusive lock at `#{caller[1]}`"
63+
end
3264
end
3365

3466
class Node < Treetop::Runtime::SyntaxNode
@@ -46,6 +78,15 @@ def process_escape_sequences=(val)
4678

4779

4880
def compile
81+
LogStash::Config::AST.exclusive { do_compile }
82+
end
83+
84+
private
85+
86+
# NON-threadsafe method compiles an AST into executable Ruby code.
87+
# @see Config#compile, which is a threadsafe wrapper around this method.
88+
# @api private
89+
def do_compile
4990
LogStash::Config::AST.deferred_conditionals = []
5091
LogStash::Config::AST.deferred_conditionals_index = 0
5192
LogStash::Config::AST.plugin_instance_index = 0
@@ -491,6 +532,7 @@ class SelectorElement < Node; end
491532
end; end; end
492533

493534

535+
494536
# Monkeypatch Treetop::Runtime::SyntaxNode's inspect method to skip
495537
# any Whitespace or SyntaxNodes with no children.
496538
class Treetop::Runtime::SyntaxNode

0 commit comments

Comments
 (0)
Please sign in to comment.