mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
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:
parent
00ce6b106b
commit
6d5b0dda0d
3 changed files with 94 additions and 39 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue