mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
Tweaks to match OSX pointer array behaviors more accurately.
This commit is contained in:
parent
5699959d39
commit
a1514249f3
3 changed files with 223 additions and 125 deletions
|
@ -179,6 +179,9 @@ relinquishRetainedMemory(const void *item,
|
|||
|
||||
- (id) initWithOptions: (NSPointerFunctionsOptions)options
|
||||
{
|
||||
int memoryType = options & 0x00ff;
|
||||
int personality = options & 0xff00;
|
||||
|
||||
#define Unsupported(X) ({\
|
||||
NSLog(@"*** An unsupported PointerFunctions configuration was requested,"\
|
||||
@" probably for use by NSMapTable, NSHashTable, or NSPointerArray. %@",\
|
||||
|
@ -186,130 +189,155 @@ relinquishRetainedMemory(const void *item,
|
|||
DESTROY(self);\
|
||||
})
|
||||
|
||||
if (memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
||||
/* Check that we have a valid memory management option.
|
||||
*/
|
||||
switch (memoryType)
|
||||
{
|
||||
case NSPointerFunctionsMachVirtualMemory:
|
||||
case NSPointerFunctionsMallocMemory:
|
||||
case NSPointerFunctionsOpaqueMemory:
|
||||
case NSPointerFunctionsStrongMemory:
|
||||
case NSPointerFunctionsWeakMemory:
|
||||
case NSPointerFunctionsZeroingWeakMemory:
|
||||
break;
|
||||
|
||||
default:
|
||||
Unsupported(@"The requested configuration fails due to"
|
||||
@" an unknown memory type being specified.");
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Save the supplied options (with modification if needed).
|
||||
*/
|
||||
if (NSPointerFunctionsZeroingWeakMemory == memoryType)
|
||||
{
|
||||
/* Garbage Collection is no longer supported, so we treat all weak
|
||||
* memory the same way.
|
||||
*/
|
||||
_x.options = (options & 0xffffff00) | NSPointerFunctionsWeakMemory;
|
||||
memoryType = NSPointerFunctionsWeakMemory;
|
||||
_x.options = (options & 0xffffff00) | memoryType;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.options = options;
|
||||
}
|
||||
|
||||
/* First we look at the memory management options to see which function
|
||||
* should be used to relinquish contents of a container with these
|
||||
* options.
|
||||
/* Check for unsupported memory/personality combinations
|
||||
*/
|
||||
if (memoryType(options, NSPointerFunctionsWeakMemory)
|
||||
|| memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
||||
if (NSPointerFunctionsIntegerPersonality == personality)
|
||||
{
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
else if (memoryType(options, NSPointerFunctionsOpaqueMemory))
|
||||
{
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
else if (memoryType(options, NSPointerFunctionsMallocMemory))
|
||||
{
|
||||
_x.relinquishFunction = relinquishMallocMemory;
|
||||
}
|
||||
else if (memoryType(options, NSPointerFunctionsMachVirtualMemory))
|
||||
{
|
||||
_x.relinquishFunction = relinquishMallocMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NSPointerFunctionsStrongMemory uses -release for objects
|
||||
*/
|
||||
if (personalityType(options, NSPointerFunctionsObjectPersonality)
|
||||
|| personalityType(options, NSPointerFunctionsObjectPointerPersonality))
|
||||
{
|
||||
_x.relinquishFunction = relinquishRetainedMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we look at the personality options to determine other functions.
|
||||
*/
|
||||
if (personalityType(options, NSPointerFunctionsOpaquePersonality))
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
_x.descriptionFunction = describePointer;
|
||||
_x.hashFunction = hashShifted;
|
||||
_x.isEqualFunction = equalDirect;
|
||||
}
|
||||
else if (personalityType(options, NSPointerFunctionsObjectPointerPersonality))
|
||||
{
|
||||
if (memoryType(options, NSPointerFunctionsWeakMemory)
|
||||
|| memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.acquireFunction = acquireRetainedObject;
|
||||
}
|
||||
_x.descriptionFunction = describeObject;
|
||||
_x.hashFunction = hashShifted;
|
||||
_x.isEqualFunction = equalDirect;
|
||||
}
|
||||
else if (personalityType(options, NSPointerFunctionsCStringPersonality))
|
||||
{
|
||||
if (memoryType(options, NSPointerFunctionsMallocMemory))
|
||||
{
|
||||
_x.acquireFunction = acquireMallocMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.acquireFunction = NULL;
|
||||
}
|
||||
_x.descriptionFunction = describeString;
|
||||
_x.hashFunction = hashString;
|
||||
_x.isEqualFunction = equalString;
|
||||
}
|
||||
else if (personalityType(options, NSPointerFunctionsStructPersonality))
|
||||
{
|
||||
_x.acquireFunction = acquireMallocMemory;
|
||||
_x.descriptionFunction = describePointer;
|
||||
_x.hashFunction = hashMemory;
|
||||
_x.isEqualFunction = equalMemory;
|
||||
}
|
||||
else if (personalityType(options, NSPointerFunctionsIntegerPersonality))
|
||||
{
|
||||
if (memoryType(options, NSPointerFunctionsOpaqueMemory))
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
_x.descriptionFunction = describeInteger;
|
||||
_x.hashFunction = hashDirect;
|
||||
_x.isEqualFunction = equalDirect;
|
||||
}
|
||||
else
|
||||
if (NSPointerFunctionsOpaqueMemory != memoryType)
|
||||
{
|
||||
Unsupported(@"The requested configuration fails due to"
|
||||
@" integer personality not using opaque memory.");
|
||||
return self;
|
||||
}
|
||||
}
|
||||
else /* objects */
|
||||
{
|
||||
if (memoryType(options, NSPointerFunctionsWeakMemory)
|
||||
|| memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.acquireFunction = acquireRetainedObject;
|
||||
}
|
||||
_x.descriptionFunction = describeObject;
|
||||
_x.hashFunction = hashObject;
|
||||
_x.isEqualFunction = equalObject;
|
||||
}
|
||||
|
||||
if (NSPointerFunctionsObjectPersonality == personality
|
||||
|| NSPointerFunctionsObjectPointerPersonality == personality)
|
||||
{
|
||||
if (NSPointerFunctionsMachVirtualMemory == memoryType
|
||||
|| NSPointerFunctionsMallocMemory == memoryType)
|
||||
{
|
||||
Unsupported(@"The requested configuration fails due to"
|
||||
@" integer personality not using opaque memory.");
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Now we look at the personality options to determine functions.
|
||||
*/
|
||||
switch (personality)
|
||||
{
|
||||
case NSPointerFunctionsCStringPersonality:
|
||||
if (NSPointerFunctionsMachVirtualMemory == memoryType
|
||||
|| NSPointerFunctionsMallocMemory == memoryType)
|
||||
{
|
||||
_x.acquireFunction = acquireMallocMemory;
|
||||
_x.relinquishFunction = relinquishMallocMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
_x.descriptionFunction = describeString;
|
||||
_x.hashFunction = hashString;
|
||||
_x.isEqualFunction = equalString;
|
||||
break;
|
||||
|
||||
case NSPointerFunctionsIntegerPersonality:
|
||||
_x.acquireFunction = 0;
|
||||
_x.relinquishFunction = 0;
|
||||
_x.descriptionFunction = describeInteger;
|
||||
_x.hashFunction = hashDirect;
|
||||
_x.isEqualFunction = equalDirect;
|
||||
break;
|
||||
|
||||
case NSPointerFunctionsObjectPersonality:
|
||||
if (NSPointerFunctionsWeakMemory == memoryType)
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.acquireFunction = acquireRetainedObject;
|
||||
_x.relinquishFunction = relinquishRetainedMemory;
|
||||
}
|
||||
_x.descriptionFunction = describeObject;
|
||||
_x.hashFunction = hashObject;
|
||||
_x.isEqualFunction = equalObject;
|
||||
break;
|
||||
|
||||
case NSPointerFunctionsObjectPointerPersonality:
|
||||
if (NSPointerFunctionsWeakMemory == memoryType)
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.acquireFunction = acquireRetainedObject;
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
_x.descriptionFunction = describeObject;
|
||||
_x.hashFunction = hashShifted;
|
||||
_x.isEqualFunction = equalDirect;
|
||||
break;
|
||||
|
||||
case NSPointerFunctionsOpaquePersonality:
|
||||
_x.acquireFunction = 0;
|
||||
_x.relinquishFunction = 0;
|
||||
_x.descriptionFunction = describePointer;
|
||||
_x.hashFunction = hashShifted;
|
||||
_x.isEqualFunction = equalDirect;
|
||||
break;
|
||||
|
||||
case NSPointerFunctionsStructPersonality:
|
||||
if (NSPointerFunctionsMachVirtualMemory == memoryType
|
||||
|| NSPointerFunctionsMallocMemory == memoryType)
|
||||
{
|
||||
_x.acquireFunction = acquireMallocMemory;
|
||||
_x.relinquishFunction = relinquishMallocMemory;
|
||||
}
|
||||
else
|
||||
{
|
||||
_x.acquireFunction = 0;
|
||||
_x.relinquishFunction = 0;
|
||||
}
|
||||
_x.descriptionFunction = describePointer;
|
||||
_x.hashFunction = hashMemory;
|
||||
_x.isEqualFunction = equalMemory;
|
||||
break;
|
||||
|
||||
default:
|
||||
Unsupported(@"The requested configuration fails due to"
|
||||
@" an unknown personality being specified.");
|
||||
return self;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,15 @@ int main()
|
|||
id testObj = [[[NSObject alloc] init] autorelease];
|
||||
for (index = 0; index < 10; index++)
|
||||
{
|
||||
[array addPointer: testObj];
|
||||
[array addPointer: testObj];
|
||||
}
|
||||
PASS([[array allObjects] count] == 10, "Array retains active weak reference");
|
||||
PASS([[array allObjects] count] == index,
|
||||
"Array retains active weak reference");
|
||||
|
||||
[arp2 release]; arp2 = nil;
|
||||
|
||||
PASS([[array allObjects] count] == 0, "Array removes dead weak reference");
|
||||
PASS([[array allObjects] count] == 0,
|
||||
"Array removes dead weak reference");
|
||||
|
||||
[arp release]; arp = nil;
|
||||
END_SET("NSPointerArray weak objects")
|
||||
|
|
|
@ -69,6 +69,10 @@ static NSUInteger aStructSize(const void *item)
|
|||
@end
|
||||
|
||||
|
||||
typedef struct {
|
||||
int code;
|
||||
const char *name;
|
||||
} OptInfo;
|
||||
|
||||
|
||||
int main()
|
||||
|
@ -83,6 +87,86 @@ int main()
|
|||
(const void *item, NSUInteger (*size)(const void *item));
|
||||
NSUInteger (*sizeFunction)(const void *item);
|
||||
|
||||
START_SET("Combinations")
|
||||
OptInfo MemoryType[] = {
|
||||
{ NSPointerFunctionsMachVirtualMemory,
|
||||
"NSPointerFunctionsMachVirtualMemory" },
|
||||
{ NSPointerFunctionsMallocMemory,
|
||||
"NSPointerFunctionsMallocMemory" },
|
||||
{ NSPointerFunctionsOpaqueMemory,
|
||||
"NSPointerFunctionsOpaqueMemory" },
|
||||
{ NSPointerFunctionsStrongMemory,
|
||||
"NSPointerFunctionsStrongMemory" },
|
||||
{ NSPointerFunctionsWeakMemory,
|
||||
"NSPointerFunctionsWeakMemory" },
|
||||
{ NSPointerFunctionsZeroingWeakMemory,
|
||||
"NSPointerFunctionsZeroingWeakMemory" },
|
||||
{ 0x00ff, "Unknown/BadMemory" }
|
||||
};
|
||||
OptInfo Personality[] = {
|
||||
{ NSPointerFunctionsCStringPersonality,
|
||||
"NSPointerFunctionsCStringPersonality" },
|
||||
{ NSPointerFunctionsIntegerPersonality,
|
||||
"NSPointerFunctionsIntegerPersonality" },
|
||||
{ NSPointerFunctionsObjectPersonality,
|
||||
"NSPointerFunctionsObjectPersonality" },
|
||||
{ NSPointerFunctionsObjectPointerPersonality,
|
||||
"NSPointerFunctionsObjectPointerPersonality" },
|
||||
{ NSPointerFunctionsOpaquePersonality,
|
||||
"NSPointerFunctionsOpaquePersonality" },
|
||||
{ NSPointerFunctionsStructPersonality,
|
||||
"NSPointerFunctionsStructPersonality" },
|
||||
{ 0xff00, "Unknown/BadPersonality" }
|
||||
};
|
||||
int mem;
|
||||
int per;
|
||||
|
||||
for (mem = 0; mem < sizeof(MemoryType) / sizeof(*MemoryType); mem++)
|
||||
{
|
||||
for (per = 0; per < sizeof(Personality) / sizeof(*Personality); per++)
|
||||
{
|
||||
int mc = MemoryType[mem].code;
|
||||
int pc = Personality[per].code;
|
||||
BOOL ok = (0x00ff != mc && 0xff00 != pc);
|
||||
const char *msg;
|
||||
|
||||
if (NSPointerFunctionsIntegerPersonality == pc)
|
||||
{
|
||||
if (NSPointerFunctionsOpaqueMemory != mc)
|
||||
{
|
||||
ok = NO;
|
||||
}
|
||||
}
|
||||
if (NSPointerFunctionsObjectPersonality == pc
|
||||
|| NSPointerFunctionsObjectPointerPersonality == pc)
|
||||
{
|
||||
if (NSPointerFunctionsMachVirtualMemory == mc
|
||||
|| NSPointerFunctionsMallocMemory == mc)
|
||||
{
|
||||
ok = NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pf = [NSPointerFunctions pointerFunctionsWithOptions: mc | pc];
|
||||
if (ok)
|
||||
{
|
||||
msg = [[NSString stringWithFormat: @"Create with %s %s allowed",
|
||||
MemoryType[mem].name, Personality[per].name] UTF8String];
|
||||
PASS(pf != nil, "%s", msg)
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = [[NSString stringWithFormat: @"Create with %s %s refused",
|
||||
MemoryType[mem].name, Personality[per].name] UTF8String];
|
||||
PASS(nil == pf, "%s", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
END_SET("Combinations")
|
||||
|
||||
START_SET("GarbageCollection")
|
||||
NSPointerFunctions *pf;
|
||||
NSPointerFunctions *zpf;
|
||||
|
@ -101,27 +185,11 @@ int main()
|
|||
|
||||
END_SET("GarbageCollection")
|
||||
|
||||
START_SET("Personality/Memory")
|
||||
PASS(nil == [NSPointerFunctions pointerFunctionsWithOptions:
|
||||
NSPointerFunctionsZeroingWeakMemory
|
||||
| NSPointerFunctionsIntegerPersonality],
|
||||
"nil on create with integer personality and zeroing weak memory")
|
||||
PASS(nil == [NSPointerFunctions pointerFunctionsWithOptions:
|
||||
NSPointerFunctionsWeakMemory
|
||||
| NSPointerFunctionsIntegerPersonality],
|
||||
"nil on create with integer personality and weak memory")
|
||||
PASS(nil == [NSPointerFunctions pointerFunctionsWithOptions:
|
||||
NSPointerFunctionsStrongMemory
|
||||
| NSPointerFunctionsIntegerPersonality],
|
||||
"nil on create with integer personality and strong memory")
|
||||
END_SET("Personality/Memory")
|
||||
|
||||
START_SET("CStringPersonality")
|
||||
{
|
||||
const char *cstr1 = "hello";
|
||||
const char *cstr2 = "hello";
|
||||
const char *cstr3 = "goodbye";
|
||||
const char *cstr;
|
||||
|
||||
pf = [NSPointerFunctions pointerFunctionsWithOptions:
|
||||
NSPointerFunctionsCStringPersonality];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue