Add default to enable mingw32 message ports

Do some debugging/fixing of mingw32 message ports.
Still not usable.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@21974 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2005-11-09 09:39:25 +00:00
parent c52e8be2d6
commit 4f6fee1ae5
4 changed files with 271 additions and 184 deletions

View file

@ -74,8 +74,7 @@ Class NSPort_concrete_class;
{
NSPort_abstract_class = self;
#ifndef __MINGW32__
/* Must be kept in sync with [NSPortNameServer
+systemDefaultPortNameServer]. */
/* Must be kept in sync with [NSPortNameServer +systemDefaultPortNameServer]. */
if (GSUserDefaultsFlag(GSMacOSXCompatible) == YES
|| [[NSUserDefaults standardUserDefaults]
boolForKey: @"NSPortIsMessagePort"])
@ -87,6 +86,11 @@ Class NSPort_concrete_class;
NSPort_concrete_class = [NSSocketPort class];
}
#else
if ([[NSUserDefaults standardUserDefaults]
boolForKey: @"GSMailslot"] == YES)
NSPort_concrete_class = [NSMessagePort class];
else
NSPort_concrete_class = [NSSocketPort class];
#endif
}

View file

@ -66,6 +66,13 @@
*/
+ (id) systemDefaultPortNameServer
{
#if defined(__MINGW__)
if ([[NSUserDefaults standardUserDefaults] boolForKey: @"GSMailslot"] == YES)
{
return [NSMessagePortNameServer sharedInstance];
}
#endif
/* Must be kept in sync with [NSPort +initialize]. */
if (GSUserDefaultsFlag(GSMacOSXCompatible) == YES)
{

View file

@ -41,6 +41,8 @@
#define UNISTR(X) \
((const unichar*)[(X) cStringUsingEncoding: NSUnicodeStringEncoding])
extern int errno;
static NSRecursiveLock *serverLock = nil;
static NSMessagePortNameServer *defaultServer = nil;
static NSMapTable portToNamesMap;
@ -68,6 +70,7 @@ static void clean_up_names(void)
}
NSEndMapTableEnumeration(&mEnum);
DESTROY(arp);
RegCloseKey(key);
if (unknownThread == YES)
{
GSUnregisterCurrentThread();
@ -93,18 +96,28 @@ static void clean_up_names(void)
NSObjectMapValueCallBacks, 0);
atexit(clean_up_names);
registry = @"Software\\GNUstepNSMessagePort\\";
rc = RegCreateKeyExW(HKEY_CURRENT_USER,
registry = @"Software\\GNUstepNSMessagePort";
rc = RegCreateKeyExW(
HKEY_CURRENT_USER,
UNISTR(registry),
0,
L"",
REG_OPTION_VOLATILE,
REG_OPTION_NON_VOLATILE,
STANDARD_RIGHTS_WRITE|STANDARD_RIGHTS_READ|KEY_SET_VALUE
|KEY_QUERY_VALUE,
NULL,
&key,
NULL);
if (rc != ERROR_SUCCESS)
if (rc == ERROR_SUCCESS)
{
rc = RegFlushKey(key);
if (rc != ERROR_SUCCESS)
{
NSLog(@"Failed to flush registry HKEY_CURRENT_USER\\%@ (%x)",
registry, rc);
}
}
else
{
NSLog(@"Failed to create registry HKEY_CURRENT_USER\\%@ (%x)",
registry, rc);
@ -134,30 +147,53 @@ static void clean_up_names(void)
+ (NSString *) _query: (NSString *)name
{
NSString *n;
unsigned char buf[24];
DWORD len = 24;
NSString *p;
unsigned char buf[25];
DWORD len = 25;
DWORD type;
HANDLE h;
int rc;
n = [[self class] _translate: name];
rc = RegQueryValueExW(key,
rc = RegQueryValueExW(
key,
UNISTR(n),
(LPDWORD)0,
(LPDWORD)REG_BINARY,
&type,
(LPBYTE)buf,
&len);
if (rc != ERROR_SUCCESS)
{
NSLog(@"Failed to read HKEY_CURRENT_USER\\%@\\%@ (%x)",
registry, n, rc);
return nil;
}
n = AUTORELEASE([[NSString alloc] initWithBytes: buf
length: 24
encoding: NSASCIIStringEncoding]);
// Fixme ... check this is valid
return n;
n = [NSString stringWithUTF8String: buf];
/*
* See if we can open the mailslot ... if not, the query returned
* an old name, and we can remove it.
*/
p = [NSString stringWithFormat:
@"\\\\.\\mailslot\\GNUstep\\NSMessagePort\\%@", n];
h = CreateFileW(
UNISTR(p),
GENERIC_WRITE,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES)0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE)0);
if (h == INVALID_HANDLE_VALUE)
{
RegDeleteValueW(key, UNISTR(n));
return nil;
}
else
{
CloseHandle(h); // OK
return n;
}
}
+ (NSString *) _translate: (NSString *)name
@ -190,7 +226,6 @@ static void clean_up_names(void)
NSMutableArray *a;
NSString *n;
int rc;
HKEY key;
NSDebugLLog(@"NSMessagePort", @"register %@ as %@\n", port, name);
if ([port isKindOfClass: [NSMessagePort class]] == NO)
@ -209,16 +244,26 @@ static void clean_up_names(void)
n = [[self class] _translate: name];
rc = RegSetValueExW(key,
rc = RegSetValueExW(
key,
UNISTR(n),
0,
REG_SZ,
REG_BINARY,
[[(NSMessagePort*)port name] UTF8String],
25);
if (rc != ERROR_SUCCESS)
if (rc == ERROR_SUCCESS)
{
NSLog(@"Failed to insert HKEY_CURRENT_USER\\%@\\%@ (%x)",
registry, n, rc);
rc = RegFlushKey(key);
if (rc != ERROR_SUCCESS)
{
NSLog(@"Failed to flush registry HKEY_CURRENT_USER\\%@\\%@ (%x)",
registry, n, rc);
}
}
else
{
NSLog(@"Failed to insert HKEY_CURRENT_USER\\%@\\%@ (%x) %s",
registry, n, rc, GSLastErrorStr(rc));
return NO;
}

View file

@ -272,6 +272,7 @@ static unsigned wordAlign;
static unsigned sequence = 0;
static int ident;
internal *this;
NSString *path;
if (sequence == 0)
{
@ -296,8 +297,11 @@ static unsigned wordAlign;
this->lock = [GSLazyRecursiveLock new];
this->rData = [NSMutableData new];
path = [NSString stringWithFormat:
@"\\\\.\\mailslot\\GNUstep\\NSMessagePort\\%@", this->name];
this->handle = CreateMailslotW(
UNISTR(this->name),
UNISTR(path),
0, /* No max message size. */
MAILSLOT_WAIT_FOREVER, /* No read/write timeout. */
(LPSECURITY_ATTRIBUTES)0);
@ -338,6 +342,7 @@ static unsigned wordAlign;
if (p == nil)
{
internal *this;
NSString *path;
_internal = NSZoneMalloc(NSDefaultMallocZone(), sizeof(internal));
memset(_internal, '\0', sizeof(internal));
@ -350,9 +355,11 @@ static unsigned wordAlign;
this->ov.hEvent = this->event;
this->lock = [GSLazyRecursiveLock new];
this->wMsgs = [NSMutableArray new];
path = [NSString stringWithFormat:
@"\\\\.\\mailslot\\GNUstep\\NSMessagePort\\%@", this->name];
this->handle = CreateFileW(
UNISTR(this->name),
UNISTR(path),
GENERIC_WRITE,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES)0,
@ -456,183 +463,199 @@ static unsigned wordAlign;
M_LOCK(this->lock);
/*
* Got something ... is it all we want?
*/
this->rLength += this->size;
this->size = 0;
/*
* Do next part only if we have completed a read.
*/
if (this->rWant > 0 && this->rLength == this->rWant)
if (this->rWant > 0)
{
switch (this->rType)
/*
* Have we read something?
*/
if (GetOverlappedResult(
this->handle,
&this->ov,
&this->size,
TRUE) == 0)
{
case GSP_ITEM:
NSLog(@"GetOverlappedResult failed ...%s", GSLastErrorStr(errno));
}
else
{
this->rLength += this->size;
this->size = 0;
}
/*
* Do next part only if we have completed a read.
*/
if (this->rLength == this->rWant)
{
switch (this->rType)
{
GSPortItemHeader *h;
unsigned l;
case GSP_ITEM:
{
GSPortItemHeader *h;
unsigned l;
/*
* We have read an item header - set up to read the
* remainder of the item.
*/
h = (GSPortItemHeader*)[this->rData bytes];
this->rType = GSSwapBigI32ToHost(h->type);
l = GSSwapBigI32ToHost(h->length);
if (this->rType == GSP_HEAD)
{
if (l + sizeof(GSPortItemHeader) > this->rWant)
/*
* We have read an item header - set up to read the
* remainder of the item.
*/
h = (GSPortItemHeader*)[this->rData bytes];
this->rType = GSSwapBigI32ToHost(h->type);
l = GSSwapBigI32ToHost(h->length);
if (this->rType == GSP_HEAD)
{
// There is more to read ... do it.
this->rWant = l + sizeof(GSPortItemHeader);
this->rType = GSP_HEAD;
}
else
{
goto gsp_head;
}
}
else if (this->rType == GSP_PORT)
{
if (l != 24)
{
NSLog(@"%@ - unreasonable length (%u) for port", self, l);
[self invalidate];
break;
}
this->rWant = l;
[this->rData setLength: this->rWant];
}
else if (this->rType == GSP_DATA)
{
if (l == 0)
{
NSData *d;
/*
* For a zero-length data chunk, we create an empty
* data object and add it to the current message.
*/
d = [NSMutableData new];
[this->rItems addObject: d];
RELEASE(d);
if (this->nItems == [this->rItems count])
if (l + sizeof(GSPortItemHeader) > this->rWant)
{
shouldDispatch = YES;
// There is more to read ... do it.
this->rWant = l + sizeof(GSPortItemHeader);
this->rType = GSP_HEAD;
}
else
{
goto gsp_head;
}
}
else
else if (this->rType == GSP_PORT)
{
if (l > maxDataLength)
if (l != 24)
{
NSLog(@"%@ - unreasonable length (%u) for data",
self, l);
NSLog(@"%@ - unreasonable length (%u) for port",
self, l);
[self invalidate];
break;
}
this->rWant = l;
[this->rData setLength: this->rWant];
}
else if (this->rType == GSP_DATA)
{
if (l == 0)
{
NSData *d;
/*
* For a zero-length data chunk, we create an empty
* data object and add it to the current message.
*/
d = [NSMutableData new];
[this->rItems addObject: d];
RELEASE(d);
if (this->nItems == [this->rItems count])
{
shouldDispatch = YES;
}
}
else
{
if (l > maxDataLength)
{
NSLog(@"%@ - unreasonable length (%u) for data",
self, l);
[self invalidate];
break;
}
this->rWant = l;
[this->rData setLength: this->rWant];
}
}
else
{
NSLog(@"%@ - bad data received on port handle", self);
[self invalidate];
return;
}
}
else
break;
case GSP_HEAD:
gsp_head:
{
NSLog(@"%@ - bad data received on port handle", self);
[self invalidate];
return;
unsigned char *b = [this->rData mutableBytes];
GSPortItemHeader *pih;
GSPortMsgHeader *pmh;
NSString *n;
NSMessagePort *p;
unsigned l;
NSMutableData *d;
pih = (GSPortItemHeader*)b;
l = GSSwapBigI32ToHost(pih->length);
pmh = (GSPortMsgHeader*)(b + sizeof(GSPortItemHeader));
this->rId = GSSwapBigI32ToHost(pmh->mId);
this->nItems = GSSwapBigI32ToHost(pmh->nItems);
if (this->nItems == 0)
{
NSLog(@"%@ - unable to decode remote port", self);
[self invalidate];
break;
}
n = [[NSString alloc] initWithBytes: pmh->port
length: 24
encoding: NSASCIIStringEncoding];
NSDebugFLLog(@"NSMessagePort", @"Decoded port as '%@'", n);
p = [NSMessagePort sendPort: n];
RELEASE(n);
if (p == nil)
{
NSLog(@"%@ - unable to decode remote port", self);
[self invalidate];
break;
}
ASSIGN(this->rPort, p);
this->rItems
= [NSMutableArray allocWithZone: NSDefaultMallocZone()];
this->rItems = [this->rItems initWithCapacity: this->nItems];
b = (unsigned char*)&pmh[1];
l -= sizeof(GSPortMsgHeader);
d = [[NSMutableData alloc] initWithBytes: b length: l];
[this->rItems addObject: d];
RELEASE(d);
if (this->nItems == [this->rItems count])
{
shouldDispatch = YES;
}
}
break;
case GSP_DATA:
{
NSMutableData *d;
d = [this->rData mutableCopy];
[this->rItems addObject: d];
RELEASE(d);
if (this->nItems == [this->rItems count])
{
shouldDispatch = YES;
}
}
break;
case GSP_PORT:
{
NSMessagePort *p;
NSString *n;
n = [[NSString alloc] initWithBytes: [this->rData bytes]
length: 24
encoding: NSASCIIStringEncoding];
NSDebugFLLog(@"NSMessagePort", @"Decoded port as '%@'", n);
p = [NSMessagePort sendPort: n];
RELEASE(n);
if (p == nil)
{
NSLog(@"%@ - unable to decode remote port", self);
[self invalidate];
break;
}
[this->rItems addObject: p];
if (this->nItems == [this->rItems count])
{
shouldDispatch = YES;
}
}
break;
}
break;
case GSP_HEAD:
gsp_head:
{
unsigned char *b = [this->rData mutableBytes];
GSPortItemHeader *pih;
GSPortMsgHeader *pmh;
NSString *n;
NSMessagePort *p;
unsigned l;
NSMutableData *d;
pih = (GSPortItemHeader*)b;
l = GSSwapBigI32ToHost(pih->length);
pmh = (GSPortMsgHeader*)(b + sizeof(GSPortItemHeader));
this->rId = GSSwapBigI32ToHost(pmh->mId);
this->nItems = GSSwapBigI32ToHost(pmh->nItems);
if (this->nItems == 0)
{
NSLog(@"%@ - unable to decode remote port", self);
[self invalidate];
break;
}
n = [[NSString alloc] initWithBytes: pmh->port
length: 24
encoding: NSASCIIStringEncoding];
NSDebugFLLog(@"NSMessagePort", @"Decoded port as '%@'", n);
p = [NSMessagePort sendPort: n];
RELEASE(n);
if (p == nil)
{
NSLog(@"%@ - unable to decode remote port", self);
[self invalidate];
break;
}
ASSIGN(this->rPort, p);
this->rItems
= [NSMutableArray allocWithZone: NSDefaultMallocZone()];
this->rItems = [this->rItems initWithCapacity: this->nItems];
b = (unsigned char*)&pmh[1];
l -= sizeof(GSPortMsgHeader);
d = [[NSMutableData alloc] initWithBytes: b length: l];
[this->rItems addObject: d];
RELEASE(d);
if (this->nItems == [this->rItems count])
{
shouldDispatch = YES;
}
}
break;
case GSP_DATA:
{
NSMutableData *d;
d = [this->rData mutableCopy];
[this->rItems addObject: d];
RELEASE(d);
if (this->nItems == [this->rItems count])
{
shouldDispatch = YES;
}
}
break;
case GSP_PORT:
{
NSMessagePort *p;
NSString *n;
n = [[NSString alloc] initWithBytes: [this->rData bytes]
length: 24
encoding: NSASCIIStringEncoding];
NSDebugFLLog(@"NSMessagePort", @"Decoded port as '%@'", n);
p = [NSMessagePort sendPort: n];
RELEASE(n);
if (p == nil)
{
NSLog(@"%@ - unable to decode remote port", self);
[self invalidate];
break;
}
[this->rItems addObject: p];
if (this->nItems == [this->rItems count])
{
shouldDispatch = YES;
}
}
break;
}
}
@ -684,14 +707,22 @@ static unsigned wordAlign;
*/
if ([self isValid] == YES && this->rLength < this->rWant)
{
int rc;
this->ov.Offset = 0;
this->ov.OffsetHigh = 0;
this->ov.hEvent = this->event;
if (ReadFile(this->handle,
rc = ReadFile(this->handle,
[this->rData mutableBytes], // Store results here
this->rWant - this->rLength,
&this->size,
&this->ov) == 0 && (errno = GetLastError()) != ERROR_HANDLE_EOF)
&this->ov);
if (rc > 0)
{
[self receivedEventRead]; // Read completed synchronously
}
else if ((errno = GetLastError()) != ERROR_IO_PENDING)
{
NSLog(@"unable to read from mailslot '%@' - %s",
this->name, GSLastErrorStr(errno));