Author: rfm
Date: Fri Apr 29 09:31:48 2016
New Revision: 39708

URL: http://svn.gna.org/viewcvs/gnustep?rev=39708&view=rev
Log:
Improve checks for attempted use of a deallocate/cached autorelease pool.

Modified:
    libs/base/trunk/Source/NSAutoreleasePool.m

Modified: libs/base/trunk/Source/NSAutoreleasePool.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSAutoreleasePool.m?rev=39708&r1=39707&r2=39708&view=diff
==============================================================================
--- libs/base/trunk/Source/NSAutoreleasePool.m  (original)
+++ libs/base/trunk/Source/NSAutoreleasePool.m  Fri Apr 29 09:31:48 2016
@@ -203,7 +203,7 @@
 
 /* When the _released_count of a pool gets over this value, we raise
    an exception.  This can be adjusted with +setPoolCountThreshhold */
-static unsigned pool_count_warning_threshhold = UINT_MAX;
+static unsigned pool_count_warning_threshhold = UINT_MAX-1;
 
 /* When the number of pools in a thread gets over this value, we raise
    an exception.  This can be adjusted with +setPoolNumberThreshhold */
@@ -300,7 +300,15 @@
     {
       NSAutoreleasePool *p = pop_pool_from_cache (tv);
 
-      NSAssert(++(p->_released_count) == 0, @"corrupted pool in cache");
+      /* When we cache a 'deallocated' pool, we set its _released_count to
+       * UINT_MAX, so when we rtrieve it fromm the cache we must increment
+       * it to start with a count of zero.
+       */
+      if (++(p->_released_count) != 0)
+        {
+          [NSException raise: NSInternalInconsistencyException
+                      format: @"NSAutoreleasePool corrupted pool in cache"];
+        }
       return p;
     }
   return NSAllocateObject (self, 0, zone);
@@ -331,6 +339,7 @@
   {
     struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
     unsigned   level = 0;
+
     _parent = tv->current_pool;
     if (_parent)
       {
@@ -536,8 +545,10 @@
     return;
 
   if (_released_count >= pool_count_warning_threshhold)
-    [NSException raise: NSGenericException
-                format: @"AutoreleasePool count threshhold exceeded."];
+    {
+      [NSException raise: NSGenericException
+                 format: @"AutoreleasePool count threshhold exceeded."];
+    }
 
   /* Get a new array for the list, if the current one is full. */
   while (_released->count == _released->size)
@@ -707,7 +718,14 @@
 {
   struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
 
+  if (UINT_MAX == _released_count)
+    {
+      [NSException raise: NSInternalInconsistencyException
+                  format: @"NSAutoreleasePool -dealloc of deallocated pool"];
+    }
+
   [self emptyPool];
+  NSAssert(0 == _released_count, NSInternalInconsistencyException);
 
   /* Remove self from the linked list of pools in use.
    * We already know that we have deallocated any child (in -emptyPool),
@@ -725,12 +743,11 @@
       _parent = nil;
     }
 
-  if (_released_count-- != 0)
-    {
-      _released_count++;
-      [NSException raise: NSInternalInconsistencyException
-                  format: @"NSAutoreleasePool -dealloc of deallocated pool"];
-    }
+  /* Mark pool as cached so that any attempt to add an object to use it
+   * or to deallocate it again will raise an exception.
+   * We reset to zero when we get i out of the cache as a new allocation.
+   */
+  _released_count = UINT_MAX;
 
   /* Don't deallocate ourself, just save us for later use. */
   push_pool_to_cache (tv, self);
@@ -802,6 +819,7 @@
 
 + (void) setPoolCountThreshhold: (unsigned)c
 {
+  if (c >= UINT_MAX) c = UINT_MAX - 1;
   pool_count_warning_threshhold = c;
 }
 


_______________________________________________
Gnustep-cvs mailing list
Gnustep-cvs@gna.org
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to