/*
 * ptw32_callUserDestroyRoutines.c
 *
 * Description:
 * This translation unit implements routines which are private to
 * the implementation and may be used throughout it.
 *
 * --------------------------------------------------------------------------
 *
 *      Pthreads-win32 - POSIX Threads Library for Win32
 *      Copyright(C) 1998 John E. Bossom
 *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 * 
 *      Contact Email: rpj@callisto.canberra.edu.au
 * 
 *      The current list of contributors is contained
 *      in the file CONTRIBUTORS included with the source
 *      code distribution. The list can also be seen at the
 *      following World Wide Web location:
 *      http://sources.redhat.com/pthreads-win32/contributors.html
 * 
 *      This library is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU Lesser General Public
 *      License as published by the Free Software Foundation; either
 *      version 2 of the License, or (at your option) any later version.
 * 
 *      This library is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *      Lesser General Public License for more details.
 * 
 *      You should have received a copy of the GNU Lesser General Public
 *      License along with this library in the file COPYING.LIB;
 *      if not, write to the Free Software Foundation, Inc.,
 *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include "pthread.h"
#include "implement.h"

#ifdef __cplusplus
# if ! defined (_MSC_VER) && ! (defined(__GNUC__) && __GNUC__ < 3) && ! defined(__WATCOMC__)
using
  std::terminate;
# endif
#endif

void
ptw32_callUserDestroyRoutines (pthread_t thread)
     /*
      * -------------------------------------------------------------------
      * DOCPRIVATE
      *
      * This the routine runs through all thread keys and calls
      * the destroy routines on the user's data for the current thread.
      * It simulates the behaviour of POSIX Threads.
      *
      * PARAMETERS
      *              thread
      *                      an instance of pthread_t
      *
      * RETURNS
      *              N/A
      * -------------------------------------------------------------------
      */
{
  ThreadKeyAssoc * assoc;

  if (thread.p != NULL)
    {
      int assocsRemaining;
      int iterations = 0;
      ptw32_thread_t * sp = (ptw32_thread_t *) thread.p;

      /*
       * Run through all Thread<-->Key associations
       * for the current thread.
       *
       * Do this process at most PTHREAD_DESTRUCTOR_ITERATIONS times.
       */
      do
	{
	  assocsRemaining = 0;
	  iterations++;

	  (void) pthread_mutex_lock(&(sp->threadLock));
	  /*
	   * The pointer to the next assoc is stored in the thread struct so that
	   * the assoc destructor in pthread_key_delete can adjust it
	   * if it deletes this assoc. This can happen if we fail to acquire
	   * both locks below, and are forced to release all of our locks,
	   * leaving open the opportunity for pthread_key_delete to get in
	   * before us.
	   */
	  sp->nextAssoc = sp->keys;
	  (void) pthread_mutex_unlock(&(sp->threadLock));

	  for (;;)
	    {
	      void * value;
	      pthread_key_t k;
	      void (*destructor) (void *);

	      /*
	       * First we need to serialise with pthread_key_delete by locking
	       * both assoc guards, but in the reverse order to our convention,
	       * so we must be careful to avoid deadlock.
	       */
	      (void) pthread_mutex_lock(&(sp->threadLock));

	      if ((assoc = (ThreadKeyAssoc *)sp->nextAssoc) == NULL)
		{
		  /* Finished */
		  pthread_mutex_unlock(&(sp->threadLock));
		  break;
		}
	      else
		{
		  /*
		   * assoc->key must be valid because assoc can't change or be
		   * removed from our chain while we hold at least one lock. If
		   * the assoc was on our key chain then the key has not been
		   * deleted yet.
		   *
		   * Now try to acquire the second lock without deadlocking.
		   * If we fail, we need to relinquish the first lock and the
		   * processor and then try to acquire them all again.
		   */
		  if (pthread_mutex_trylock(&(assoc->key->keyLock)) == EBUSY)
		    {
		      pthread_mutex_unlock(&(sp->threadLock));
		      Sleep(1); // Ugly but necessary to avoid priority effects.
		      /*
		       * Go around again.
		       * If pthread_key_delete has removed this assoc in the meantime,
		       * sp->nextAssoc will point to a new assoc.
		       */
		      continue;
		    }
		}

	      /* We now hold both locks */

	      sp->nextAssoc = assoc->nextKey;

	      /*
	       * Key still active; pthread_key_delete
	       * will block on these same mutexes before
	       * it can release actual key; therefore,
	       * key is valid and we can call the destroy
	       * routine;
	       */
	      k = assoc->key;
	      destructor = k->destructor;
	      value = TlsGetValue(k->key);
	      TlsSetValue (k->key, NULL);

	      // Every assoc->key exists and has a destructor
	      if (value != NULL && iterations <= PTHREAD_DESTRUCTOR_ITERATIONS)
		{
		  /*
		   * Unlock both locks before the destructor runs.
		   * POSIX says pthread_key_delete can be run from destructors,
		   * and that probably includes with this key as target.
		   * pthread_setspecific can also be run from destructors and
		   * also needs to be able to access the assocs.
		   */
		  (void) pthread_mutex_unlock(&(sp->threadLock));
		  (void) pthread_mutex_unlock(&(k->keyLock));

		  assocsRemaining++;

#ifdef __cplusplus

		  try
		    {
		      /*
		       * Run the caller's cleanup routine.
		       */
		      destructor (value);
		    }
		  catch (...)
		    {
		      /*
		       * A system unexpected exception has occurred
		       * running the user's destructor.
		       * We get control back within this block in case
		       * the application has set up it's own terminate
		       * handler. Since we are leaving the thread we
		       * should not get any internal pthreads
		       * exceptions.
		       */
		      terminate ();
		    }

#else /* __cplusplus */

		  /*
		   * Run the caller's cleanup routine.
		   */
		  destructor (value);

#endif /* __cplusplus */

		}
	      else
		{
		  /*
		   * Remove association from both the key and thread chains
		   * and reclaim it's memory resources.
		   */
		  ptw32_tkAssocDestroy (assoc);
		  (void) pthread_mutex_unlock(&(sp->threadLock));
		  (void) pthread_mutex_unlock(&(k->keyLock));
		}
	    }
	}
      while (assocsRemaining);
    }
}				/* ptw32_callUserDestroyRoutines */
