2006-04-14 Jeremy Bettis <jeremy@deadbeef.com>

* Source/win32/GSFileHandleWin32.m: Fix background reading of pipes.
		Several changes for Openstep compatiblity: Don't queue notification,
		don't raise exception when asked to read while a background operation
		is in progress.
	* Source/win32/GSRunLoopCtxt.m: If there are no handles to block on
		but there is a timer, sleep until the timer needs to wake up.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22791 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
jbettis 2006-04-14 15:17:21 +00:00
parent 00ce6b106b
commit 6d5b0dda0d
3 changed files with 94 additions and 39 deletions

View file

@ -1,3 +1,11 @@
2006-04-14 Jeremy Bettis <jeremy@deadbeef.com>
* Source/win32/GSFileHandleWin32.m: Fix background reading of pipes.
Several changes for Openstep compatiblity: Don't queue notification,
don't raise exception when asked to read while a background operation
is in progress.
* Source/win32/GSRunLoopCtxt.m: If there are no handles to block on
but there is a timer, sleep until the timer needs to wake up.
2006-04-12 Jeremy Bettis <jeremy@deadbeef.com> 2006-04-12 Jeremy Bettis <jeremy@deadbeef.com>
* Source/NSTimeZone.m: Use native time zone files under Solaris. * Source/NSTimeZone.m: Use native time zone files under Solaris.
* Source/GSFFCallInvocation.m: If the returning context is expecting * Source/GSFFCallInvocation.m: If the returning context is expecting

View file

