tidied pipe streams in mingw32

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22711 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-03-26 06:24:55 +00:00
parent 8325ce26d1
commit eaedea3169
2 changed files with 132 additions and 97 deletions

View file

@ -1,3 +1,7 @@
2006-03-25 Richard Frith-Macdonald <rfm@gnu.org>
* Source/win32/NSStreamWin32.m: Variout tidyups for pipe streams.
2006-03-24 Richard Frith-Macdonald <rfm@gnu.org> 2006-03-24 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSRunLoopCtxt.h: * Source/GSRunLoopCtxt.h:

View file

@ -44,6 +44,8 @@
#include "../GSStream.h" #include "../GSStream.h"
#define BUFFERSIZE (BUFSIZ*64)
typedef int socklen_t; typedef int socklen_t;
/** /**
@ -63,12 +65,13 @@ typedef int socklen_t;
{ {
HANDLE handle; HANDLE handle;
OVERLAPPED ov; OVERLAPPED ov;
uint8_t data[BUFSIZ*64]; uint8_t data[BUFFERSIZE];
unsigned offset; // Read pointer within buffer unsigned offset; // Read pointer within buffer
unsigned length; // Amount of data in buffer unsigned length; // Amount of data in buffer
unsigned want; // Amount of data we want to read. unsigned want; // Amount of data we want to read.
DWORD size; // Number of bytes returned by read. DWORD size; // Number of bytes returned by read.
} }
- (NSStreamStatus) _check;
- (void) _queue; - (void) _queue;
- (void) _setHandle: (HANDLE)h; - (void) _setHandle: (HANDLE)h;
@end @end
@ -141,11 +144,12 @@ typedef int socklen_t;
{ {
HANDLE handle; HANDLE handle;
OVERLAPPED ov; OVERLAPPED ov;
NSMutableData *data; uint8_t data[BUFFERSIZE];
unsigned offset; unsigned offset;
unsigned want; unsigned want;
DWORD size; DWORD size;
} }
- (NSStreamStatus) _check;
- (void) _queue; - (void) _queue;
- (void) _setHandle: (HANDLE)h; - (void) _setHandle: (HANDLE)h;
@end @end
@ -419,6 +423,43 @@ static void setNonblocking(SOCKET fd)
[self _queue]; [self _queue];
} }
- (NSStreamStatus) _check
{
// Must only be called when current status is NSStreamStatusReading.
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0)
{
errno = GetLastError();
if (errno == ERROR_HANDLE_EOF
|| errno == ERROR_BROKEN_PIPE)
{
/*
* Got EOF, but we don't want to register it until a
* -read:maxLength: is called.
*/
offset = length = want = 0;
[self _setStatus: NSStreamStatusOpen];
}
else if (errno != ERROR_IO_PENDING)
{
/*
* Got an error ... record it.
*/
want = 0;
[self _recordError];
}
}
else
{
/*
* Read completed and some data was read.
*/
length = size;
[self _setStatus: NSStreamStatusOpen];
}
return [self streamStatus];
}
- (void) _queue - (void) _queue
{ {
if ([self streamStatus] == NSStreamStatusOpen) if ([self streamStatus] == NSStreamStatusOpen)
@ -461,6 +502,10 @@ static void setNonblocking(SOCKET fd)
{ {
NSStreamStatus myStatus = [self streamStatus]; NSStreamStatus myStatus = [self streamStatus];
if (myStatus == NSStreamStatusReading)
{
myStatus = [self _check];
}
if (myStatus == NSStreamStatusAtEnd) if (myStatus == NSStreamStatusAtEnd)
{ {
return 0; // At EOF return 0; // At EOF
@ -509,54 +554,27 @@ static void setNonblocking(SOCKET fd)
- (void) _dispatch - (void) _dispatch
{ {
NSStreamEvent myEvent; NSStreamEvent myEvent;
NSStreamStatus myStatus = [self streamStatus]; NSStreamStatus oldStatus = [self streamStatus];
NSStreamStatus myStatus = oldStatus;
if (myStatus == NSStreamStatusReading) if (myStatus == NSStreamStatusReading
|| myStatus == NSStreamStatusOpening)
{ {
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0) myStatus = [self _check];
{
errno = GetLastError();
if (errno == ERROR_HANDLE_EOF
|| errno == ERROR_BROKEN_PIPE)
{
/*
* Got EOF, but we don't want to register it until a
* -read:maxLength: is called.
*/
offset = length = 0;
}
else if (errno == ERROR_IO_PENDING)
{
/*
* Read operation has not completed.
*/
return;
}
else
{
/*
* Got an error ... record it.
*/
[self _recordError];
}
myStatus = NSStreamStatusOpen;
want = 0;
}
else
{
/*
* Read completed and some data was read.
*/
myStatus = NSStreamStatusOpen;
length = size;
}
[self _setStatus: myStatus];
} }
if (myStatus == NSStreamStatusAtEnd) if (myStatus == NSStreamStatusAtEnd)
{ {
myEvent = NSStreamEventEndEncountered; myEvent = NSStreamEventEndEncountered;
} }
else if (myStatus == NSStreamStatusError)
{
myEvent = NSStreamEventErrorOccurred;
}
else if (oldStatus == NSStreamStatusOpening)
{
myEvent = NSStreamEventOpenCompleted;
}
else else
{ {
myEvent = NSStreamEventHasBytesAvailable; myEvent = NSStreamEventHasBytesAvailable;
@ -569,15 +587,12 @@ static void setNonblocking(SOCKET fd)
{ {
NSStreamStatus myStatus = [self streamStatus]; NSStreamStatus myStatus = [self streamStatus];
*trigger = YES;
if (myStatus == NSStreamStatusReading) if (myStatus == NSStreamStatusReading)
{ {
// Need to wait for I/O return YES; // Need to wait for I/O
*trigger = YES;
return YES;
} }
// Need to signal for an event return NO; // Need to signal for an event
*trigger = YES;
return NO;
} }
@end @end
@ -973,10 +988,6 @@ static void setNonblocking(SOCKET fd)
- (void) dealloc - (void) dealloc
{ {
if (data != nil)
{
DESTROY(data);
}
if ([self _isOpened]) if ([self _isOpened])
[self close]; [self close];
[super dealloc]; [super dealloc];
@ -1022,7 +1033,7 @@ static void setNonblocking(SOCKET fd)
ov.OffsetHigh = 0; ov.OffsetHigh = 0;
ov.hEvent = (HANDLE)_loopID; ov.hEvent = (HANDLE)_loopID;
size = 0; size = 0;
rc = WriteFile(handle, [data bytes]+offset, want-offset, &size, &ov); rc = WriteFile(handle, data + offset, want - offset, &size, &ov);
if (rc != 0) if (rc != 0)
{ {
offset += size; offset += size;
@ -1043,23 +1054,56 @@ static void setNonblocking(SOCKET fd)
- (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len - (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len
{ {
if (len <= 0 || [self streamStatus] != NSStreamStatusOpen) NSStreamStatus myStatus = [self streamStatus];
if (len < 0)
{ {
return -1; return -1;
} }
if (data == nil) if (myStatus == NSStreamStatusWriting)
{ {
data = [[NSMutableData alloc] initWithBytes: buffer length: len]; myStatus = [self _check];
}
if ((myStatus != NSStreamStatusOpen && myStatus != NSStreamStatusWriting))
{
return -1;
}
if (len > (sizeof(data) - offset))
{
len = sizeof(data) - offset;
}
if (len > 0)
{
memcpy(data + offset, buffer, len);
want = offset + len;
[self _queue];
}
return len;
}
- (NSStreamStatus) _check
{
// Must only be called when current status is NSStreamStatusWriting.
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0)
{
errno = GetLastError();
if (errno != ERROR_IO_PENDING)
{
offset = 0;
want = 0;
[self _recordError];
}
} }
else else
{ {
[data setLength: 0]; [self _setStatus: NSStreamStatusOpen];
[data appendBytes: buffer length: len]; offset += size;
if (offset <= want)
{
[self _queue];
}
} }
want = len; return [self streamStatus];
offset = 0;
[self _queue];
return len;
} }
- (void) _setHandle: (HANDLE)h - (void) _setHandle: (HANDLE)h
@ -1069,44 +1113,32 @@ static void setNonblocking(SOCKET fd)
- (void) _dispatch - (void) _dispatch
{ {
BOOL av;
NSStreamEvent myEvent; NSStreamEvent myEvent;
NSStreamStatus oldStatus = [self streamStatus];
NSStreamStatus myStatus = oldStatus;
if ([self streamStatus] == NSStreamStatusWriting) if (myStatus == NSStreamStatusWriting
|| myStatus == NSStreamStatusOpening)
{ {
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0) myStatus = [self _check];
{
errno = GetLastError();
if (errno == ERROR_IO_PENDING)
{
/*
* Write operation has not completed.
*/
return;
}
[self _recordError];
offset = 0;
want = 0;
[self _setStatus: NSStreamStatusAtEnd];
}
else
{
[self _setStatus: NSStreamStatusOpen];
offset += size;
if (offset <= want)
{
[self _queue];
}
if ([self streamStatus] == NSStreamStatusWriting)
{
return; // Write not complete
}
}
} }
av = [self hasSpaceAvailable]; if (myStatus == NSStreamStatusAtEnd)
myEvent = av ? NSStreamEventHasSpaceAvailable : {
NSStreamEventEndEncountered; myEvent = NSStreamEventEndEncountered;
}
else if (myStatus == NSStreamStatusError)
{
myEvent = NSStreamEventErrorOccurred;
}
else if (oldStatus == NSStreamStatusOpening)
{
myEvent = NSStreamEventOpenCompleted;
}
else
{
myEvent = NSStreamEventHasSpaceAvailable;
}
[self _sendEvent: myEvent]; [self _sendEvent: myEvent];
} }
@ -1115,12 +1147,11 @@ static void setNonblocking(SOCKET fd)
{ {
NSStreamStatus myStatus = [self streamStatus]; NSStreamStatus myStatus = [self streamStatus];
*trigger = YES;
if (myStatus == NSStreamStatusWriting) if (myStatus == NSStreamStatusWriting)
{ {
*trigger = YES;
return YES; return YES;
} }
*trigger = YES;
return NO; return NO;
} }
@end @end