Skip to content

Commit

Permalink
Making the ANTLR parser thread-safe
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@17223 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Sep 13, 2013
1 parent e6af23d commit 716c821
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 39 deletions.
14 changes: 3 additions & 11 deletions Parser/Modelica.g
Expand Up @@ -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;
Expand Down
32 changes: 24 additions & 8 deletions Parser/ModelicaParserCommon.h
Expand Up @@ -37,15 +37,31 @@ extern "C" {
#endif

#include "systemimpl.h"
#include <pthread.h>

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
Expand Down
50 changes: 30 additions & 20 deletions Parser/parse.c
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand All @@ -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); }
Expand All @@ -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);
Expand Down

0 comments on commit 716c821

Please sign in to comment.