/* GSWDefaultAdaptor.m - GSWeb: Class GSWDefaultAdaptor Copyright (C) 1999 Free Software Foundation, Inc. Written by: Manuel Guesdon 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 //==================================================================== @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]0 && [threads count]