From 9a81b9838f7a386e38111ea4d2354481241562b9 Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Wed, 10 Apr 2013 19:08:14 +0200 Subject: [PATCH] Make expression parser goroutine-safe. See https://github.com/prometheus/prometheus/issues/127 --- rules/load.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/rules/load.go b/rules/load.go index 1b73683be..36a08e1d6 100644 --- a/rules/load.go +++ b/rules/load.go @@ -20,14 +20,16 @@ import ( "io" "os" "strings" + "sync" ) -// NOTE: This parser is non-reentrant due to its dependence on global state. - // GoLex sadly needs these global variables for storing temporary token/parsing information. -var yylval *yySymType // For storing extra token information, like the contents of a string. -var yyline int // Line number within the current file or buffer. -var yypos int // Character position within the current line. +var ( + yylval *yySymType // For storing extra token information, like the contents of a string. + yyline int // Line number within the current file or buffer. + yypos int // Character position within the current line. + parseMutex sync.Mutex // Mutex protecting the parsing-related global state defined above. +) type RulesLexer struct { errors []string // Errors encountered during parsing. @@ -58,6 +60,9 @@ func (lexer *RulesLexer) Error(errorStr string) { } func LoadFromReader(rulesReader io.Reader, singleExpr bool) (interface{}, error) { + parseMutex.Lock() + defer parseMutex.Unlock() + yyin = rulesReader yypos = 1 yyline = 1