@ -35,7 +35,6 @@
#include "Foundation/NSException.h" #include "Foundation/NSException.h"
#include "Foundation/NSRunLoop.h" #include "Foundation/NSRunLoop.h"
#include "Foundation/NSNotification.h" #include "Foundation/NSNotification.h"
#include "Foundation/NSNotificationQueue.h"
#include "Foundation/NSHost.h" #include "Foundation/NSHost.h"
#include "Foundation/NSByteOrder.h" #include "Foundation/NSByteOrder.h"
#include "Foundation/NSProcessInfo.h" #include "Foundation/NSProcessInfo.h"
@ -108,7 +107,16 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey";
} }
else else
{ {
len = read(descriptor, buf, len); DWORD readBytes=-1;
if (ReadFile((HANDLE)_get_osfhandle(descriptor), buf, len, &readBytes, NULL)) {
return readBytes;
} else {
DWORD err = GetLastError();
if (err == ERROR_BROKEN_PIPE || err == ERROR_HANDLE_EOF) {
return readBytes;
}
return -1;
}
} }
return len; return len;
} }
@ -634,13 +642,10 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
*/ */
if (n != nil) if (n != nil)
{ {
NSNotificationQueue *q; NSNotificationCenter *q;
q = [NSNotificationQueue defaultQueue]; q = [NSNotificationCenter defaultCenter];
[q enqueueNotification: n [q postNotification: n];
postingStyle: NSPostASAP
coalesceMask: NSNotificationNoCoalescing
forModes: modes];
} }
} }
@ -1220,18 +1225,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
} }
if (readInfo) if (readInfo)
{ {
id operation = [readInfo objectForKey: NotificationKey]; [self receivedEventRead];
if (operation == NSFileHandleConnectionAcceptedNotification)
{
[NSException raise: NSFileHandleOperationException
format: @"accept already in progress"];
}
else
{
[NSException raise: NSFileHandleOperationException
format: @"read already in progress"];
}
} }
} }
@ -1677,7 +1671,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
{ {
NSMutableDictionary *info = readInfo; NSMutableDictionary *info = readInfo;
NSNotification *n; NSNotification *n;
NSNotificationQueue *q; NSNotificationCenter *q;
NSArray *modes; NSArray *modes;
NSString *name; NSString *name;
@ -1695,17 +1689,14 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
RELEASE(info); /* Retained by the notification. */ RELEASE(info); /* Retained by the notification. */
q = [NSNotificationQueue defaultQueue]; q = [NSNotificationCenter defaultCenter];
[q enqueueNotification: n [q postNotification: n];
postingStyle: NSPostASAP
coalesceMask: NSNotificationNoCoalescing
forModes: modes];
} }
- (void) postWriteNotification - (void) postWriteNotification
{ {
NSMutableDictionary *info = [writeInfo objectAtIndex: 0]; NSMutableDictionary *info = [writeInfo objectAtIndex: 0];
NSNotificationQueue *q; NSNotificationCenter *q;
NSNotification *n; NSNotification *n;
NSArray *modes; NSArray *modes;
NSString *name; NSString *name;
@ -1719,11 +1710,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
writePos = 0; writePos = 0;
[writeInfo removeObjectAtIndex: 0]; /* Retained by notification. */ [writeInfo removeObjectAtIndex: 0]; /* Retained by notification. */
q = [NSNotificationQueue defaultQueue]; q = [NSNotificationCenter defaultCenter];
[q enqueueNotification: n [q postNotification: n];
postingStyle: NSPostASAP
coalesceMask: NSNotificationNoCoalescing
forModes: modes];
if ((writeOK || connectOK) && [writeInfo count] > 0) if ((writeOK || connectOK) && [writeInfo count] > 0)
{ {
[self watchWriteDescriptor]; /* In case of queued writes. */ [self watchWriteDescriptor]; /* In case of queued writes. */
@ -1772,18 +1760,30 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
for (i = 0; i < [modes count]; i++) for (i = 0; i < [modes count]; i++)
{ {
if (event)
[l removeEvent: (void*)(uintptr_t)event [l removeEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: ET_HANDLE
forMode: [modes objectAtIndex: i] forMode: [modes objectAtIndex: i]
all: YES]; all: YES];
else
[l removeEvent:0
type: ET_TRIGGER
forMode: [modes objectAtIndex: i]
all: YES];
} }
} }
else else
{ {
if (event)
[l removeEvent: (void*)(uintptr_t)event [l removeEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: ET_HANDLE
forMode: NSDefaultRunLoopMode forMode: NSDefaultRunLoopMode
all: YES]; all: YES];
else
[l removeEvent:0
type: ET_TRIGGER
forMode: NSDefaultRunLoopMode
all: YES];
} }
} }
@ -1813,7 +1813,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
for (i = 0; i < [modes count]; i++) for (i = 0; i < [modes count]; i++)
{ {
[l removeEvent: (void*)(uintptr_t)event [l removeEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: event ? ET_HANDLE : ET_TRIGGER
forMode: [modes objectAtIndex: i] forMode: [modes objectAtIndex: i]
all: YES]; all: YES];
} }
@ -1821,7 +1821,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
else else
{ {
[l removeEvent: (void*)(uintptr_t)event [l removeEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: event ? ET_HANDLE : ET_TRIGGER
forMode: NSDefaultRunLoopMode forMode: NSDefaultRunLoopMode
all: YES]; all: YES];
} }
@ -1844,19 +1844,31 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
for (i = 0; i < [modes count]; i++) for (i = 0; i < [modes count]; i++)
{ {
if (event)
[l addEvent: (void*)(uintptr_t)event [l addEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: ET_HANDLE
watcher: self watcher: self
forMode: [modes objectAtIndex: i]]; forMode: [modes objectAtIndex: i]];
else
[l addEvent:0
type: ET_TRIGGER
watcher: self
forMode: [modes objectAtIndex: i]];
} }
[readInfo setObject: modes forKey: NSFileHandleNotificationMonitorModes]; [readInfo setObject: modes forKey: NSFileHandleNotificationMonitorModes];
} }
else else
{ {
if (event)
[l addEvent: (void*)(uintptr_t)event [l addEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: ET_HANDLE
watcher: self watcher: self
forMode: NSDefaultRunLoopMode]; forMode: NSDefaultRunLoopMode];
else
[l addEvent:0
type: ET_TRIGGER
watcher: self
forMode: NSDefaultRunLoopMode];
} }
} }
@ -1882,7 +1894,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
for (i = 0; i < [modes count]; i++) for (i = 0; i < [modes count]; i++)
{ {
[l addEvent: (void*)(uintptr_t)event [l addEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: event ? ET_HANDLE : ET_TRIGGER
watcher: self watcher: self
forMode: [modes objectAtIndex: i]]; forMode: [modes objectAtIndex: i]];
} }
@ -1890,7 +1902,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
else else
{ {
[l addEvent: (void*)(uintptr_t)event [l addEvent: (void*)(uintptr_t)event
type: ET_HANDLE type: event ? ET_HANDLE : ET_TRIGGER
watcher: self watcher: self
forMode: NSDefaultRunLoopMode]; forMode: NSDefaultRunLoopMode];
} }
@ -1979,8 +1991,17 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
} }
else if (received < 0) else if (received < 0)
{ {
if (WSAGetLastError() != WSAEINTR if (isSocket && (WSAGetLastError() != WSAEINTR
&& WSAGetLastError() != WSAEWOULDBLOCK) && WSAGetLastError() != WSAEWOULDBLOCK))
{
NSString *s;
s = [NSString stringWithFormat: @"Read attempt failed - %s",
GSLastErrorStr(errno)];
[readInfo setObject: s forKey: GSFileHandleNotificationError];
[self postReadNotification];
}
else if (!isSocket && (GetLastError() != ERROR_NO_DATA))
{ {
NSString *s; NSString *s;
@ -2089,6 +2110,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
{ {
[self setNonBlocking: YES]; [self setNonBlocking: YES];
} }
if (isSocket) {
if (WSAEnumNetworkEvents((SOCKET)_get_osfhandle(descriptor), if (WSAEnumNetworkEvents((SOCKET)_get_osfhandle(descriptor),
event, &ocurredEvents) == SOCKET_ERROR) event, &ocurredEvents) == SOCKET_ERROR)
{ {
@ -2149,6 +2171,17 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
NSLog(@"Event not get %d", ocurredEvents.lNetworkEvents); NSLog(@"Event not get %d", ocurredEvents.lNetworkEvents);
abort(); abort();
} }
} else {
if ([writeInfo count] > 0)
{
[self receivedEventWrite];
}
else
{
[self receivedEventRead];
}
GSNotifyASAP();
}
} }
- (NSDate*) timedOutEvent: (void*)data - (NSDate*) timedOutEvent: (void*)data
@ -2184,8 +2217,21 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
{ {
unsigned long dummy; unsigned long dummy;
if (isSocket != YES) if (isSocket != YES) {
// Not a file and not a socket, must be a pipe
DWORD mode;
if (flag)
mode = PIPE_NOWAIT;
else
mode = PIPE_WAIT;
if (SetNamedPipeHandleState((HANDLE)_get_osfhandle(descriptor), &mode, NULL, NULL)) {
isNonBlocking = flag;
} else {
NSLog(@"unable to set pipe non-blocking mode - %d",
GetLastError());
}
return; return;
}
if (flag) if (flag)
{ {

View file

@ -413,6 +413,7 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
} }
else else
{ {
SleepEx(wait_timeout, TRUE);
wait_return = WAIT_OBJECT_0; wait_return = WAIT_OBJECT_0;
} }
NSDebugMLLog(@"NSRunLoop", @"wait returned %d", wait_return); NSDebugMLLog(@"NSRunLoop", @"wait returned %d", wait_return);