1  /* Interface for NSAutoreleasePool for GNUStep
       2     Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
       3  
       4     Written by:  Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
       5     Date: 1995
       6     
       7     This file is part of the GNUstep Base Library.
       8  
       9     This library is free software; you can redistribute it and/or
      10     modify it under the terms of the GNU Lesser General Public
      11     License as published by the Free Software Foundation; either
      12     version 2 of the License, or (at your option) any later version.
      13     
      14     This library is distributed in the hope that it will be useful,
      15     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17     Library General Public License for more details.
      18     
      19     You should have received a copy of the GNU Lesser General Public
      20     License along with this library; if not, write to the Free
      21     Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      22     Boston, MA 02111 USA.
      23     */ 
      24  
      25  #ifndef __NSAutoreleasePool_h_GNUSTEP_BASE_INCLUDE
      26  #define __NSAutoreleasePool_h_GNUSTEP_BASE_INCLUDE
      27  #import	"../GNUstepBase/GSVersionMacros.h"
      28  
      29  #import	"NSObject.h"
      30  
      31  #if	defined(__cplusplus)
      32  extern "C" {
      33  #endif
      34  
      35  @class NSAutoreleasePool;
      36  @class NSThread;
      37  
      38  
      39  /**
      40   * Each thread has its own copy of these variables.
      41   <example>
      42  {
      43    NSAutoreleasePool *current_pool; // current pool for thread
      44    unsigned total_objects_count;    // total #/autoreleased objects over thread's lifetime
      45    id *pool_cache;                  // cache of previously-allocated pools,
      46    int pool_cache_size;             //  used internally for recycling
      47    int pool_cache_count;
      48  }
      49   </example>
      50  */
      51  typedef struct autorelease_thread_vars
      52  {
      53    /* The current, default NSAutoreleasePool for the calling thread;
      54       the one that will hold objects that are arguments to
      55       [NSAutoreleasePool +addObject:]. */
      56    __unsafe_unretained NSAutoreleasePool *current_pool;
      57  
      58    /* The total number of objects autoreleased since the thread was
      59       started, or since -resetTotalAutoreleasedObjects was called
      60       in this thread. (if compiled in) */
      61    unsigned total_objects_count;
      62  
      63    /* A cache of NSAutoreleasePool's already alloc'ed.  Caching old pools
      64       instead of deallocating and re-allocating them will save time. */
      65    __unsafe_unretained id *pool_cache;
      66    int pool_cache_size;
      67    int pool_cache_count;
      68  } thread_vars_struct;
      69  
      70  /* Initialize an autorelease_thread_vars structure for a new thread.
      71     This function is called in NSThread each time an NSThread is created.
      72     TV should be of type `struct autorelease_thread_vars *' */
      73  #define init_autorelease_thread_vars(TV) \
      74  memset (TV, 0, sizeof (__typeof__ (*TV)))
      75  
      76  
      77  
      78  /**
      79   *  Each pool holds its objects-to-be-released in a linked-list of 
      80      these structures.
      81      <example>
      82  {
      83    struct autorelease_array_list *next;
      84    unsigned size;
      85    unsigned count;
      86    id objects[0];
      87  }
      88      </example>
      89   */
      90  typedef struct autorelease_array_list
      91  {
      92    struct autorelease_array_list *next;
      93    unsigned size;
      94    unsigned count;
      95    __unsafe_unretained id objects[0];
      96  } array_list_struct;
      97  
      98  
      99  
     100  /**
     101   * <p>
     102   *   The standard OpenStep system of memory management employs retain counts.
     103   *   When an object is created, it has a retain count of 1.  When an object
     104   *   is retained, the retain count is incremented.  When it is released the
     105   *   retain count is decremented, and when the retain count goes to zero the
     106   *   object gets deallocated.
     107   * </p>
     108   * <p>
     109   *   A simple retain/release mechanism has problems with passing objects
     110   *   from one scope to another,
     111   *   so it's augmented with autorelease pools.  You can use the
     112   *   AUTORELEASE() macro to call the [NSObject-autorelease]
     113   *   method, which adds an object to the current autorelease pool by
     114   *   calling [NSAutoreleasePool+addObject:].<br />
     115   *   An autorelease pool simply maintains a reference to each object
     116   *   added to it, and for each addition, the autorelease pool will
     117   *   call the [NSObject-release] method of the object when the pool
     118   *   is released.  So doing an AUTORELEASE() is just the same as
     119   *   doing a RELEASE(), but deferred until the current autorelease
     120   *   pool is deallocated.
     121   * </p>
     122   * <p>
     123   *   The NSAutoreleasePool class maintains a separate stack of
     124   *   autorelease pools objects in each thread.
     125   * </p>
     126   * <p>
     127   *   When an autorelease pool is created, it is automatically
     128   *   added to the stack of pools in the thread.
     129   * </p>
     130   * <p>
     131   *   When a pool is destroyed, it (and any pool later in
     132   *   the stack) is removed from the stack.
     133   * </p>
     134   * <p>
     135   *   This mechanism provides a simple but controllable and reasonably
     136   *   efficient way of managing temporary objects.  An object can be
     137   *   autoreleased and then passed around and used until the topmost 
     138   *   pool in the stack is destroyed.
     139   * </p>   
     140   * <p>
     141   *   Most methods return objects which are either owned by autorelease
     142   *   pools or by the receiver of the method, so the lifetime of the
     143   *   returned object can be assumed to be the shorter of the lifetime
     144   *   of the current autorelease pool, or that of the receiver on which
     145   *   the method was called.<br />
     146   *   The exceptions to this are those object returned by -
     147   * </p>
     148   * <deflist>
     149   *   <term>[NSObject+alloc], [NSObject+allocWithZone:]</term>
     150   *   <desc>
     151   *     Methods whose names begin with alloc return an uninitialised
     152   *     object, owned by the caller.
     153   *   </desc>
     154   *   <term>[NSObject-init]</term>
     155   *   <desc>
     156   *     Methods whose names begin with init return an initialised
     157   *     version of the receiving object, owned by the caller.<br />
     158   *     NB. The returned object may not actually be the same as the
     159   *     receiver ... sometimes an init method releases the original
     160   *     receiver and returns an alternative.
     161   *   </desc>
     162   *   <term>[NSObject+new]</term>
     163   *   <desc>
     164   *     Methods whose names begin with new combine the effects of
     165   *     allocation and initialisation.
     166   *   </desc>
     167   *   <term>[NSObject-copy], [(NSCopying)-copyWithZone:]</term>
     168   *   <desc>
     169   *     Methods whose names begin with copy create a copy of the receiver
     170   *     which is owned by the caller.
     171   *   </desc>
     172   *   <term>
     173   *     [NSObject-mutableCopy], [(NSMutableCopying)-mutableCopyWithZone:]
     174   *   </term>
     175   *   <desc>
     176   *     Methods whose names begin with mutableCopy create a copy of the receiver
     177   *     which is owned by the caller.
     178   *   </desc>
     179   * </deflist>
     180   */
     181  NS_AUTOMATED_REFCOUNT_UNAVAILABLE
     182  @interface NSAutoreleasePool : NSObject 
     183  {
     184  #if	GS_EXPOSE(NSAutoreleasePool) && !__has_feature(objc_arc)
     185    /* For re-setting the current pool when we are dealloc'ed. */
     186    NSAutoreleasePool *_parent;
     187    /* This pointer to our child pool is  necessary for co-existing
     188       with exceptions. */
     189    NSAutoreleasePool *_child;
     190    /* A collection of the objects to be released. */
     191    struct autorelease_array_list *_released;
     192    struct autorelease_array_list *_released_head;
     193    /* The total number of objects autoreleased in this pool. */
     194    unsigned _released_count;
     195    /* The method to add an object to this pool */
     196    void 	(*_addImp)(id, SEL, id);
     197  #endif
     198  #if     GS_NONFRAGILE
     199  #else
     200    /* Pointer to private additional data used to avoid breaking ABI
     201     * when we don't have the non-fragile ABI available.
     202     * Use this mechanism rather than changing the instance variable
     203     * layout (see Source/GSInternal.h for details).
     204     */
     205    @private id _internal GS_UNUSED_IVAR;
     206  #endif
     207  }
     208  
     209  /**
     210   * Adds anObj to the current autorelease pool.<br />
     211   * If there is no autorelease pool in the thread,
     212   * a warning is logged and the object is leaked (ie it will not be released).
     213   */
     214  + (void) addObject: (id)anObj;
     215  
     216  /**
     217   * Allocate and return an autorelease pool instance.<br />
     218   * If there is an already-allocated NSAutoreleasePool available,
     219   * save time by just returning that, rather than allocating a new one.<br />
     220   * The pool instance becomes the current autorelease pool for this thread.
     221   */
     222  + (id) allocWithZone: (NSZone*)zone;
     223  
     224  /**
     225   * Adds anObj to this autorelease pool.
     226   */
     227  - (void) addObject: (id)anObj;
     228  
     229  /**
     230   * Raises an exception - pools should not be autoreleased.
     231   */
     232  - (id) autorelease;
     233  
     234  #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
     235  /**
     236   * Intended to trigger a garbage collection run (if needed) when called in
     237   * a garbage collected environment.<br />
     238   * In a non-garbage collected environment, this method implements the
     239   * undocumented MacOS-X behavior, and releases the receiver.
     240   */
     241  - (void) drain;
     242  #endif
     243  
     244  /**
     245   * Destroys the receiver (calls -dealloc).
     246   */
     247  - (oneway void) release;
     248  
     249  /**
     250   * Raises an exception ... pools should not be retained.
     251   */
     252  - (id) retain;
     253  
     254  #if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
     255  /**
     256   * <p>
     257   *   Counts the number of times that the specified object occurs
     258   *   in autorelease pools in the current thread.
     259   * </p>
     260   * <p>
     261   *   This method is <em>slow</em> and should probably only be
     262   *   used for debugging purposes.
     263   * </p>
     264   */
     265  + (unsigned) autoreleaseCountForObject: (id)anObject;
     266  
     267  /** 
     268   * Return the currently active autorelease pool.
     269   */
     270  + (id) currentPool;
     271  
     272  /**
     273   * <p>
     274   *   Specifies whether objects contained in autorelease pools are to
     275   *   be released when the pools are deallocated (by default YES).
     276   * </p>
     277   * <p>
     278   *   You can set this to NO for debugging purposes.
     279   * </p>
     280   */
     281  + (void) enableRelease: (BOOL)enable;
     282  
     283  /**
     284   * <p>
     285   *   When autorelease pools are deallocated, the memory they used
     286   *   is retained in a cache for re-use so that new polls can be
     287   *   created very quickly.
     288   * </p>
     289   * <p>
     290   *   This method may be used to empty that cache, ensuring that
     291   *   the minimum memory is used by the application.
     292   * </p>
     293   */
     294  + (void) freeCache;
     295  
     296  /**
     297   * <p>
     298   *   Specifies a limit to the number of objects that may be added to
     299   *   an autorelease pool.  When this limit is reached an exception is
     300   *   raised.
     301   * </p>
     302   * <p>
     303   *   You can set this to a smallish value to catch problems with code
     304   *   that autoreleases too many objects to operate efficiently.
     305   * </p>
     306   * <p>
     307   *   Default value is maxint.
     308   * </p>
     309   */
     310  + (void) setPoolCountThreshold: (unsigned)c;
     311  
     312  /**
     313   * Return the number of objects in this pool.
     314   */
     315  - (unsigned) autoreleaseCount;
     316  
     317  /**
     318   * Empties the current pool by releasing all the autoreleased objects
     319   * in it.  Also destroys any child pools (ones created after
     320   * the receiver in the same thread) causing any objects in those pools
     321   * to be released.<br />
     322   * This is a low cost (efficient) method which may be used to get rid of
     323   * autoreleased objects in the pool, but carry on using the pool.
     324   */
     325  - (void) emptyPool;
     326  #endif
     327  @end
     328  
     329  #if	defined(__cplusplus)
     330  }
     331  #endif
     332  
     333  #endif /* __NSAutoreleasePool_h_GNUSTEP_BASE_INCLUDE */