mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 08:41:03 +00:00
Merged in 'dawn' CVS branch
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3827 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2c66a6581f
commit
fc772ee2e5
26 changed files with 1090 additions and 607 deletions
|
@ -58,19 +58,22 @@ after-install::
|
|||
$(INSTALL_DATA) $(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS)/mframe.h \
|
||||
$(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS)
|
||||
if [ "$(INSTALL_ROOT_DIR)" = "" ]; then \
|
||||
if [ "`whoami`" != root ]; then \
|
||||
echo "WARNING: Please add the following lines yourself"; \
|
||||
fi; \
|
||||
services=/etc/services; \
|
||||
else \
|
||||
mkdir -p $(INSTALL_ROOT_DIR)/etc; \
|
||||
services=$(INSTALL_ROOT_DIR)/etc/services.add; \
|
||||
echo "GNUstep addons for /etc/services written to $$services"; \
|
||||
fi; \
|
||||
if [ "`fgrep gdomap $$services 2>/dev/null`" = "" ]; then \
|
||||
if [ "`whoami`" != root ]; then \
|
||||
echo "WARNING: Please add the following lines to $$services"; \
|
||||
echo "gdomap 538/tcp # GNUstep distrib objects"; \
|
||||
echo "gdomap 538/udp # GNUstep distrib objects"; \
|
||||
else \
|
||||
if [ "`fgrep gdomap $$services 2>/dev/null`" = "" ]; then \
|
||||
echo "GNUstep addons for /etc/services written to $$services"; \
|
||||
set -x; \
|
||||
echo "gdomap 538/tcp # GNUstep distrib objects" >> $$services; \
|
||||
echo "gdomap 538/udp # GNUstep distrib objects" >> $$services; \
|
||||
fi; \
|
||||
fi
|
||||
|
||||
# Things to do before uninstalling
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
#include <Foundation/NSThread.h>
|
||||
#include <Foundation/NSPort.h>
|
||||
#include <Foundation/NSPortMessage.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
|
||||
NSString* NSConnectionReplyMode = @"NSConnectionReplyMode";
|
||||
|
@ -184,6 +186,7 @@ static unsigned local_object_counter = 0;
|
|||
|
||||
@interface NSConnection (Private)
|
||||
- _superInit;
|
||||
- (void) handlePortMessage: (NSPortMessage*)msg;
|
||||
+ setDebug: (int)val;
|
||||
@end
|
||||
|
||||
|
@ -411,9 +414,14 @@ static int messages_received_count;
|
|||
return delegate;
|
||||
}
|
||||
|
||||
- (void) handlePortMessage: (NSPortMessage*)msg
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
}
|
||||
|
||||
- (BOOL) independantConversationQueueing
|
||||
{
|
||||
return independant_queueing;
|
||||
return independant_queueing;
|
||||
}
|
||||
|
||||
- (void) enableMultipleThreads
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
#include <Foundation/NSPort.h>
|
||||
|
@ -38,17 +39,17 @@ NSString *NSPortTimeoutException
|
|||
|
||||
+ (NSPort*) port
|
||||
{
|
||||
return [[[NSPort alloc] init] autorelease];
|
||||
return AUTORELEASE([NSPort new]);
|
||||
}
|
||||
|
||||
+ (NSPort*) portWithMachPort: (int)machPort
|
||||
{
|
||||
return [[[NSPort alloc] initWithMachPort: machPort] autorelease];
|
||||
return AUTORELEASE([[NSPort alloc] initWithMachPort: machPort]);
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone*)aZone
|
||||
{
|
||||
return [self retain];
|
||||
return RETAIN(self);
|
||||
}
|
||||
|
||||
- (id) delegate
|
||||
|
@ -75,7 +76,7 @@ NSString *NSPortTimeoutException
|
|||
|
||||
- (id) initWithMachPort: (int)machPort
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
[self shouldNotImplement: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -96,10 +97,10 @@ NSString *NSPortTimeoutException
|
|||
return is_valid;
|
||||
}
|
||||
|
||||
- (id) machPort
|
||||
- (int) machPort
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return nil;
|
||||
[self shouldNotImplement: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (void) release
|
||||
|
@ -126,8 +127,38 @@ NSString *NSPortTimeoutException
|
|||
|
||||
- (void) setDelegate: anObject
|
||||
{
|
||||
NSAssert([anObject respondsToSelector: @selector(handlePortMessage:)],
|
||||
NSInvalidArgumentException);
|
||||
delegate = anObject;
|
||||
}
|
||||
|
||||
- (void) addConnection: (NSConnection*)aConnection
|
||||
toRunLoop: (NSRunLoop*)aLoop
|
||||
forMode: (NSString*)aMode
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) removeConnection: (NSConnection*)aConnection
|
||||
fromRunLoop: (NSRunLoop*)aLoop
|
||||
forMode: (NSString*)aMode
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (unsigned) reservedSpaceLength
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (void) sendBeforeDate: (NSDate*)when
|
||||
components: (NSArray*)components
|
||||
from: (NSPort*)receivingPort
|
||||
reserved: (unsigned) length
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -32,21 +32,21 @@
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[components release];
|
||||
[super dealloc];
|
||||
RELEASE(components);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* PortMessages MUST be initialised with ports and data. */
|
||||
- (id) init
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return nil;
|
||||
[self shouldNotImplement: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) initWithMachMessage: (void*)buffer
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return nil;
|
||||
[self shouldNotImplement: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* This is the designated initialiser. */
|
||||
|
@ -54,47 +54,61 @@
|
|||
receivePort: (NSPort*)anotherPort
|
||||
components: (NSArray*)items
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
components = [[NSMutableArray allocWithZone: [self zone]]
|
||||
initWithCapacity: [items count] + 2];
|
||||
[components addObject: aPort];
|
||||
[components addObject: anotherPort];
|
||||
[components addObjectsFromArray: items];
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
components = [[NSMutableArray allocWithZone: [self zone]]
|
||||
initWithCapacity: [items count] + 2];
|
||||
[components addObject: aPort];
|
||||
[components addObject: anotherPort];
|
||||
[components addObjectsFromArray: items];
|
||||
}
|
||||
return self;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) sendBeforeDate: (NSDate*)when
|
||||
- (void) addComponent: (id)aComponent
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
NSAssert([aComponent isKindOfClass: [NSData class]]
|
||||
|| [aComponent isKindOfClass: [NSPort class]],
|
||||
NSInvalidArgumentException);
|
||||
[components addObject: aComponent];
|
||||
}
|
||||
|
||||
- (NSArray*) components
|
||||
{
|
||||
NSRange r = NSMakeRange(2, [components count]-2);
|
||||
NSRange r = NSMakeRange(2, [components count]-2);
|
||||
|
||||
return [components subarrayWithRange: r];
|
||||
}
|
||||
|
||||
- (NSPort*) sendPort
|
||||
{
|
||||
return [components objectAtIndex: 0];
|
||||
}
|
||||
|
||||
- (NSPort*) receivePort
|
||||
{
|
||||
return [components objectAtIndex: 1];
|
||||
}
|
||||
|
||||
- (void) setMsgid: (unsigned)anId
|
||||
{
|
||||
msgid = anId;
|
||||
return [components subarrayWithRange: r];
|
||||
}
|
||||
|
||||
- (unsigned) msgid
|
||||
{
|
||||
return msgid;
|
||||
return msgid;
|
||||
}
|
||||
|
||||
- (NSPort*) receivePort
|
||||
{
|
||||
return [components objectAtIndex: 1];
|
||||
}
|
||||
|
||||
- (void) sendBeforeDate: (NSDate*)when
|
||||
{
|
||||
NSPort *port = [self sendPort];
|
||||
|
||||
[port sendBeforeDate: when
|
||||
components: [self components]
|
||||
from: [self receivePort]
|
||||
reserved: [port reservedSpaceLength]];
|
||||
}
|
||||
|
||||
- (NSPort*) sendPort
|
||||
{
|
||||
return [components objectAtIndex: 0];
|
||||
}
|
||||
|
||||
- (void) setMsgid: (unsigned)anId
|
||||
{
|
||||
msgid = anId;
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -74,12 +74,11 @@
|
|||
|
||||
/* This error message should be called only if the private main function
|
||||
* was not executed successfully. This may heppen ONLY if onother library
|
||||
* or kit defines its own main function (as libobjects does).
|
||||
* or kit defines its own main function (as gnustep-base does).
|
||||
*/
|
||||
#define _GNU_MISSING_MAIN_FUNCTION_CALL @"Libobjects internal error: \
|
||||
the private libobjects function to establish the argv and environment \
|
||||
variables was not called. Please contact Tuparev@EMBL-Heidelberg.de for \
|
||||
further information."
|
||||
#define _GNU_MISSING_MAIN_FUNCTION_CALL @"GNUSTEP Internal Error: \
|
||||
The private GNUstep function to establish the argv and environment \
|
||||
variables was not called. Please report this error to bug-gnustep@gnu.org."
|
||||
|
||||
/*************************************************************************
|
||||
*** _NSConcreteProcessInfo
|
||||
|
|
|
@ -107,10 +107,11 @@ static int debug_run_loop = 0;
|
|||
* NB. This class is private to NSRunLoop and must not be subclassed.
|
||||
*/
|
||||
|
||||
@interface RunLoopWatcher: NSObject
|
||||
@interface RunLoopWatcher: NSObject <GCFinalization>
|
||||
{
|
||||
@public
|
||||
BOOL invalidated;
|
||||
BOOL handleEvent; // New-style event handling
|
||||
void *data;
|
||||
id receiver;
|
||||
RunLoopEventType type;
|
||||
|
@ -130,9 +131,9 @@ static int debug_run_loop = 0;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self invalidate];
|
||||
[limit release];
|
||||
[receiver release];
|
||||
[self gcFinalize];
|
||||
RELEASE(limit);
|
||||
RELEASE(receiver);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -144,8 +145,7 @@ static int debug_run_loop = 0;
|
|||
return;
|
||||
}
|
||||
|
||||
if ([receiver respondsToSelector:
|
||||
@selector(receivedEvent:type:extra:forMode:)])
|
||||
if (handleEvent)
|
||||
{
|
||||
[receiver receivedEvent: data type: type extra: info forMode: mode];
|
||||
}
|
||||
|
@ -155,21 +155,27 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
case ET_RDESC:
|
||||
case ET_RPORT:
|
||||
[receiver readyForReadingOnFileDescriptor: (int)info];
|
||||
[receiver readyForReadingOnFileDescriptor: (int)(gsaddr)info];
|
||||
break;
|
||||
|
||||
case ET_WDESC:
|
||||
[receiver readyForWritingOnFileDescriptor: (int)info];
|
||||
[receiver readyForWritingOnFileDescriptor: (int)(gsaddr)info];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- initWithType: (RunLoopEventType)aType
|
||||
receiver: (id)anObj
|
||||
data: (void*)item
|
||||
- (void) gcFinalize
|
||||
{
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (id) initWithType: (RunLoopEventType)aType
|
||||
receiver: (id)anObj
|
||||
data: (void*)item
|
||||
{
|
||||
invalidated = NO;
|
||||
|
||||
switch (aType)
|
||||
{
|
||||
case ET_RDESC: type = aType; break;
|
||||
|
@ -179,7 +185,12 @@ static int debug_run_loop = 0;
|
|||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSRunLoop - unknown event type"];
|
||||
}
|
||||
receiver = [anObj retain];
|
||||
receiver = RETAIN(anObj);
|
||||
if ([receiver respondsToSelector:
|
||||
@selector(receivedEvent:type:extra:forMode:)])
|
||||
handleEvent = YES;
|
||||
else
|
||||
handleEvent = NO;
|
||||
data = item;
|
||||
return self;
|
||||
}
|
||||
|
@ -224,7 +235,7 @@ static int debug_run_loop = 0;
|
|||
* messages which are due to be sent to objects once a particular
|
||||
* runloop iteration has passed.
|
||||
*/
|
||||
@interface RunLoopPerformer: NSObject
|
||||
@interface RunLoopPerformer: NSObject <GCFinalization>
|
||||
{
|
||||
SEL selector;
|
||||
id target;
|
||||
|
@ -252,10 +263,10 @@ static int debug_run_loop = 0;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[timer invalidate];
|
||||
[target release];
|
||||
[argument release];
|
||||
[modes release];
|
||||
[self gcFinalize];
|
||||
RELEASE(target);
|
||||
RELEASE(argument);
|
||||
RELEASE(modes);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -264,13 +275,18 @@ static int debug_run_loop = 0;
|
|||
if (timer != nil)
|
||||
{
|
||||
timer = nil;
|
||||
[[self retain] autorelease];
|
||||
AUTORELEASE(RETAIN(self));
|
||||
[[[NSRunLoop currentInstance] _timedPerformers]
|
||||
removeObjectIdenticalTo: self];
|
||||
}
|
||||
[target performSelector: selector withObject: argument];
|
||||
}
|
||||
|
||||
- (void) gcFinalize
|
||||
{
|
||||
[timer invalidate];
|
||||
}
|
||||
|
||||
- initWithSelector: (SEL)aSelector
|
||||
target: (id)aTarget
|
||||
argument: (id)anArgument
|
||||
|
@ -281,8 +297,8 @@ static int debug_run_loop = 0;
|
|||
if (self)
|
||||
{
|
||||
selector = aSelector;
|
||||
target = [aTarget retain];
|
||||
argument = [anArgument retain];
|
||||
target = RETAIN(aTarget);
|
||||
argument = RETAIN(anArgument);
|
||||
order = theOrder;
|
||||
modes = [theModes copy];
|
||||
}
|
||||
|
@ -331,8 +347,8 @@ static int debug_run_loop = 0;
|
|||
NSMutableArray *array;
|
||||
int i;
|
||||
|
||||
[target retain];
|
||||
[arg retain];
|
||||
RETAIN(target);
|
||||
RETAIN(arg);
|
||||
array = [[NSRunLoop currentInstance] _timedPerformers];
|
||||
for (i = [array count]; i > 0; i--)
|
||||
{
|
||||
|
@ -343,8 +359,8 @@ static int debug_run_loop = 0;
|
|||
[array removeObjectAtIndex: i-1];
|
||||
}
|
||||
}
|
||||
[arg release];
|
||||
[target release];
|
||||
RELEASE(arg);
|
||||
RELEASE(target);
|
||||
}
|
||||
|
||||
- (void) performSelector: (SEL)aSelector
|
||||
|
@ -366,7 +382,7 @@ static int debug_run_loop = 0;
|
|||
selector: @selector(fire)
|
||||
userInfo: nil
|
||||
repeats: NO]];
|
||||
[item release];
|
||||
RELEASE(item);
|
||||
}
|
||||
|
||||
- (void) performSelector: (SEL)aSelector
|
||||
|
@ -398,7 +414,7 @@ static int debug_run_loop = 0;
|
|||
userInfo: nil
|
||||
repeats: NO];
|
||||
[item setTimer: timer];
|
||||
[item release];
|
||||
RELEASE(item);
|
||||
for (i = 0; i < [modes count]; i++)
|
||||
{
|
||||
[loop addTimer: timer forMode: [modes objectAtIndex: i]];
|
||||
|
@ -438,8 +454,8 @@ static int debug_run_loop = 0;
|
|||
if (watchers == nil)
|
||||
{
|
||||
watchers = [NSMutableArray new];
|
||||
NSMapInsert (_mode_2_watchers, mode, watchers);
|
||||
[watchers release];
|
||||
NSMapInsert(_mode_2_watchers, mode, watchers);
|
||||
RELEASE(watchers);
|
||||
count = 0;
|
||||
}
|
||||
else
|
||||
|
@ -592,7 +608,7 @@ static int debug_run_loop = 0;
|
|||
data: data];
|
||||
/* Add the object to the array for the mode. */
|
||||
[self _addWatcher:info forMode:mode];
|
||||
[info release]; /* Now held in array. */
|
||||
RELEASE(info); /* Now held in array. */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,11 +699,12 @@ static int debug_run_loop = 0;
|
|||
/* Positive values are in the future. */
|
||||
while (ti > 0 && mayDoMore == YES)
|
||||
{
|
||||
id arp = [NSAutoreleasePool new];
|
||||
CREATE_AUTORELEASE_POOL(arp);
|
||||
|
||||
if (debug_run_loop)
|
||||
printf ("\tNSRunLoop run until date %f seconds from now\n", ti);
|
||||
mayDoMore = [self runMode: mode beforeDate: date];
|
||||
[arp release];
|
||||
RELEASE(arp);
|
||||
ti = [date timeIntervalSinceNow];
|
||||
}
|
||||
}
|
||||
|
@ -698,7 +715,7 @@ static int debug_run_loop = 0;
|
|||
|
||||
@implementation NSRunLoop
|
||||
|
||||
+ currentRunLoop
|
||||
+ (NSRunLoop*) currentRunLoop
|
||||
{
|
||||
static NSString *key = @"NSRunLoopThreadKey";
|
||||
NSRunLoop* r;
|
||||
|
@ -710,7 +727,7 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
r = [NSRunLoop new];
|
||||
[[t threadDictionary] setObject: r forKey: key];
|
||||
[r release];
|
||||
RELEASE(r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -722,7 +739,7 @@ static int debug_run_loop = 0;
|
|||
}
|
||||
|
||||
/* This is the designated initializer. */
|
||||
- init
|
||||
- (id) init
|
||||
{
|
||||
[super init];
|
||||
_current_mode = NSDefaultRunLoopMode;
|
||||
|
@ -736,12 +753,17 @@ static int debug_run_loop = 0;
|
|||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self gcFinalize];
|
||||
RELEASE(_performers);
|
||||
RELEASE(_timedPerformers);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) gcFinalize
|
||||
{
|
||||
NSFreeMapTable(_mode_2_timers);
|
||||
NSFreeMapTable(_mode_2_watchers);
|
||||
[_performers release];
|
||||
[_timedPerformers release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString*) currentMode
|
||||
|
@ -762,7 +784,7 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
timers = [Heap new];
|
||||
NSMapInsert (_mode_2_timers, mode, timers);
|
||||
[timers release];
|
||||
RELEASE(timers);
|
||||
}
|
||||
/* xxx Should we make sure it isn't already there? */
|
||||
[timers addObject: timer];
|
||||
|
@ -801,7 +823,7 @@ static int debug_run_loop = 0;
|
|||
break;
|
||||
}
|
||||
|
||||
[min_timer retain];
|
||||
RETAIN(min_timer);
|
||||
[timers removeFirstObject];
|
||||
/* Firing will also increment its fireDate, if it is repeating. */
|
||||
[min_timer fire];
|
||||
|
@ -809,7 +831,7 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
[timers addObject: min_timer];
|
||||
}
|
||||
[min_timer release];
|
||||
RELEASE(min_timer);
|
||||
min_timer = nil;
|
||||
[NSNotificationQueue runLoopASAP]; /* Post notifications. */
|
||||
}
|
||||
|
@ -871,11 +893,11 @@ static int debug_run_loop = 0;
|
|||
* If the watcher has been given a revised limit date -
|
||||
* re-insert it into the queue in the correct place.
|
||||
*/
|
||||
[min_watcher retain];
|
||||
RETAIN(min_watcher);
|
||||
ASSIGN(min_watcher->limit, nxt);
|
||||
[watchers removeObjectAtIndex: 0];
|
||||
[self _addWatcher: min_watcher forMode: mode];
|
||||
[min_watcher release];
|
||||
RELEASE(min_watcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1204,14 +1226,14 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
id watcher = (id) NSMapGet (wfd_2_object, (void*)fd_index);
|
||||
NSAssert(watcher, NSInternalInconsistencyException);
|
||||
[watcher eventFor:(void*)fd_index mode:_current_mode];
|
||||
[watcher eventFor: (void*)(gsaddr)fd_index mode: _current_mode];
|
||||
[NSNotificationQueue runLoopASAP];
|
||||
}
|
||||
if (FD_ISSET (fd_index, &read_fds))
|
||||
{
|
||||
id watcher = (id) NSMapGet (rfd_2_object, (void*)fd_index);
|
||||
NSAssert(watcher, NSInternalInconsistencyException);
|
||||
[watcher eventFor:(void*)fd_index mode:_current_mode];
|
||||
[watcher eventFor: (void*)(gsaddr)fd_index mode: _current_mode];
|
||||
[NSNotificationQueue runLoopASAP];
|
||||
}
|
||||
}
|
||||
|
@ -1250,12 +1272,12 @@ static int debug_run_loop = 0;
|
|||
}
|
||||
|
||||
/* Use the earlier of the two dates we have. */
|
||||
d = [[d earlierDate:date] retain];
|
||||
d = RETAIN([d earlierDate: date]);
|
||||
|
||||
/* Wait, listening to our input sources. */
|
||||
[self acceptInputForMode: mode beforeDate: d];
|
||||
|
||||
[d release];
|
||||
RELEASE(d);
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -1297,8 +1319,8 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
|||
int count = [_performers count];
|
||||
int i;
|
||||
|
||||
[target retain];
|
||||
[argument retain];
|
||||
RETAIN(target);
|
||||
RETAIN(argument);
|
||||
for (i = count; i > 0; i--)
|
||||
{
|
||||
item = (RunLoopPerformer*)[_performers objectAtIndex:(i-1)];
|
||||
|
@ -1308,8 +1330,8 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
|||
[_performers removeObjectAtIndex:(i-1)];
|
||||
}
|
||||
}
|
||||
[argument release];
|
||||
[target release];
|
||||
RELEASE(argument);
|
||||
RELEASE(target);
|
||||
}
|
||||
|
||||
- (void) configureAsServer
|
||||
|
@ -1353,7 +1375,7 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
|||
[_performers addObject:item];
|
||||
}
|
||||
}
|
||||
[item release];
|
||||
RELEASE(item);
|
||||
}
|
||||
|
||||
- (void) removePort: (NSPort*)port
|
||||
|
|
696
Source/TcpPort.m
696
Source/TcpPort.m
|
@ -44,6 +44,10 @@
|
|||
#include <base/Invocation.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSDate.h>
|
||||
#include <Foundation/NSHashTable.h>
|
||||
#include <Foundation/NSHost.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
#include <Foundation/NSPortMessage.h>
|
||||
#include <Foundation/NSPortNameServer.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -108,6 +112,698 @@ static int debug_tcp_port = 0;
|
|||
|
||||
/* Private interfaces */
|
||||
|
||||
@class GSTcpPort;
|
||||
|
||||
typedef struct {
|
||||
gsu32 sendAddr;
|
||||
gsu32 recvAddr;
|
||||
gsu16 sendPort;
|
||||
gsu16 recvPort;
|
||||
gsu32 mesgId;
|
||||
gsu32 mesgElems;
|
||||
gsu32 remaining;
|
||||
} GSTcpHeader;
|
||||
|
||||
@interface GSTcpHandle : NSObject <GCFinalization>
|
||||
{
|
||||
int desc; // Unix file descriptor.
|
||||
NSLock *myLock; // Lock for This handle.
|
||||
unsigned rLength; // Length of item read so far.
|
||||
NSPortMessage *rMsg; // Message in progress.
|
||||
unsigned rItem; // Index of current message item.
|
||||
NSMutableData *rHeader; // Buffer for item data.
|
||||
unsigned wLength;
|
||||
NSPortMessage *wMsg;
|
||||
unsigned wItem;
|
||||
NSHashTable *ports;
|
||||
}
|
||||
|
||||
+ (GSTcpHandle*) handleWithDescriptor: (int)descriptor;
|
||||
- (void) addPort: (GSTcpPort*)p;
|
||||
- (void) invalidate;
|
||||
- (void) readData;
|
||||
- (void) removePort: (GSTcpPort*)p;
|
||||
- (void) writeData;
|
||||
@end
|
||||
|
||||
@implementation GSTcpHandle
|
||||
|
||||
static NSRecursiveLock *tcpHandleLock = nil;
|
||||
static NSHashTable *tcpHandleTable = 0;
|
||||
|
||||
+ (id) allocWithZone: (NSZone*)zone
|
||||
{
|
||||
[NSException raise: NSGenericException
|
||||
format: @"attempt to alloc a GSTcpHandle!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (tcpHandleLock == nil)
|
||||
{
|
||||
[gnustep_global_lock lock];
|
||||
if (tcpHandleLock == nil)
|
||||
{
|
||||
tcpHandleLock = [NSRecursiveLock new];
|
||||
tcpHandleTable =
|
||||
NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0);
|
||||
}
|
||||
[gnustep_global_lock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
+ (GSTcpHandle*) handleWithDescriptor: (int)descriptor
|
||||
{
|
||||
static GSTcpHandle *dummy = nil;
|
||||
GSTcpHandle *handle;
|
||||
|
||||
if (descriptor < 0)
|
||||
{
|
||||
NSLog(@"illegal descriptor (%d) for Tcp Handle", descriptor);
|
||||
return nil;
|
||||
}
|
||||
|
||||
[tcpHandleLock lock];
|
||||
if (dummy == nil)
|
||||
dummy = (GSTcpHandle*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
||||
|
||||
dummy->desc = descriptor;
|
||||
handle = (GSTcpHandle*)NSHashGet(tcpHandleTable, (void*)dummy);
|
||||
|
||||
if (handle == nil)
|
||||
{
|
||||
int e;
|
||||
BOOL ok = YES;
|
||||
|
||||
if ((e = fcntl(descriptor, F_GETFL, 0)) >= 0)
|
||||
{
|
||||
e |= NBLK_OPT;
|
||||
if (fcntl(descriptor, F_SETFL, e) < 0)
|
||||
{
|
||||
NSLog(@"unable to set non-blocking mode - %s", strerror(errno));
|
||||
ok = NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"unable to get non-blocking mode - %s", strerror(errno));
|
||||
ok = NO;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
handle = (GSTcpHandle*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||
handle->desc = descriptor;
|
||||
handle->ports =
|
||||
NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0);
|
||||
NSHashInsert(tcpHandleTable, (void*)handle);
|
||||
AUTORELEASE(handle);
|
||||
}
|
||||
}
|
||||
[tcpHandleLock unlock];
|
||||
return handle;
|
||||
}
|
||||
|
||||
- (void) addPort: (GSTcpPort*)p
|
||||
{
|
||||
[myLock lock];
|
||||
NSHashInsert(ports, (void*)p);
|
||||
[myLock unlock];
|
||||
}
|
||||
|
||||
- (void) gcFinalize
|
||||
{
|
||||
[myLock lock];
|
||||
|
||||
[tcpHandleLock lock];
|
||||
NSHashRemove(tcpHandleTable, (void*)self);
|
||||
[tcpHandleLock unlock];
|
||||
|
||||
(void) close(desc);
|
||||
desc = -1;
|
||||
|
||||
NSFreeHashTable(ports);
|
||||
RELEASE(rHeader);
|
||||
RELEASE(rMsg);
|
||||
RELEASE(wMsg);
|
||||
|
||||
[myLock unlock];
|
||||
RELEASE(myLock);
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
{
|
||||
return (unsigned)desc;
|
||||
}
|
||||
|
||||
- (void) invalidate
|
||||
{
|
||||
[myLock lock];
|
||||
[myLock unlock];
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (id)anObject
|
||||
{
|
||||
if (anObject == self)
|
||||
return YES;
|
||||
if ([anObject class] == [self class]
|
||||
&& ((GSTcpHandle*)anObject)->desc == desc)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) readData
|
||||
{
|
||||
int result;
|
||||
unsigned want;
|
||||
void *bytes = 0;
|
||||
|
||||
[myLock lock];
|
||||
|
||||
do
|
||||
{
|
||||
/*
|
||||
* Get address and length of buffer for incoming data if we don't already
|
||||
* have it from an earlier iteration of the loop. Create the buffer if
|
||||
* necessary.
|
||||
*/
|
||||
if (bytes == 0)
|
||||
{
|
||||
if (rHeader == nil)
|
||||
{
|
||||
if (rItem == 0)
|
||||
want = sizeof(GSTcpHeader);
|
||||
else
|
||||
want = 6;
|
||||
|
||||
rHeader = [[NSMutableData alloc] initWithLength: want];
|
||||
bytes = [rHeader mutableBytes];
|
||||
rLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
want = [rHeader length];
|
||||
bytes = [rHeader mutableBytes];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we attempt to fill the buffer.
|
||||
*/
|
||||
result = read(desc, bytes + rLength, want - rLength);
|
||||
if (result == 0)
|
||||
{
|
||||
NSLog(@"Unexpected EOF on descriptor %d", desc);
|
||||
[self invalidate];
|
||||
}
|
||||
else if (result < 0)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
NSLog(@"Error reading on descriptor %d - %s",
|
||||
desc, strerror(errno));
|
||||
[self invalidate];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rLength += result;
|
||||
if (rLength == want)
|
||||
{
|
||||
if (rItem == 0)
|
||||
{
|
||||
if (want == sizeof(GSTcpHeader))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (result > 0);
|
||||
|
||||
[myLock unlock];
|
||||
}
|
||||
|
||||
- (void) release
|
||||
{
|
||||
if ([self retainCount] == 1)
|
||||
{
|
||||
[super retain];
|
||||
[self gcFinalize];
|
||||
[super release];
|
||||
}
|
||||
[super release];
|
||||
}
|
||||
|
||||
- (void) removePort: (GSTcpPort*)p
|
||||
{
|
||||
[myLock lock];
|
||||
NSHashRemove(ports, (void*)p);
|
||||
[myLock unlock];
|
||||
}
|
||||
|
||||
- (void) writeData
|
||||
{
|
||||
[myLock lock];
|
||||
[myLock unlock];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface GSTcpPort : NSPort <GCFinalization>
|
||||
{
|
||||
NSRecursiveLock *myLock;
|
||||
struct sockaddr_in addr;
|
||||
int listener;
|
||||
NSHashTable *handles;
|
||||
}
|
||||
|
||||
+ (GSTcpPort*) portWithNumber: (gsu16)number
|
||||
onHost: (NSHost*)host
|
||||
beforeDate: (NSDate*)limit;
|
||||
+ (GSTcpPort*) portWithAddress: (struct sockaddr_in*)address
|
||||
andHandle: (GSTcpHandle*)handle
|
||||
beforeDate: (NSDate*)limit;
|
||||
|
||||
- (void) addHandle: (GSTcpHandle*)h;
|
||||
- (void) removeHandle: (GSTcpHandle*)h;
|
||||
@end
|
||||
|
||||
@implementation GSTcpPort
|
||||
|
||||
static NSRecursiveLock *tcpPortLock = nil;
|
||||
static NSMapTable *tcpPortMap = 0;
|
||||
static GSTcpPort *dummyPort = nil;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (tcpPortLock == nil)
|
||||
{
|
||||
[gnustep_global_lock lock];
|
||||
if (tcpPortLock == nil)
|
||||
{
|
||||
tcpPortLock = [NSRecursiveLock new];
|
||||
tcpPortMap = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
dummyPort = (GSTcpPort*)NSAllocateObject(self, 0,
|
||||
NSDefaultMallocZone());
|
||||
}
|
||||
[gnustep_global_lock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
+ (GSTcpPort*) portWithAddress: (struct sockaddr_in*)sockaddr
|
||||
andHandle: (GSTcpHandle*)handle
|
||||
beforeDate: (NSDate*)limit
|
||||
{
|
||||
GSTcpPort *port = nil;
|
||||
NSMapTable *thePorts;
|
||||
|
||||
[tcpPortLock lock];
|
||||
|
||||
thePorts = (NSMapTable*)NSMapGet(tcpPortMap,
|
||||
(void*)(gsaddr)sockaddr->sin_port);
|
||||
|
||||
if (thePorts == 0)
|
||||
{
|
||||
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
NSMapInsert(tcpPortMap,
|
||||
(void*)(gsaddr)sockaddr->sin_port,
|
||||
(void*)thePorts);
|
||||
}
|
||||
|
||||
port = (GSTcpPort*)NSMapGet(tcpPortMap,
|
||||
(void*)(gsaddr)sockaddr->sin_addr.s_addr);
|
||||
|
||||
if (port == nil)
|
||||
{
|
||||
port = (GSTcpPort*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||
|
||||
port->listener = -1;
|
||||
memcpy(&port->addr, sockaddr, sizeof(port->addr));
|
||||
port->myLock = [NSRecursiveLock new];
|
||||
port->handles = NSCreateHashTable(NSObjectHashCallBacks, 0);
|
||||
NSMapInsert(thePorts, (void*)(gsaddr)sockaddr->sin_addr.s_addr,
|
||||
(void*)port);
|
||||
AUTORELEASE(port);
|
||||
}
|
||||
|
||||
if (port != nil && handle != nil)
|
||||
{
|
||||
NSHashInsert(port->handles, (void*)handle);
|
||||
[handle addPort: port];
|
||||
}
|
||||
|
||||
[tcpPortLock unlock];
|
||||
return port;
|
||||
}
|
||||
|
||||
+ (GSTcpPort*) portWithNumber: (gsu16)number
|
||||
onHost: (NSHost*)host
|
||||
beforeDate: (NSDate*)limit
|
||||
{
|
||||
unsigned i;
|
||||
GSTcpPort *port = nil;
|
||||
NSHost *thisHost = [NSHost currentHost];
|
||||
NSArray *addresses;
|
||||
NSMapTable *thePorts;
|
||||
|
||||
if (host == nil)
|
||||
{
|
||||
host = thisHost;
|
||||
}
|
||||
addresses = [host addresses];
|
||||
if ([addresses count] == 0)
|
||||
{
|
||||
NSLog(@"attempt to get port on host with no IP address");
|
||||
return nil;
|
||||
}
|
||||
|
||||
[tcpPortLock lock];
|
||||
|
||||
memset(&dummyPort->addr, '\0', sizeof(dummyPort->addr));
|
||||
dummyPort->addr.sin_family = AF_INET;
|
||||
dummyPort->addr.sin_port = GSSwapHostI16ToBig(number);
|
||||
|
||||
/*
|
||||
* Get the map table of ports with the specified number.
|
||||
*/
|
||||
thePorts = (NSMapTable*)NSMapGet(tcpPortMap,
|
||||
(void*)(gsaddr)dummyPort->addr.sin_port);
|
||||
|
||||
if (thePorts)
|
||||
{
|
||||
/*
|
||||
* Check to see if we have a port for any one of the hosts IP addresses.
|
||||
*/
|
||||
for (i = 0; port == nil && i < [addresses count]; i++)
|
||||
{
|
||||
const char *a = [[addresses objectAtIndex: i] cString];
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
dummyPort->sin_addr.s_addr = inet_addr(a);
|
||||
#else
|
||||
if (inet_aton(a, &dummyPort->addr.sin_addr) == 0)
|
||||
{
|
||||
NSLog(@"attempt to get port on host with bad address - '%s'", a);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
port = (GSTcpPort*)NSMapGet(thePorts,
|
||||
(void*)(gsaddr)dummyPort->addr.sin_addr.s_addr);
|
||||
if (port != nil)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (port == nil)
|
||||
{
|
||||
if (host == thisHost)
|
||||
{
|
||||
int status = 1;
|
||||
int desc;
|
||||
|
||||
port = (GSTcpPort*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||
port->listener = -1;
|
||||
port->handles =
|
||||
NSCreateHashTable(NSObjectHashCallBacks, 0);
|
||||
|
||||
port->addr.sin_addr.s_addr = GSSwapHostI32ToBig(INADDR_ANY);
|
||||
|
||||
if ((desc = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0)
|
||||
{
|
||||
NSLog(@"unable to create socket - %s", strerror(errno));
|
||||
DESTROY(port);
|
||||
}
|
||||
else if (setsockopt(desc, SOL_SOCKET, SO_REUSEADDR, (char *)&status,
|
||||
sizeof(status)) < 0)
|
||||
{
|
||||
(void) close(desc);
|
||||
NSLog(@"unable to set reuse on socket - %s", strerror(errno));
|
||||
DESTROY(port);
|
||||
}
|
||||
else if (bind(desc, (struct sockaddr *)&port->addr,
|
||||
sizeof(port->addr)) < 0)
|
||||
{
|
||||
NSLog(@"unable to bind to port %s:%d - %s",
|
||||
inet_ntoa(port->addr.sin_addr), number, strerror(errno));
|
||||
(void) close(desc);
|
||||
DESTROY(port);
|
||||
}
|
||||
else if (listen(desc, 5) < 0)
|
||||
{
|
||||
NSLog(@"unable to listen on port - %s", strerror(errno));
|
||||
(void) close(desc);
|
||||
DESTROY(port);
|
||||
}
|
||||
else if (getsockname(desc, (struct sockaddr*)&port->addr, &i) < 0)
|
||||
{
|
||||
NSLog(@"unable to get socket name - %s", strerror(errno));
|
||||
(void) close(desc);
|
||||
DESTROY(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
port->listener = desc;
|
||||
port->myLock = [NSRecursiveLock new];
|
||||
|
||||
/*
|
||||
* Ok - now add the port for all the IP addresses it listens on.
|
||||
*/
|
||||
for (i = 0; i < [addresses count]; i++)
|
||||
{
|
||||
const char *a = [[addresses objectAtIndex: i] cString];
|
||||
gsaddr val;
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
dummyPort->addr.sin_addr.s_addr = inet_addr(a);
|
||||
#else
|
||||
if (inet_aton(a, &dummyPort->addr.sin_addr) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
val = (gsaddr)dummyPort->addr.sin_addr.s_addr;
|
||||
|
||||
if (thePorts == 0)
|
||||
{
|
||||
/*
|
||||
* No known ports within this port number -
|
||||
* create the map table to add the new port to.
|
||||
*/
|
||||
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
NSMapInsert(tcpPortMap,
|
||||
(void*)(gsaddr)port->addr.sin_port,
|
||||
(void*)thePorts);
|
||||
}
|
||||
NSMapInsert(thePorts, (void*)val, (void*)port);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (number != 0) /* Can't connect to port zero */
|
||||
{
|
||||
for (i = 0; port == nil && i < [addresses count]; i++)
|
||||
{
|
||||
int desc;
|
||||
const char *a = [[addresses objectAtIndex: i] cString];
|
||||
|
||||
port = (GSTcpPort*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||
port->listener = -1;
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
port->addr.sin_addr.s_addr = inet_addr(a);
|
||||
#else
|
||||
if (inet_aton(a, &port->addr.sin_addr) == 0)
|
||||
{
|
||||
NSLog(@"opening port on host with bad address - '%s'", a);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((desc = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0)
|
||||
{
|
||||
NSLog(@"unable to create socket - %s", strerror(errno));
|
||||
DESTROY(port);
|
||||
}
|
||||
else if (connect(desc, (struct sockaddr*)&port->addr,
|
||||
sizeof(port->addr)) < 0)
|
||||
{
|
||||
NSLog(@"unable to make connection to %s:%d - %s", a,
|
||||
GSSwapBigI16ToHost(port->addr.sin_port), strerror(errno));
|
||||
DESTROY(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSTcpHandle *handle;
|
||||
|
||||
port->myLock = [NSRecursiveLock new];
|
||||
port->handles =
|
||||
NSCreateHashTable(NSObjectHashCallBacks, 0);
|
||||
handle = [GSTcpHandle handleWithDescriptor: desc];
|
||||
NSHashInsert(port->handles, (void*)handle);
|
||||
if (thePorts == 0)
|
||||
{
|
||||
/*
|
||||
* No known ports within this port number -
|
||||
* create the map table to add the new port to.
|
||||
*/
|
||||
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
NSMapInsert(tcpPortMap,
|
||||
(void*)(gsaddr)port->addr.sin_port,
|
||||
(void*)thePorts);
|
||||
}
|
||||
NSMapInsert(thePorts,
|
||||
(void*)(gsaddr)port->addr.sin_addr.s_addr, (void*)port);
|
||||
}
|
||||
}
|
||||
}
|
||||
AUTORELEASE(port);
|
||||
}
|
||||
|
||||
[tcpPortLock unlock];
|
||||
return port;
|
||||
}
|
||||
|
||||
- (void) addHandle: (GSTcpHandle*)h
|
||||
{
|
||||
[myLock lock];
|
||||
NSHashInsert(handles, (void*)h);
|
||||
[myLock unlock];
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone*)zone
|
||||
{
|
||||
return RETAIN(self);
|
||||
}
|
||||
|
||||
- (void) gcFinalize
|
||||
{
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
{
|
||||
return (unsigned)(addr.sin_addr.s_addr ^ addr.sin_port);
|
||||
}
|
||||
|
||||
- (void) invalidate
|
||||
{
|
||||
[myLock lock];
|
||||
|
||||
if ([self isValid])
|
||||
{
|
||||
NSMapTable *thePorts;
|
||||
NSArray *handleArray;
|
||||
unsigned i;
|
||||
|
||||
[tcpPortLock lock];
|
||||
thePorts = NSMapGet(tcpPortMap, (void*)(gsaddr)addr.sin_port);
|
||||
if (thePorts)
|
||||
{
|
||||
gsaddr val;
|
||||
|
||||
if (listener == -1)
|
||||
{
|
||||
val = (gsaddr)addr.sin_addr.s_addr;
|
||||
NSMapRemove(thePorts, (void*)val);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i;
|
||||
NSArray *addresses = [[NSHost currentHost] addresses];
|
||||
|
||||
for (i = 0; i < [addresses count]; i++)
|
||||
{
|
||||
const char *a = [[addresses objectAtIndex: i] cString];
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
addr,sin_addr.s_addr = inet_addr(a);
|
||||
#else
|
||||
if (inet_aton(a, &addr.sin_addr) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
val = (gsaddr)addr.sin_addr.s_addr;
|
||||
NSMapRemove(thePorts, (void*)val);
|
||||
}
|
||||
}
|
||||
}
|
||||
[tcpPortLock unlock];
|
||||
|
||||
if (listener >= 0)
|
||||
{
|
||||
(void)close(listener);
|
||||
listener = -1;
|
||||
}
|
||||
|
||||
handleArray = NSAllHashTableObjects(handles);
|
||||
i = [handleArray count];
|
||||
while (i > 0)
|
||||
{
|
||||
GSTcpHandle *handle = [handleArray objectAtIndex: i];
|
||||
|
||||
[handle removePort: self];
|
||||
}
|
||||
NSFreeHashTable(handles);
|
||||
|
||||
[super invalidate];
|
||||
}
|
||||
[myLock unlock];
|
||||
RELEASE(myLock);
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (id)anObject
|
||||
{
|
||||
if (anObject == self)
|
||||
return YES;
|
||||
if ([anObject class] == [self class])
|
||||
{
|
||||
GSTcpPort *o = (GSTcpPort*)anObject;
|
||||
|
||||
if (o->addr.sin_port == addr.sin_port &&
|
||||
o->addr.sin_addr.s_addr == addr.sin_addr.s_addr)
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) release
|
||||
{
|
||||
if ([self retainCount] == 1)
|
||||
{
|
||||
[super retain];
|
||||
[self gcFinalize];
|
||||
[super release];
|
||||
}
|
||||
[super release];
|
||||
}
|
||||
|
||||
- (void) removeHandle: (GSTcpHandle*)h
|
||||
{
|
||||
[myLock lock];
|
||||
NSHashRemove(handles, (void*)h);
|
||||
[myLock unlock];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface TcpInPort (Private)
|
||||
- (int) _port_socket;
|
||||
- (struct sockaddr_in*) _listeningSockaddr;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue