From 6fdd577b58c6b1f8779dda5bb2d019867315d018 Mon Sep 17 00:00:00 2001 From: Richard Frith-MacDonald Date: Fri, 8 Sep 2000 09:14:29 +0000 Subject: [PATCH] Bugfix for performing action at end of run loop - do it only once, not once per loop iteration. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@7447 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 7 +++++++ Source/NSRunLoop.m | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83691a986..d071e91d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2000-09-08 Richard Frith-Macdonald + + * Source/NSRunLoop.m: ([-_checkPerformers:]) When a loop executes the + method to deal with a ([-performSelector:target:argument:order:modes]), + we cancel the request rather than leaving it to be actioned again next + time round the loop. + 2000-09-07 Richard Frith-Macdonald * Source/NSGeometry.m: Add code to parse MacOS-X format strings. diff --git a/Source/NSRunLoop.m b/Source/NSRunLoop.m index 12c341293..2960ce881 100644 --- a/Source/NSRunLoop.m +++ b/Source/NSRunLoop.m @@ -275,7 +275,7 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1) timer = nil; [target performSelector: selector withObject: argument]; [[[NSRunLoop currentInstance] _timedPerformers] - removeObjectIdenticalTo: self]; + removeObjectIdenticalTo: self]; } - (void) gcFinalize @@ -455,17 +455,45 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1) if (performers != 0 && (count = GSIArrayCount(performers)) > 0) { GSRunLoopPerformer *array[count]; + NSMapEnumerator enumerator; + GSIArray tmp; + void *mode; unsigned i; /* - * Copy the array - so we don't get messed up by any changes caused - * by 'fire'ing the performers. + * Copy the array - because we have to cancel the requests before firing. */ for (i = 0; i < count; i++) { array[i] = RETAIN(GSIArrayItemAtIndex(performers, i).obj); } + /* + * Remove the requests that we are about to fire from all modes. + */ + enumerator = NSEnumerateMapTable(_mode_2_performers); + while (NSNextMapEnumeratorPair(&enumerator, &mode, (void**)&tmp)) + { + unsigned tmpCount = GSIArrayCount(tmp); + + while (tmpCount--) + { + GSRunLoopPerformer *p; + + p = GSIArrayItemAtIndex(tmp, tmpCount).obj; + for (i = 0; i < count; i++) + { + if (p == array[i]) + { + GSIArrayRemoveItemAtIndex(tmp, tmpCount); + } + } + } + } + + /* + * Finally, fire the requests. + */ for (i = 0; i < count; i++) { [array[i] fire];