7
7
module LogStash ; module Config ; module AST
8
8
PROCESS_ESCAPE_SEQUENCES = :process_escape_sequences
9
9
10
- def self . deferred_conditionals = ( val )
11
- @deferred_conditionals = val
12
- end
10
+ class << self
11
+ # @api private
12
+ MUTEX = Mutex . new
13
13
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
17
22
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
21
27
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
25
32
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
29
42
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
32
64
end
33
65
34
66
class Node < Treetop ::Runtime ::SyntaxNode
@@ -46,6 +78,15 @@ def process_escape_sequences=(val)
46
78
47
79
48
80
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
49
90
LogStash ::Config ::AST . deferred_conditionals = [ ]
50
91
LogStash ::Config ::AST . deferred_conditionals_index = 0
51
92
LogStash ::Config ::AST . plugin_instance_index = 0
@@ -491,6 +532,7 @@ class SelectorElement < Node; end
491
532
end ; end ; end
492
533
493
534
535
+
494
536
# Monkeypatch Treetop::Runtime::SyntaxNode's inspect method to skip
495
537
# any Whitespace or SyntaxNodes with no children.
496
538
class Treetop ::Runtime ::SyntaxNode
0 commit comments