pike.git / src / builtin.cmod

version» Context lines:

pike.git/src/builtin.cmod:2495:   #endif /* !USE_SETENV */   }      /*    * Backtrace handling.    */      /*! @module Pike    */    + /*! @class InhibitDestruct +  *! +  *! This is a class that implements a way to temporarily +  *! inhibit destruction by explicit calls of @[destruct()]. +  *! +  *! This is mostly useful as a mix-in for modules +  *! implemented in C or similar. +  *! +  *! All symbols in the class are either @expr{protected@} +  *! or @expr{private@} in order to affect users minimally. +  */ + PIKECLASS InhibitDestruct + { +  CVAR ptrdiff_t lock_count; +  +  /*! @decl void inhibit_destruct() +  *! +  *! Inhibit explicit destruction of this object. +  *! +  *! @seealso +  *! @[permit_destruct()], @[_destruct()], +  *! @[destruct()], @[lfun::_destruct()] +  */ +  PIKEFUN void inhibit_destruct() +  flags ID_PROTECTED; +  { +  if (UNLIKELY(THIS->lock_count < 0)) { +  THIS->lock_count--; +  } else { +  THIS->lock_count++; +  } +  } +  +  /*! @decl void permit_destruct() +  *! +  *! Allow explicit destruction of this object again. +  *! +  *! @seealso +  *! @[inhibit_destruct()], @[_destruct()], +  *! @[destruct()], @[lfun::_destruct()] +  */ +  PIKEFUN void permit_destruct() +  flags ID_PROTECTED; +  { +  if (!THIS->lock_count) { +  Pike_error("permit_destruct() without inhibit.\n"); +  } +  if (UNLIKELY(THIS->lock_count < 0)) { +  /* destruct() has been called on the object. */ +  if (UNLIKELY(!++THIS->lock_count)) { +  /* No inhibits remaining. +  * +  * Time to die. +  */ +  destruct(Pike_fp->current_object); +  } +  } else { +  THIS->lock_count--; +  } +  } +  +  /*! @decl int(0..1) _destruct(int|void reason) +  *! +  *! Returns @expr{1@} when @[inhibit_destruct()] has been +  *! called more times than @[permit_destruct()]. +  *! +  *! @seealso +  *! @[inhibit_destruct()], @[permit_destruct()], +  *! @[destruct()], @[lfun::_destruct()] +  */ +  PIKEFUN int(0..1) _destruct(int|void reason) +  flags ID_PROTECTED; +  { +  if (THIS->lock_count > 0) { +  THIS->lock_count = -THIS->lock_count; +  } +  push_int(!!THIS->lock_count); +  } + }; +  + /*! @endclass +  */ +    /*! @class FakeObject    *!    *! Used as a place holder in eg backtraces for objects that    *! are unsuitable to have references to in backtraces.    *!    *! Examples of such objects are instances of @[Thread.MutexKey],    *! and @[Nettle.Cipher.State].    *!    *! @seealso    *! @[backtrace()]