libs-gsweb/GSWeb.framework/GSWDefaultAdaptor.m
Manuel Guesdon bd47f4ea4a 2001-03-11 Manuel Guesdon <mguesdon@orange-concept.com>
* GSWeb.framework/GSWWOCompatibility.h/.m: added
        * GSWeb.framework/GNUmakefile: added GSWWOCompatibility.h/.m
        * GSWeb.framework/GSWApplication.h/m: added WOApplicationMain, handle WO/GSWeb names
        * GSWeb.framework/GSWContext.m: handle WO/GSWeb names, added traces
        * GSWeb.framework/GSWConstants.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWDynamicURLString.m: handle WO/GSWeb names
        * GSWeb.framework/GSWProjectBundle.m/.h: handle WO/GSWeb names, suppress warnings
        * GSWeb.framework/GSWSession.m: handle WO/GSWeb names
        * GSWeb.framework/GSWRequest.m: handle WO/GSWeb names
        * GSWeb.framework/GSWTemplateParser.m: handle WO/GSWeb names,
                added tag counts to help errors hunt
        * GSWeb.framework/GSWBundle.m: handle WO/GSWeb names, added traces
        * GSWeb.framework/GSWResourceManager.m: handle WO/GSWeb names
        * GSWeb.framework/GSWURLValuedElementData.m: handle WO/GSWeb names
        * GSWeb.framework/GSWComponentRequestHandler.m: handle WO/GSWeb names
        * GSWeb.framework/GSWDirectAction.m: handle WO/GSWeb names
        * GSWeb.framework/GSWForm.m/.h: handle WO/GSWeb names
        * GSWeb.framework/GSWHyperlink.m/.h: handle WO/GSWeb names
        * GSWeb.framework/GSWResourceRequestHandler.m: handle WO/GSWeb names
        * GSWeb.framework/GSWDirectActionRequestHandler.m: handle WO/GSWeb names
        * GSWeb.framework/GSWActiveImage.m/.h: handle WO/GSWeb names
        * GSWeb.framework/GSWBindingNameAssociation.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWBrowser.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWComponent.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWHTMLURLValuedElement.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWImageButton.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWInput.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWPopUpButton.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWString.h/.m: handle WO/GSWeb names
        * GSWeb.framework/GSWAssociation.m: handle WO/GSWeb names
        * GSWeb.framework/GSWCheckBox.m: handle WO/GSWeb names
        * GSWeb.framework/GSWCheckBoxList.m: handle WO/GSWeb names
        * GSWeb.framework/GSWComponentDefinition.m: handle WO/GSWeb names
        * GSWeb.framework/GSWRadioButton.m: handle WO/GSWeb names
        * GSWeb.framework/GSWRadioButtonList.m: handle WO/GSWeb names
        * GSWeb.framework/GSWText.m: handle WO/GSWeb names
        * GSWeb.framework/GSWTextField.m: handle WO/GSWeb names
        * GSWeb.framework/GSWDeployedBundle.m: warnings
        * GSWeb.framework/GSWeb.h: added include GSWeb/GSWSessionTimeOut.h, GSWWOCompatibility.h
        * GSWeb.framework/GSWAdaptor.m: traces
        * GSWeb.framework/GSWDefaultAdaptor.m: handle WO/GSWeb names, added traces
        * GSWeb.framework/GSWDefaultAdaptorThread.m/.h: handle WO/GSWeb names
        * GSWeb.framework/NSNonBlockingFileHandle.m: added traces
        * GSWeb.framework/GSWTemplateParserANTLR.m: handle WO/GSWeb names
        * GSWeb.framework/GSWTemplateParserXML.m: handle WO/GSWeb names
                added tag count to help errors hunt
                remove "Tag gsweb invalid" message
                handle unicode strings in node content traces
                remove html and body tags if they are not present in the template
        * GSWeb.framework/GSWTemplateParseXML.h: added ivar _isHTMLTag, _isBodyTag
        * GSWeb.framework/GSWSessionTimeOutManager.m: dealloc sessionOrderedTimeOuts instead
                of deallocating 2 times sessionTimeOuts
        * GSWExtensions.framework/French.lproj/GSWSessionRestorationErrorPage.gswc/GSWSessionRestorationErrorPage.html:
                tag mismatch, Encode french characters
        * GSWExtensions.framework/GSWSessionRestorationErrorPage.gswc/GSWSessionRestorationErrorPage.html:
                tag mismatch
        * GSWHTMLBareString.m: handle unicode strings in description
        * GSWExtensions.framework/French.lproj/GSWExceptionPage.gswc/GSWExceptionPage.html:
                Encode french characters, Tag Mismatch
        * GSWExtensions.framework/French.lproj/GSWPageRestorationErrorPage.gswc/GSWPageRestorationErrorPage.html:
                Encode french characters
        * GSWExtensions.framework/French.lproj/GSWSessionCreationErrorPage.gswc/GSWSessionCreationErrorPage.html:
                Encode french characters
        * GSWExtensions.framework/GSWExceptionPage.gswc/GSWExceptionPage.html:
                Tag Mismatch
        * GSWExtensions.framework/GSWExceptionPage.gswc/GSWExceptionPage.gswd:
                added convertHTMLEntities for strings
        * GSWeb.framework/GSWRepetition.m: added traces, fix "count" property bug, standardize ivars
        * GSWeb.framework/NSObject+IVarAccess+PerformSel.m: added traces, handle underscored ivars search


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@9332 72102866-910b-0410-8b05-ffd578937521
2001-03-11 17:15:44 +00:00

