SIP(Session Initiation Protocol)是由IETF定义

源代码在线查看: tsd.c

软件大小: 10015 K
上传用户: liuchuyuan
关键词: Initiation Protocol Session IETF
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*
				 * tsd.c
				 *
				 * Description:
				 * POSIX thread functions which implement thread-specific data (TSD).
				 *
				 * Pthreads-win32 - POSIX Threads Library for Win32
				 * Copyright (C) 1998
				 *
				 * This library is free software; you can redistribute it and/or
				 * modify it under the terms of the GNU Library 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
				 * Library General Public License for more details.
				 *
				 * You should have received a copy of the GNU Library General Public
				 * License along with this library; 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"
				
				/* TLS_OUT_OF_INDEXES not defined on WinCE */
				#ifndef TLS_OUT_OF_INDEXES
				#define TLS_OUT_OF_INDEXES 0xffffffff
				#endif
				
				int
				pthread_key_create (pthread_key_t * key, void (*destructor) (void *))
				     /*
				      * ------------------------------------------------------
				      * DOCPUBLIC
				      *      This function creates a thread-specific data key visible
				      *      to all threads. All existing and new threads have a value
				      *      NULL for key until set using pthread_setspecific. When any
				      *      thread with a non-NULL value for key terminates, 'destructor'
				      *      is called with key's current value for that thread.
				      *
				      * PARAMETERS
				      *      key
				      *              pointer to an instance of pthread_key_t
				      *
				      *
				      * DESCRIPTION
				      *      This function creates a thread-specific data key visible
				      *      to all threads. All existing and new threads have a value
				      *      NULL for key until set using pthread_setspecific. When any
				      *      thread with a non-NULL value for key terminates, 'destructor'
				      *      is called with key's current value for that thread.
				      *
				      * RESULTS
				      *              0               successfully created semaphore,
				      *              EAGAIN          insufficient resources or PTHREAD_KEYS_MAX
				      *                              exceeded,
				      *              ENOMEM          insufficient memory to create the key,
				      *
				      * ------------------------------------------------------
				      */
				{
				  int result = 0;
				  pthread_key_t newkey;
				
				  if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL)
				    {
				      result = ENOMEM;
				    }
				  else if ((newkey->key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
				    {
				      result = EAGAIN;
				
				      free (newkey);
				      newkey = NULL;
				    }
				  else if (destructor != NULL)
				    {
				      /*
				       * Have to manage associations between thread and key;
				       * Therefore, need a lock that allows multiple threads
				       * to gain exclusive access to the key->threads list.
				       *
				       * The mutex will only be created when it is first locked.
				       */
				      newkey->threadsLock = PTHREAD_MUTEX_INITIALIZER;
				      newkey->destructor = destructor;
				    }
				
				  *key = newkey;
				
				  return (result);
				}
				
				int
				pthread_key_delete (pthread_key_t key)
				     /*
				      * ------------------------------------------------------
				      * DOCPUBLIC
				      *      This function deletes a thread-specific data key. This
				      *      does not change the value of the thread spcific data key
				      *      for any thread and does not run the key's destructor
				      *      in any thread so it should be used with caution.
				      *
				      * PARAMETERS
				      *      key
				      *              pointer to an instance of pthread_key_t
				      *
				      *
				      * DESCRIPTION
				      *      This function deletes a thread-specific data key. This
				      *      does not change the value of the thread spcific data key
				      *      for any thread and does not run the key's destructor
				      *      in any thread so it should be used with caution.
				      *
				      * RESULTS
				      *              0               successfully deleted the key,
				      *              EINVAL          key is invalid,
				      *
				      * ------------------------------------------------------
				      */
				{
				  int result = 0;
				
				  if (key != NULL)
				    {
				      if (key->threads != NULL &&
				          key->destructor != NULL &&
				          pthread_mutex_lock (&(key->threadsLock)) == 0)
				        {
				          /*
				           * Run through all ThreadKey associations
				           * for this key.
				           * If the pthread_t still exits (ie the assoc->thread
				           * is not NULL) then leave the assoc for the thread to
				           * destroy.
				           * Notes:
				           *      If assoc->thread is NULL, then the associated thread
				           *      is no longer referencing this assoc.
				           *      The association is only referenced
				           *      by this key and must be released; otherwise
				           *      the assoc will be destroyed when the thread is destroyed.
				           */
				          ThreadKeyAssoc *assoc;
				
				          assoc = (ThreadKeyAssoc *) key->threads;
				
				          while (assoc != NULL)
				            {
				              if (pthread_mutex_lock (&(assoc->lock)) == 0)
				                {
				                  ThreadKeyAssoc *next;
				
				                  assoc->key = NULL;
				                  next = assoc->nextThread;
				                  assoc->nextThread = NULL;
				
				                  pthread_mutex_unlock (&(assoc->lock));
				
				                  ptw32_tkAssocDestroy (assoc);
				
				                  assoc = next;
				                }
				            }
				          pthread_mutex_unlock (&(key->threadsLock));
				        }
				
				      TlsFree (key->key);
				      if (key->destructor != NULL)
				        {
				          pthread_mutex_destroy (&(key->threadsLock));
				        }
				
				#if defined( _DEBUG )
				      memset ((char *) key, 0, sizeof (*key));
				#endif
				      free (key);
				    }
				
				  return (result);
				}
				
				
				int
				pthread_setspecific (pthread_key_t key, const void *value)
				     /*
				      * ------------------------------------------------------
				      * DOCPUBLIC
				      *      This function sets the value of the thread specific
				      *	     key in the calling thread.
				      *
				      * PARAMETERS
				      *      key
				      *              an instance of pthread_key_t
				      *	     value
				      *		     the value to set key to
				      *
				      *
				      * DESCRIPTION
				      *      This function sets the value of the thread specific
				      *      key in the calling thread.
				      *
				      * RESULTS
				      *              0               successfully set value
				      *              EAGAIN          could not set value
				      *              ENOENT          SERIOUS!!
				      *
				      * ------------------------------------------------------
				      */
				{
				  pthread_t self;
				  int result = 0;
				
				  if (key != ptw32_selfThreadKey)
				    {
				      /*
				       * Using pthread_self will implicitly create
				       * an instance of pthread_t for the current
				       * thread if one wasn't explicitly created
				       */
				      self = pthread_self ();
				      if (self == NULL)
				        {
				          return ENOENT;
				        }
				    }
				  else
				    {
				      /*
				       * Resolve catch-22 of registering thread with threadSelf
				       * key
				       */
				      self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey);
				      if (self == NULL)
				        {
				          self = (pthread_t) value;
				        }
				    }
				
				  result = 0;
				
				  if (key != NULL)
				    {
				      ThreadKeyAssoc *assoc;
				
				      if (self != NULL &&
				          key->destructor != NULL &&
				          value != NULL)
				        {
				          /*
				           * Only require associations if we have to
				           * call user destroy routine.
				           * Don't need to locate an existing association
				           * when setting data to NULL for WIN32 since the
				           * data is stored with the operating system; not
				           * on the association; setting assoc to NULL short
				           * circuits the search.
				           */
				          assoc = (ThreadKeyAssoc *) self->keys;
				          /*
				           * Locate existing association
				           */
				          while (assoc != NULL)
				            {
				              if (assoc->key == key)
				                {
				                  /*
				                   * Association already exists
				                   */
				                  break;
				                }
				              assoc = assoc->nextKey;
				            }
				
				          /*
				           * create an association if not found
				           */
					  if (assoc == NULL)
					    {
					      result = ptw32_tkAssocCreate (&assoc, self, key);
					    }
				        }
				
				      if (result == 0)
				        {
				          if ( ! TlsSetValue (key->key, (LPVOID) value))
					    {
					      result = EAGAIN;
					    }
				        }
				    }
				
				  return (result);
				}                               /* pthread_setspecific */
				
				
				void *
				pthread_getspecific (pthread_key_t key)
				     /*
				      * ------------------------------------------------------
				      * DOCPUBLIC
				      *      This function returns the current value of key in the
				      *      calling thread. If no value has been set for 'key' in 
				      *      the thread, NULL is returned.
				      *
				      * PARAMETERS
				      *      key
				      *              an instance of pthread_key_t
				      *
				      *
				      * DESCRIPTION
				      *      This function returns the current value of key in the
				      *      calling thread. If no value has been set for 'key' in 
				      *      the thread, NULL is returned.
				      *
				      * RESULTS
				      *              key value
				      *
				      * ------------------------------------------------------
				      */
				{
				  return (TlsGetValue (key->key));
				}
				
							

相关资源