Enhanced file descriptor handling

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6394 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2000-03-28 13:02:01 +00:00
parent f39fe8336d
commit 0ed86abd4f
5 changed files with 78 additions and 105 deletions

View file

@ -1,3 +1,16 @@
2000-03-28 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/gnustep/base/NSRunLoop.h: Added event type for exceptional
conditions on a file descriptor and removed obsolete methods.
* Source/NSRunLoop.m: Added support for monitoring for exceptional
conditions on a file descriptor and removed obsolete methods for
handling file descriptors.
2000-03-26 Richard Frith-Macdonald <rfm@gnu.org>
* NSTimeZones/NSTimeZones.tar: Updated to latest information
available from elsie.nci.nih.gov
2000-03-25 Jonathan Gapen <jagapen@whitewater.chem.wisc.edu>
* Source/NSUser.m: Added new MacOS X function,

View file

@ -40,6 +40,7 @@ extern id NSDefaultRunLoopMode;
NSMapTable *_mode_2_watchers;
NSMapTable *_mode_2_performers;
NSMutableArray *_timedPerformers;
NSMapTable *_efdMap;
NSMapTable *_rfdMap;
NSMapTable *_wfdMap;
}
@ -91,17 +92,11 @@ extern id NSDefaultRunLoopMode;
* GNUstep extensions
*/
@protocol FdListening
- (void) readyForReadingOnFileDescriptor: (int)fd;
@end
@protocol FdSpeaking
- (void) readyForWritingOnFileDescriptor: (int)fd;
@end
typedef enum {
ET_RDESC, /* Watch for descriptor becoming readable. */
ET_WDESC, /* Watch for descriptor becoming writeable. */
ET_RPORT /* Watch for message arriving on port. */
ET_RDESC, /* Watch for descriptor becoming readable. */
ET_WDESC, /* Watch for descriptor becoming writeable. */
ET_RPORT, /* Watch for message arriving on port. */
ET_EDESC /* Watch for descriptor with exception data. */
} RunLoopEventType;
@protocol RunLoopEvents
@ -162,21 +157,6 @@ typedef enum {
type: (RunLoopEventType)type
forMode: (NSString*)mode
all: (BOOL)removeAll;
/*
* The next four methods are rendered obsolete by
* [-addEvent:type:watcher:forMode:] and
* [-removeEvent:type:forMode:]
*/
- (void) addReadDescriptor: (int)fd
object: (id <FdListening>)listener
forMode: (NSString*)mode;
- (void) addWriteDescriptor: (int)fd
object: (id <FdSpeaking>)speaker
forMode: (NSString*)mode;
- (void) removeReadDescriptor: (int)fd
forMode: (NSString*)mode;
- (void) removeWriteDescriptor: (int)fd
forMode: (NSString*)mode;
@end
/* xxx This interface will probably change. */

Binary file not shown.

View file

@ -118,6 +118,7 @@ static SEL eventSel = @selector(receivedEvent:type:extra:forMode:);
switch (aType)
{
case ET_EDESC: type = aType; break;
case ET_RDESC: type = aType; break;
case ET_WDESC: type = aType; break;
case ET_RPORT: type = aType; break;
@ -129,7 +130,8 @@ static SEL eventSel = @selector(receivedEvent:type:extra:forMode:);
if ([receiver respondsToSelector: eventSel] == YES)
handleEvent = [receiver methodForSelector: eventSel];
else
handleEvent = 0;
[NSException raise: NSInvalidArgumentException
format: @"RunLoop listener has no event handling method"];
data = item;
return self;
}
@ -542,27 +544,6 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
}
}
- (void) addReadDescriptor: (int)fd
object: (id <FdListening>)listener
forMode: (NSString*)mode
{
return [self addEvent: (void*)fd
type: ET_RDESC
watcher: (id<RunLoopEvents>)listener
forMode: mode];
}
/* Add our new handler information to the array. */
- (void) addWriteDescriptor: (int)fd
object: (id <FdSpeaking>)speaker
forMode: (NSString*)mode
{
return [self addEvent: (void*)fd
type: ET_WDESC
watcher: (id<RunLoopEvents>)speaker
forMode: mode];
}
- (void) removeEvent: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode
@ -596,18 +577,6 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
}
}
- (void) removeReadDescriptor: (int)fd
forMode: (NSString*)mode
{
return [self removeEvent: (void*)fd type: ET_RDESC forMode: mode all: NO];
}
- (void) removeWriteDescriptor: (int)fd
forMode: (NSString*)mode
{
return [self removeEvent: (void*)fd type: ET_WDESC forMode: mode all: NO];
}
- (BOOL) runOnceBeforeDate: date
{
return [self runOnceBeforeDate: date forMode: _current_mode];
@ -732,6 +701,8 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
_mode_2_performers = NSCreateMapTable (NSObjectMapKeyCallBacks,
ArrayMapValueCallBacks, 0);
_timedPerformers = [[NSMutableArray alloc] initWithCapacity: 8];
_efdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
WatcherMapValueCallBacks, 0);
_rfdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
WatcherMapValueCallBacks, 0);
_wfdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
@ -751,6 +722,7 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
NSFreeMapTable(_mode_2_timers);
NSFreeMapTable(_mode_2_watchers);
NSFreeMapTable(_mode_2_performers);
NSFreeMapTable(_efdMap);
NSFreeMapTable(_rfdMap);
NSFreeMapTable(_wfdMap);
}
@ -1015,7 +987,6 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
NSTimeInterval ti;
struct timeval timeout;
void *select_timeout;
fd_set fds; /* The file descriptors we will listen to. */
fd_set read_fds; /* Copy for listening to read-ready fds. */
fd_set exception_fds; /* Copy for listening to exception fds. */
fd_set write_fds; /* Copy for listening for write-ready fds. */
@ -1077,8 +1048,10 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
* The maps may not have been emptied if a previous call to this
* method was terminated by an exception.
*/
memset(&fds, '\0', sizeof(fds));
memset(&exception_fds, '\0', sizeof(exception_fds));
memset(&read_fds, '\0', sizeof(read_fds));
memset(&write_fds, '\0', sizeof(write_fds));
NSResetMapTable(_efdMap);
NSResetMapTable(_rfdMap);
NSResetMapTable(_wfdMap);
@ -1104,20 +1077,27 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
}
switch (info->type)
{
case ET_WDESC:
case ET_EDESC:
fd = (int)info->data;
FD_SET (fd, &write_fds);
NSMapInsert(_wfdMap, (void*)fd, info);
FD_SET (fd, &exception_fds);
NSMapInsert(_efdMap, (void*)fd, info);
num_inputs++;
break;
case ET_RDESC:
fd = (int)info->data;
FD_SET (fd, &fds);
FD_SET (fd, &read_fds);
NSMapInsert(_rfdMap, (void*)fd, info);
num_inputs++;
break;
case ET_WDESC:
fd = (int)info->data;
FD_SET (fd, &write_fds);
NSMapInsert(_wfdMap, (void*)fd, info);
num_inputs++;
break;
case ET_RPORT:
if ([info->receiver isValid] == NO)
{
@ -1129,7 +1109,7 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
}
else
{
id port = info->receiver;
id port = info->receiver;
int port_fd_count = 128; // xxx #define this constant
int port_fd_array[port_fd_count];
@ -1141,10 +1121,9 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
while (port_fd_count--)
{
FD_SET (port_fd_array[port_fd_count], &fds);
FD_SET (port_fd_array[port_fd_count], &read_fds);
NSMapInsert(_rfdMap,
(void*)port_fd_array[port_fd_count],
info);
(void*)port_fd_array[port_fd_count], info);
num_inputs++;
}
}
@ -1154,10 +1133,6 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
}
}
/* Wait for incoming data, listening to the file descriptors in _FDS. */
read_fds = fds;
exception_fds = fds;
/*
* If there are notifications in the 'idle' queue, we try an instantaneous
* select so that, if there is no input pending, we can service the queue.
@ -1196,6 +1171,7 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
}
if (select_return == 0)
{
NSResetMapTable(_efdMap);
NSResetMapTable(_rfdMap);
NSResetMapTable(_wfdMap);
GSNotifyIdle();
@ -1214,6 +1190,25 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
*/
for (fd_index = 0; fd_index < FD_SETSIZE; fd_index++)
{
if (FD_ISSET (fd_index, &exception_fds))
{
GSRunLoopWatcher *watcher;
watcher = (GSRunLoopWatcher*)NSMapGet(_efdMap, (void*)fd_index);
if (watcher != nil && watcher->_invalidated == NO)
{
/*
* The watcher is still valid - so call it's receivers
* event handling method.
*/
(*watcher->handleEvent)(watcher->receiver,
eventSel, watcher->data, watcher->type,
(void*)(gsaddr)fd_index, _current_mode);
}
GSNotifyASAP();
if (--select_return == 0)
break;
}
if (FD_ISSET (fd_index, &write_fds))
{
GSRunLoopWatcher *watcher;
@ -1225,17 +1220,9 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
* The watcher is still valid - so call it's receivers
* event handling method.
*/
if (watcher->handleEvent != 0)
{
(*watcher->handleEvent)(watcher->receiver,
eventSel, watcher->data, watcher->type,
(void*)(gsaddr)fd_index, _current_mode);
}
else if (watcher->type == ET_WDESC)
{
[watcher->receiver readyForWritingOnFileDescriptor:
(int)(gsaddr)fd_index];
}
(*watcher->handleEvent)(watcher->receiver,
eventSel, watcher->data, watcher->type,
(void*)(gsaddr)fd_index, _current_mode);
}
GSNotifyASAP();
if (--select_return == 0)
@ -1252,17 +1239,9 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
* The watcher is still valid - so call it's receivers
* event handling method.
*/
if (watcher->handleEvent != 0)
{
(*watcher->handleEvent)(watcher->receiver,
eventSel, watcher->data, watcher->type,
(void*)(gsaddr)fd_index, _current_mode);
}
else if (watcher->type == ET_RDESC)
{
[watcher->receiver readyForReadingOnFileDescriptor:
(int)(gsaddr)fd_index];
}
(*watcher->handleEvent)(watcher->receiver,
eventSel, watcher->data, watcher->type,
(void*)(gsaddr)fd_index, _current_mode);
}
GSNotifyASAP();
if (--select_return == 0)
@ -1272,6 +1251,7 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
/* Clean up before returning. */
NSResetMapTable(_efdMap);
NSResetMapTable(_rfdMap);
NSResetMapTable(_wfdMap);

