Add some consistecy checks

This commit is contained in:
rfm 2024-11-15 12:28:14 +00:00
parent a1e17402cf
commit 072c17f315
2 changed files with 77 additions and 31 deletions

View file

@ -241,21 +241,31 @@ extern "C" {
*/
+ (BOOL) isExiting;
/** This method informs the system that anAddress is a pointer whose content
* has been leaked and should be released and zeroed out (if clean-up is
* enabled) at process exit. If the content of the location is changed
* between the point where this method is called and the process exits,
* then the new content of the address is what will be released on clean-up.
/** This method informs the system that anObject should be retained to
* persist until the process exits. If clean-up is enabled the object
* should be released upon process exit.
* If this method is called while the process is already existing it
* returns nil, otherwise it returnes the retained argument.
* Raises an exception if anObject has already been leaked or if it is
* nil (unless the process is exiting).
*/
+ (id) NS_RETURNS_RETAINED leak: (id)anObject;
/** This method informs the system that the object at anAddress has been
* retained to persist until the process exits. If clean-up is enabled
* the object should be released (and the address content zeroed out)
* upon process exit.
* If this method is called while the process is already existing it releases
* the object and zeros out the memory location then returns nil, otherwise
* it returns the object found at the memory location.
* Raises an exception if anAddress (or the object at anAddress) has already
* been leaked or if it is nil (unless the process is exiting).
*/
+ (void) leaked: (id*)anAddress;
/** Deprecated: use +leaked: instead.
/** DEPRECATED ... use +leaked: instead.
*/
+ (id) NS_RETURNS_RETAINED leak: (id)anObject GS_DEPRECATED_FUNC;
/** Deprecated: use +leaked: instead.
*/
+ (id) NS_RETURNS_RETAINED leakAt: (id*)anAddress ;//GS_DEPRECATED_FUNC;
+ (id) NS_RETURNS_RETAINED leakAt: (id*)anAddress;
/** Sets the receiver to have its +atExit method called at the point when
* the process terminates.<br />

View file

@ -227,26 +227,9 @@ handleExit()
return isExiting;
}
+ (void) leaked: (id*)anAddress
{
struct exitLink *l;
NSAssert(*anAddress && [*anAddress isKindOfClass: [NSObject class]],
NSInvalidArgumentException);
l = (struct exitLink*)malloc(sizeof(struct exitLink));
l->at = anAddress;
l->obj = *anAddress;
l->sel = 0;
setup();
[exitLock lock];
l->next = exited;
exited = l;
[exitLock unlock];
}
+ (id) leakAt: (id*)anAddress
{
struct exitLink *l;
struct exitLink *l;
l = (struct exitLink*)malloc(sizeof(struct exitLink));
l->at = anAddress;
@ -260,16 +243,69 @@ handleExit()
return l->obj;
}
+ (void) leaked: (id*)anAddress
{
struct exitLink *l;
NSAssert(anAddress != NULL, NSInvalidArgumentException);
if (isExiting)
{
[*anAddress release];
*anAddress = nil;
return nil;
}
NSAssert([*anAddress isKindOfClass: [NSObject class]],
NSInvalidArgumentException);
setup();
[exitLock lock];
for (l = exited; l != NULL; l = l->next)
{
if (l->at == anAddress)
{
[exitLock unlock];
[NSException raise: NSInvalidArgumentException
format: @"Repeated use of leak address %p", anAddress];
}
if (*anAddress != nil && *anAddress == l->obj)
{
[exitLock unlock];
[NSException raise: NSInvalidArgumentException
format: @"Repeated use of leak object %p", *anAddress];
}
}
l = (struct exitLink*)malloc(sizeof(struct exitLink));
l->at = anAddress;
l->obj = *anAddress;
l->sel = 0;
l->next = exited;
exited = l;
[exitLock unlock];
return l->obj;
}
+ (id) leak: (id)anObject
{
struct exitLink *l;
if (nil == anObject || isExiting)
{
return nil;
}
setup();
[exitLock lock];
for (l = exited; l != NULL; l = l->next)
{
if (l->obj == anObject || (l->at != nil && *l->at == anObject))
{
[exitLock unlock];
[NSException raise: NSInvalidArgumentException
format: @"Repeated use of leak object %p", anObject];
}
}
l = (struct exitLink*)malloc(sizeof(struct exitLink));
l->at = 0;
l->obj = [anObject retain];
l->sel = 0;
setup();
[exitLock lock];
l->next = exited;
exited = l;
[exitLock unlock];