From 716c82130c0cfa82a2536b8be5ce3405f09acca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 13 Sep 2013 08:44:46 +0000 Subject: [PATCH] Making the ANTLR parser thread-safe git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@17223 f25d12d1-65f4-0310-ae8a-bbce733d8d8e --- Parser/Modelica.g | 14 +++------- Parser/ModelicaParserCommon.h | 32 ++++++++++++++++------ Parser/parse.c | 50 +++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/Parser/Modelica.g b/Parser/Modelica.g index 4742d5c5c00..cd1c6ae3fe4 100644 --- a/Parser/Modelica.g +++ b/Parser/Modelica.g @@ -95,27 +95,19 @@ goto rule ## func ## Ex; }} #endif #define token_to_scon(tok) mk_scon((char*)tok->getText(tok)->chars) #define NYI(void) fprintf(stderr, "NYI \%s \%s:\%d\n", __FUNCTION__, __FILE__, __LINE__); exit(1); - #define PARSER_INFO(start) ((void*) Absyn__INFO(ModelicaParser_filename_RML, mk_bcon(isReadOnly), mk_icon(start->line), mk_icon(start->line == 1 ? start->charPosition+2 : start->charPosition+1), mk_icon(LT(1)->line), mk_icon(LT(1)->charPosition+1), Absyn__TIMESTAMP(mk_rcon(0),mk_rcon(0)))) + + #define PARSER_INFO(start) ((void*) Absyn__INFO(ModelicaParser_filename_RML, mk_bcon(ModelicaParser_readonly), mk_icon(start->line), mk_icon(start->line == 1 ? start->charPosition+2 : start->charPosition+1), mk_icon(LT(1)->line), mk_icon(LT(1)->charPosition+1), Absyn__TIMESTAMP(mk_rcon(0),mk_rcon(0)))) typedef struct fileinfo_struct { int line1; int line2; int offset1; int offset2; } fileinfo; - extern int isReadOnly; - extern long omc_first_comment; } @members { - void* ModelicaParser_filename_RML = 0; - const char* ModelicaParser_filename_C = 0; - const char* ModelicaParser_filename_C_testsuiteFriendly = 0; - int ModelicaParser_readonly = 0; - int ModelicaParser_flags = 0; - int ModelicaParser_langStd = 0; - int isReadOnly; - long omc_first_comment; + parser_members members; void* mk_box_eat_all(int ix, ...) {return NULL;} double getCurrentTime(void) { time_t t; diff --git a/Parser/ModelicaParserCommon.h b/Parser/ModelicaParserCommon.h index 5546e4d11c0..f720b12b609 100644 --- a/Parser/ModelicaParserCommon.h +++ b/Parser/ModelicaParserCommon.h @@ -37,15 +37,31 @@ extern "C" { #endif #include "systemimpl.h" +#include -extern int ModelicaParser_flags; -extern int ModelicaParser_readonly; -extern void *ModelicaParser_filename_RML; -extern const char *ModelicaParser_filename_C; -extern const char *ModelicaParser_filename_C_testsuiteFriendly; -extern int ModelicaParser_lexerError; -extern int ModelicaParser_langStd; -extern const char *ModelicaParser_encoding; +extern pthread_key_t modelicaParserKey; + +#define omc_first_comment ((parser_members*)pthread_getspecific(modelicaParserKey))->first_comment +#define ModelicaParser_filename_RML ((parser_members*)pthread_getspecific(modelicaParserKey))->filename_RML +#define ModelicaParser_filename_C ((parser_members*)pthread_getspecific(modelicaParserKey))->filename_C +#define ModelicaParser_filename_C_testsuiteFriendly ((parser_members*)pthread_getspecific(modelicaParserKey))->filename_C_testsuiteFriendly +#define ModelicaParser_readonly ((parser_members*)pthread_getspecific(modelicaParserKey))->readonly +#define ModelicaParser_flags ((parser_members*)pthread_getspecific(modelicaParserKey))->flags +#define ModelicaParser_langStd ((parser_members*)pthread_getspecific(modelicaParserKey))->langStd +#define ModelicaParser_lexerError ((parser_members*)pthread_getspecific(modelicaParserKey))->lexerError +#define ModelicaParser_encoding ((parser_members*)pthread_getspecific(modelicaParserKey))->encoding + +typedef struct antlr_members_struct { + int lexerError; + const char *encoding; + long first_comment; + void* filename_RML; + const char* filename_C; + const char* filename_C_testsuiteFriendly; + int readonly; + int flags; + int langStd; +} parser_members; #define PARSE_MODELICA 0 #define PARSE_FLAT 1<<0 diff --git a/Parser/parse.c b/Parser/parse.c index 188f525fc57..bda163bed69 100644 --- a/Parser/parse.c +++ b/Parser/parse.c @@ -45,9 +45,13 @@ #include "runtime/errorext.h" #include "runtime/systemimpl.h" -static long unsigned int szMemoryUsed = 0; -int ModelicaParser_lexerError = 0; -const char *ModelicaParser_encoding = 0; +pthread_once_t once_create_key = PTHREAD_ONCE_INIT; +pthread_key_t modelicaParserKey; + +static void make_key() +{ + pthread_key_create(&modelicaParserKey,NULL); +} static void lexNoRecover(pANTLR3_LEXER lexer) { @@ -360,20 +364,23 @@ static void* parseString(const char* data, const char* interactiveFilename, int pANTLR3_UINT8 fName; pANTLR3_INPUT_STREAM input; + parser_members members; + pthread_once(&once_create_key,make_key); + pthread_setspecific(modelicaParserKey,&members); - ModelicaParser_encoding = "UTF-8"; - ModelicaParser_filename_C = interactiveFilename; - ModelicaParser_filename_C_testsuiteFriendly = interactiveFilename; - ModelicaParser_flags = flags; - isReadOnly = 0; - omc_first_comment = 0; + members.encoding = "UTF-8"; + members.filename_C = interactiveFilename; + members.filename_C_testsuiteFriendly = interactiveFilename; + members.flags = flags; + members.readonly = 0; + members.first_comment = 0; - if (debug) { fprintf(stderr, "Starting parsing of file: %s\n", ModelicaParser_filename_C); fflush(stderr); } + if (debug) { fprintf(stderr, "Starting parsing of file: %s\n", members.filename_C); fflush(stderr); } - fName = (pANTLR3_UINT8)ModelicaParser_filename_C; + fName = (pANTLR3_UINT8)members.filename_C; input = antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8)data,strlen(data),fName); if ( input == NULL ) { - fprintf(stderr, "Unable to open file %s\n", ModelicaParser_filename_C); fflush(stderr); + fprintf(stderr, "Unable to open file %s\n", members.filename_C); fflush(stderr); return NULL; } return parseStream(input, langStd, runningTestsuite); @@ -388,12 +395,15 @@ static void* parseFile(const char* fileName, const char* infoName, int flags, co pANTLR3_UINT8 fName; pANTLR3_INPUT_STREAM input; int len = 0; - - ModelicaParser_encoding = encoding; - ModelicaParser_filename_C = fileName; - ModelicaParser_filename_C_testsuiteFriendly = infoName; - ModelicaParser_flags = flags; - isReadOnly = !SystemImpl__regularFileWritable(ModelicaParser_filename_C); + parser_members members; + pthread_once(&once_create_key,make_key); + pthread_setspecific(modelicaParserKey,&members); + + members.encoding = encoding; + members.filename_C = fileName; + members.filename_C_testsuiteFriendly = infoName; + members.flags = flags; + members.readonly = !SystemImpl__regularFileWritable(fileName); omc_first_comment = 0; if (debug) { fprintf(stderr, "Starting parsing of file: %s\n", fileName); fflush(stderr); } @@ -407,8 +417,8 @@ static void* parseFile(const char* fileName, const char* infoName, int flags, co * So we pass an empty string instead :) */ struct stat st; - stat(ModelicaParser_filename_C, &st); - if (0 == st.st_size) return parseString("",ModelicaParser_filename_C,ModelicaParser_flags, langStd, runningTestsuite); + stat(members.filename_C, &st); + if (0 == st.st_size) return parseString("",members.filename_C,ModelicaParser_flags, langStd, runningTestsuite); fName = (pANTLR3_UINT8)fileName; input = antlr3AsciiFileStreamNew(fName);