Simplify buffering and re-use single buffer for registrations and notifications

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31172 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2010-08-17 07:28:44 +00:00
parent fd9e60c1af
commit cba4f3d4a5
2 changed files with 17 additions and 12 deletions

View file

@ -7,9 +7,9 @@
2010-08-17 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSNotificationQueue.m: notify() .. buffer notifications
in a mutable array and remove from list before posting them.
Prevents re-entrancy problems and avoids memory leak when an exception
occurs during posting.
and remove from list before posting them.
Prevents re-entrancy problems where another call to notify() could
post (and remove from the list) notifications.
2010-08-13 Eric Wasylishen <ewasylishen@gmail.com>

View file

@ -567,8 +567,8 @@ notify(NSNotificationCenter *center, NSNotificationQueueList *list,
NSString *mode, NSZone *zone)
{
BOOL allocated = NO;
NSNotificationQueueRegistration *buf[100];
NSNotificationQueueRegistration **ptr = buf;
void *buf[100];
void **ptr = buf;
unsigned len = sizeof(buf) / sizeof(*buf);
unsigned pos = 0;
NSNotificationQueueRegistration *item = list->head;
@ -607,24 +607,29 @@ notify(NSNotificationCenter *center, NSNotificationQueueList *list,
}
len = pos; // Number of items found
/* Posting a notification catches exceptions, so it's OK to use
* retain/release of objects here as we won't get an exception
* causing a leak.
*/
if (len > 0)
{
NSMutableArray *ma = [NSMutableArray arrayWithCapacity: len];
for (pos = 0; pos < len; pos++)
{
item = ptr[pos];
[ma addObject: item->notification];
ptr[pos] = RETAIN(item->notification);
remove_from_queue(list, item, zone);
}
for (pos = 0; pos < len; pos++)
{
NSNotification *n = (NSNotification*)ptr[pos];
[center postNotification: n];
RELEASE(n);
}
if (allocated)
{
NSZoneFree(NSDefaultMallocZone(), ptr);
}
for (pos = 0; pos < len; pos++)
{
[center postNotification: [ma objectAtIndex: pos]];
}
}
}