522 lines
14 KiB
Objective-C

/* GSWDefaultAdaptor.m - GSWeb: Class GSWDefaultAdaptor
Copyright (C) 1999 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com>
Date: Jan 1999
This file is part of the GNUstep Web Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
static char rcsId[] = "$Id$";
#include <GSWeb/GSWeb.h>
//====================================================================
@implementation GSWDefaultAdaptor
-(id)initWithName:(NSString*)name_
arguments:(NSDictionary*)arguments_
{
NSDebugMLog(@"Init");
if ((self=[super initWithName:name_
arguments:arguments_]))
{
fileHandle=nil;
threads=[NSMutableArray new];
waitingThreads=[NSMutableArray new];
selfLock=[NSLock new];
port=[[arguments_ objectForKey:GSWOPT_Port[GSWebNamingConv]] intValue];
NSDebugMLLog(@"info",@"port=%d",port);
ASSIGN(host,[arguments_ objectForKey:GSWOPT_Host[GSWebNamingConv]]);
// [self setInstance:_instance];
queueSize=[[arguments_ objectForKey:GSWOPT_ListenQueueSize[GSWebNamingConv]] intValue];
workerThreadCount=[[arguments_ objectForKey:GSWOPT_WorkerThreadCount[GSWebNamingConv]] intValue];
isMultiThreadEnabled=[[arguments_ objectForKey:GSWOPT_MultiThreadEnabled] boolValue];
};
LOGObjectFnStop();
return self;
};
//--------------------------------------------------------------------
-(void)dealloc
{
GSWLogC("Dealloc GSWDefaultAdaptor");
//TODO? DESTROY(listenPortObject);
GSWLogC("Dealloc GSWDefaultAdaptor: host");
DESTROY(host);
GSWLogC("Dealloc GSWDefaultAdaptor: fileHandle");
DESTROY(fileHandle);
GSWLogC("Dealloc GSWDefaultAdaptor: threads");
DESTROY(threads);
GSWLogC("Dealloc GSWDefaultAdaptor: waitingThreads");
DESTROY(waitingThreads);
GSWLogC("Dealloc GSWDefaultAdaptor: selfLock");
DESTROY(selfLock);
GSWLogC("Dealloc GSWDefaultAdaptor Super");
[super dealloc];
GSWLogC("End Dealloc GSWDefaultAdaptor");
};
//--------------------------------------------------------------------
-(void)registerForEvents
{
NSAssert(!fileHandle,@"fileHandle already exists");
NSDebugMLLog(@"info",@"registerForEvents port=%d",port);
NSDebugMLLog(@"info",@"registerForEvents host=%@",host);
if (!host)
{
ASSIGN(host,[[NSHost currentHost] name]);
};
fileHandle=[[NSFileHandle fileHandleAsServerAtAddress:host
service:[NSString stringWithFormat:@"%d",port]
protocol:@"tcp"] retain];
NSDebugMLLog(@"info",@"fileHandle=%p\n",(void*)fileHandle);
[[NSNotificationCenter defaultCenter] addObserver:self
selector: @selector(announceNewConnection:)
name: NSFileHandleConnectionAcceptedNotification
object:fileHandle];
/* [NotificationDispatcher addObserver:self
selector: @selector(announceNewConnection:)
name: NSFileHandleConnectionAcceptedNotification
object:fileHandle];
*/
[fileHandle acceptConnectionInBackgroundAndNotify];
[GSWApplication statusLogWithFormat:@"Waiting for connections."];
};
//--------------------------------------------------------------------
-(void)unregisterForEvents
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name: NSFileHandleConnectionAcceptedNotification
object:fileHandle];
/* [NotificationDispatcher removeObserver:self
name: NSFileHandleConnectionAcceptedNotification
object:fileHandle];
*/
DESTROY(fileHandle);
};
//--------------------------------------------------------------------
-(void)logWithFormat:(NSString*)_format,...
{
LOGObjectFnNotImplemented(); //TODOFN
};
//--------------------------------------------------------------------
+(void)logWithFormat:(NSString*)_format,...
{
LOGClassFnNotImplemented(); //TODOFN
};
//--------------------------------------------------------------------
-(void)runOnce
{
//call doesBusyRunOnce
LOGObjectFnNotImplemented(); //TODOFN
};
//--------------------------------------------------------------------
-(BOOL)doesBusyRunOnce
{
//call _runOnce
LOGObjectFnNotImplemented(); //TODOFN
return NO;
};
//--------------------------------------------------------------------
-(BOOL)dispatchesRequestsConcurrently
{
return YES;
};
//--------------------------------------------------------------------
-(int)port
{
return port;
};
//--------------------------------------------------------------------
-(NSString*)host
{
return host;
};
//--------------------------------------------------------------------
-(void)setWorkerThreadCount:(id)workerThreadCount_
{
if ([self tryLock])
{
NS_DURING
{
workerThreadCount=[workerThreadCount_ intValue];
if (workerThreadCount<1)
workerThreadCount=1;
}
NS_HANDLER
{
LOGException(@"%@ (%@)",
localException,
[localException reason]);
}
NS_ENDHANDLER;
[self unlock];
}
else
{
//TODO
};
};
//--------------------------------------------------------------------
-(id)workerThreadCount
{
return [NSNumber numberWithInt:workerThreadCount];
};
//--------------------------------------------------------------------
-(BOOL)isMultiThreadEnabled
{
return isMultiThreadEnabled;
};
//--------------------------------------------------------------------
-(void)setListenQueueSize:(id)listenQueueSize_
{
if ([self tryLock])
{
NS_DURING
{
queueSize=[listenQueueSize_ intValue];
if (queueSize<1)
queueSize=1;
}
NS_HANDLER
{
LOGException(@"%@ (%@)",
localException,
[localException reason]);
}
NS_ENDHANDLER;
[self unlock];
}
else
{
//TODO
};
};
//--------------------------------------------------------------------
//NDFN
-(id)announceNewConnection:(id)notification
{
GSWDefaultAdaptorThread* _newThread=nil;
NSFileHandle* _listenHandle=nil;
NSFileHandle* inStream = nil;
NSCalendarDate* requestDate=nil;
NSString* requestDateString=nil;
LOGObjectFnStart();
_listenHandle=[notification object];
requestDate=[NSCalendarDate calendarDate];
requestDateString=[NSString stringWithFormat:@"New Request %@",requestDate];
[GSWApplication statusLogWithFormat:@"%@",requestDateString];
NSDebugMLLog(@"info",@"_listenHandle=%p",(void*)_listenHandle);
inStream = [[notification userInfo]objectForKey:@"NSFileHandleNotificationFileHandleItem"];
NSDebugMLLog(@"info",@"announceNewConnection notification=%@\n",notification);
NSDebugMLLog(@"info",@"notification userInfo=%@\n",[notification userInfo]);
if ([waitingThreads count]>=queueSize)
{
DESTROY(_newThread);
}
else
{
//release done after lock !
_newThread=[[GSWDefaultAdaptorThread alloc] initWithApp:[GSWApplication application]
withAdaptor:self
withStream:inStream];
if (_newThread)
{
NSDebugMLog0(@"_newThread !");
if ([self tryLock])
{
NSDebugMLog0(@"locked !");
NS_DURING
{
NSDebugMLLog(@"low",
@"[waitingThreads count]=%d [threads count]=%d",
[waitingThreads count],
[threads count]);
if ([threads count]<workerThreadCount)
{
[threads addObject:_newThread];
if (isMultiThreadEnabled)
{
requestDate=[NSCalendarDate calendarDate];
requestDateString=[NSString stringWithFormat:@"Lauch Thread (Multi) %@",requestDate];
[GSWApplication statusLogWithFormat:@"%@",requestDateString];
NSDebugMLLog(@"info",
@"Lauch Thread (Multi) %p",
(void*)_newThread);
[NSThread detachNewThreadSelector:@selector(run:)
toTarget:_newThread
withObject:nil];
DESTROY(_newThread);
}
else
{
//Runit after
/*
[GSWApplication statusLogWithFormat:@"Lauch Thread (Mono)"];
NSDebugMLLog(@"info",
@"Lauch Thread (Mono) %p",
(void*)_newThread);
[_newThread run:nil];
*/
};
}
else
{
[GSWApplication statusLogWithFormat:@"Set Thread to wait"];
NSDebugMLLog(@"info",
@"Set Thread to wait %p",
(void*)_newThread);
[waitingThreads addObject:_newThread];
DESTROY(_newThread);
};
}
NS_HANDLER
{
LOGException(@"%@ (%@)",
localException,[localException reason]);
//TODO
[self unlock];
[localException raise];
}
NS_ENDHANDLER;
[self unlock];
}
else
{
DESTROY(_newThread);
};
};
if (!isMultiThreadEnabled && _newThread)
{
requestDate=[NSCalendarDate calendarDate];
requestDateString=[NSString stringWithFormat:@"Lauch Thread (Mono) %@",requestDate];
[GSWApplication statusLogWithFormat:@"%@",requestDateString];
NSDebugMLLog(@"info",
@"%@ %p",
requestDateString,
(void*)_newThread);
[_newThread run:nil];
DESTROY(_newThread);
requestDate=[NSCalendarDate calendarDate];
requestDateString=[NSString stringWithFormat:@"Stop Thread (Mono) %@",requestDate];
[GSWApplication statusLogWithFormat:@"%@",requestDateString];
NSDebugMLLog0(@"info",
requestDateString);
};
if ([self tryLock])
{
BOOL accept=[waitingThreads count]<queueSize;
NS_DURING
{
if (accept)
[_listenHandle acceptConnectionInBackgroundAndNotify];
}
NS_HANDLER
{
LOGException(@"%@ (%@)",
localException,[localException reason]);
//TODO
blocked=!accept;
[self unlock];
[localException raise];
}
NS_ENDHANDLER;
blocked=!accept;
[self unlock];
};
};
LOGObjectFnStop();
return self;
};
//--------------------------------------------------------------------
-(void)adaptorThreadExited:(GSWDefaultAdaptorThread*)adaptorThread_
{
LOGObjectFnStart();
if ([self tryLock])
{
NSAutoreleasePool* pool=nil;
#ifndef NDEBUG
pool=[NSAutoreleasePool new];
NSDebugMLLog(@"low",
@"remove thread %p",
(void*)adaptorThread_);
DESTROY(pool);
#endif
NS_DURING
{
[threads removeObject:adaptorThread_];
}
NS_HANDLER
{
pool=[NSAutoreleasePool new];
LOGException(@"%@ (%@)",
localException,
[localException reason]);
DESTROY(pool);
//TODO
// [self unlock];
// [localException raise];
}
NS_ENDHANDLER;
#ifndef NDEBUG
pool=[NSAutoreleasePool new];
NSDebugMLLog(@"low",
@"[waitingThreads count]=%d [threads count]=%d",
[waitingThreads count],
[threads count]);
DESTROY(pool);
#endif
if ([threads count]==0)
{
BOOL _isApplicationRequestHandlingLocked=[[GSWApplication application] isRequestHandlingLocked];
if (_isApplicationRequestHandlingLocked)
{
pool=[NSAutoreleasePool new];
LOGSeriousError0(@"Application RequestHandling is LOCKED !!!");
[[GSWApplication application] terminate];
DESTROY(pool);
};
};
if ([waitingThreads count]>0 && [threads count]<workerThreadCount)
{
NS_DURING
{
GSWDefaultAdaptorThread* _thread=[waitingThreads objectAtIndex:0];
[threads addObject:_thread];
[waitingThreads removeObjectAtIndex:0];
#ifndef NDEBUG
pool=[NSAutoreleasePool new];
[GSWApplication statusLogWithFormat:@"Lauch waiting Thread"];
NSDebugMLLog(@"info",
@"Lauch waiting Thread %p",
(void*)_thread);
DESTROY(pool);
#endif
if (isMultiThreadEnabled)
[NSThread detachNewThreadSelector:@selector(run:)
toTarget:_thread
withObject:nil];
else
[_thread run:nil];
}
NS_HANDLER
{
pool=[NSAutoreleasePool new];
LOGException(@"%@ (%@)",
localException,
[localException reason]);
DESTROY(pool);
//TODO
// [self unlock];
// [localException raise];
}
NS_ENDHANDLER;
};
NS_DURING
{
BOOL accept=[waitingThreads count]<queueSize;
if (blocked && accept)
{
[fileHandle acceptConnectionInBackgroundAndNotify];
blocked=NO;
};
}
NS_HANDLER
{
pool=[NSAutoreleasePool new];
LOGException(@"%@ (%@)",
localException,
[localException reason]);
DESTROY(pool);
//TODO
// [self unlock];
// [localException raise];
}
NS_ENDHANDLER;
[self unlock];
};
LOGObjectFnStop();
};
//--------------------------------------------------------------------
//NDFN
-(id)announceBrokenConnection:(id)notification
{
LOGObjectFnNotImplemented(); //TODOFN
// [self shutDownConnectionWithSocket:[in_port _port_socket]];
return self;
};
//--------------------------------------------------------------------
// lock
-(BOOL)tryLock
{
BOOL _locked=NO;
LOGObjectFnStart();
_locked=[selfLock tmptryLockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:90]];
LOGObjectFnStop();
return _locked;
};
//--------------------------------------------------------------------
// unlock
-(void)unlock
{
LOGObjectFnStart();
[selfLock tmpunlock];
LOGObjectFnStop();
};
@end
//====================================================================
@implementation GSWDefaultAdaptor (GSWDefaultAdaptorA)
-(void)stop
{
LOGObjectFnNotImplemented(); //TODOFN
};
-(void)run
{
LOGObjectFnNotImplemented(); //TODOFN
};
-(void)_runOnce
{
LOGObjectFnNotImplemented(); //TODOFN
};
@end