View file

@ -310,13 +310,13 @@ NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directoryKey,
int i;
env = [[NSProcessInfo processInfo] environment];
gnustep_user_root = [env objectForKey:@"GNUSTEP_USER_ROOT"];
gnustep_local_root = [env objectForKey:@"GNUSTEP_LOCAL_ROOT"];
gnustep_network_root = [env objectForKey:@"GNUSTEP_NETWORK_ROOT"];
gnustep_system_root = [env objectForKey:@"GNUSTEP_SYSTEM_ROOT"];
gnustep_user_root = [env objectForKey: @"GNUSTEP_USER_ROOT"];
gnustep_local_root = [env objectForKey: @"GNUSTEP_LOCAL_ROOT"];
gnustep_network_root = [env objectForKey: @"GNUSTEP_NETWORK_ROOT"];
gnustep_system_root = [env objectForKey: @"GNUSTEP_SYSTEM_ROOT"];
if (directoryKey == NSApplicationDirectory
|| directoryKey == NSAllApplicationsDirectory)
|| directoryKey == NSAllApplicationsDirectory)
{
if (domainMask & NSUserDomainMask)
[paths addObject:
@ -333,14 +333,14 @@ NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directoryKey,
}
/*
if (directoryKey == NSDemoApplicationDirectory
|| directoryKey == NSAllApplicationsDirectory);
|| directoryKey == NSAllApplicationsDirectory);
if (directoryKey == NSDeveloperApplicationDirectory
|| directoryKey == NSAllApplicationsDirectory);
|| directoryKey == NSAllApplicationsDirectory);
if (directoryKey == NSAdminApplicationDirectory
|| directoryKey == NSAllApplicationsDirectory);
|| directoryKey == NSAllApplicationsDirectory);
*/
if (directoryKey == NSLibraryDirectory
|| directoryKey == NSAllLibrariesDirectory)
|| directoryKey == NSAllLibrariesDirectory)
{
if (domainMask & NSUserDomainMask)
[paths addObject:
@ -356,7 +356,7 @@ NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directoryKey,
[gnustep_system_root stringByAppendingPathComponent: libraryDir]];
}
if (directoryKey == NSDeveloperDirectory
|| directoryKey == NSAllLibrariesDirectory)
|| directoryKey == NSAllLibrariesDirectory)
{
// GNUstep doesn't have a 'Developer' subdirectory (yet?)
if (domainMask & NSUserDomainMask)