Add attempts at thread safety as long as different parsers are kept in

different threads.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22577 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2006-02-27 16:54:36 +00:00
parent 854cd456b0
commit aad5fbe073
2 changed files with 28 additions and 46 deletions

View file

@ -1,3 +1,13 @@
2006-02-27 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Additions/GSXML.m: Helge spotted thread safety issues with
the code controlling warnings and the external entity loader.
Changed code to modify internals of the parser context and SAX
context to set the values in there directly rather than using the
global setter mechanism (strangely recommended in the libxml2 docs),
so that all setup is made to the individual parser and should not
effect other parsers in other threads.
2006-02-27 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSString.h: Correct return type for

View file

@ -166,8 +166,8 @@ setupCache()
}
static xmlParserInputPtr
loadEntityFunction(const unsigned char *url, const unsigned char *eid,
xmlParserCtxtPtr ctxt);
loadEntityFunction(void *ctx,
const unsigned char *eid, const unsigned char *url);
@interface GSXPathObject(Private)
+ (id) _newWithNativePointer: (xmlXPathObject *)lib
@ -1609,8 +1609,6 @@ static NSMapTable *nodeNames = 0;
*/
@implementation GSXMLParser
static NSHashTable *warnings = 0;
static NSString *endMarker = @"At end of incremental parse";
+ (void) initialize
@ -1622,7 +1620,6 @@ static NSString *endMarker = @"At end of incremental parse";
beenHere = YES;
if (cacheDone == NO)
setupCache();
warnings = NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0);
}
}
@ -1864,7 +1861,6 @@ static NSString *endMarker = @"At end of incremental parse";
- (void) dealloc
{
NSHashRemove(warnings, self);
RELEASE(messages);
RELEASE(src);
RELEASE(saxHandler);
@ -1912,20 +1908,17 @@ static NSString *endMarker = @"At end of incremental parse";
*/
- (BOOL) getWarnings: (BOOL)yesno
{
BOOL old = YES;
BOOL old = (((xmlParserCtxtPtr)lib)->vctxt.warning) ? YES : NO;
if (NSHashGet(warnings, self) == nil)
if (yesno == YES)
{
old = NO;
((xmlParserCtxtPtr)lib)->vctxt.warning = xmlParserValidityWarning;
}
if (yesno == YES && old == NO)
else
{
NSHashInsert(warnings, self);
}
else if (yesno == NO && old == YES)
{
NSHashRemove(warnings, self);
((xmlParserCtxtPtr)lib)->vctxt.warning = 0;
}
return old;
}
@ -2305,6 +2298,11 @@ static NSString *endMarker = @"At end of incremental parse";
* the GSSAXHandler to use in our SAX C Functions.
*/
((xmlParserCtxtPtr)lib)->_private = saxHandler;
/*
* Set the entity loading function for this parser to be our one.
*/
((xmlParserCtxtPtr)lib)->sax->resolveEntity = loadEntityFunction;
}
return YES;
}
@ -2317,38 +2315,11 @@ static NSString *endMarker = @"At end of incremental parse";
// nil data allowed
- (void) _parseChunk: (NSData*)data
{
xmlExternalEntityLoader oldLoader;
int oldWarnings;
if (lib == NULL || ((xmlParserCtxtPtr)lib)->disableSAX != 0)
{
return; // Parsing impossible or disabled.
}
oldLoader = xmlGetExternalEntityLoader();
oldWarnings = xmlGetWarningsDefaultValue;
NS_DURING
{
if (NSHashGet(warnings, self) == nil)
{
xmlGetWarningsDefaultValue = 0;
}
else
{
xmlGetWarningsDefaultValue = 1;
}
xmlSetExternalEntityLoader((xmlExternalEntityLoader)loadEntityFunction);
xmlParseChunk(lib, [data bytes], [data length], data == nil);
xmlSetExternalEntityLoader(oldLoader);
xmlGetWarningsDefaultValue = oldWarnings;
}
NS_HANDLER
{
xmlSetExternalEntityLoader(oldLoader);
xmlGetWarningsDefaultValue = oldWarnings;
[localException raise];
}
NS_ENDHANDLER
xmlParseChunk(lib, [data bytes], [data length], data == nil);
}
@end
@ -2436,8 +2407,8 @@ static NSString *endMarker = @"At end of incremental parse";
#define HANDLER ((GSSAXHandler*)(((xmlParserCtxtPtr)ctx)->_private))
static xmlParserInputPtr
loadEntityFunction(const unsigned char *url, const unsigned char *eid,
xmlParserCtxtPtr ctx)
loadEntityFunction(void *ctx,
const unsigned char *eid, const unsigned char *url)
{
extern xmlParserInputPtr xmlNewInputFromFile();
NSString *file;
@ -2596,7 +2567,7 @@ loadEntityFunction(const unsigned char *url, const unsigned char *eid,
#else
path = [file fileSystemRepresentation];
#endif
ret = xmlNewInputFromFile(ctx, path);
ret = xmlNewInputFromFile((xmlParserCtxtPtr)ctx, path);
}
else
{
@ -2605,6 +2576,7 @@ loadEntityFunction(const unsigned char *url, const unsigned char *eid,
return ret;
}
#define TREEFUN(NAME,ARGS) ((HANDLER->isHtmlHandler == YES) ? (*(htmlDefaultSAXHandler.NAME))ARGS : (*(xmlDefaultSAXHandler.NAME))ARGS)
#define START(SELNAME, RET, ARGS) \
static SEL sel; \