specific.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* ==== specific.c =======================================================
  2.  * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *  This product includes software developed by Chris Provenzano.
  16.  * 4. The name of Chris Provenzano may not be used to endorse or promote 
  17.  *   products derived from this software without specific prior written
  18.  *   permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
  21.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED.  IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY 
  24.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  25.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  26.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  28.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  30.  * SUCH DAMAGE.
  31.  *
  32.  * Description : Pthread thread specific data management.
  33.  *
  34.  *  1.20 94/03/30 proven
  35.  *      -Started coding this file.
  36.  */
  37. #ifndef lint
  38. static const char rcsid[] = "$Id$";
  39. #endif
  40. #include <errno.h>
  41. #include <pthread.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. static struct pthread_key key_table[PTHREAD_DATAKEYS_MAX];
  45. static pthread_mutex_t key_mutex = PTHREAD_MUTEX_INITIALIZER;
  46. /* ==========================================================================
  47.  * pthread_key_create()
  48.  */
  49. int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
  50. {
  51. pthread_mutex_lock(&key_mutex);
  52. for ((*key) = 0; (*key) < PTHREAD_DATAKEYS_MAX; (*key)++) {
  53. if (key_table[(*key)].count == 0) {
  54. key_table[(*key)].count++;
  55. key_table[(*key)].destructor = destructor;
  56. pthread_mutex_init(&(key_table[(*key)].mutex), NULL);
  57. pthread_mutex_unlock(&key_mutex);
  58. return(OK);
  59. }
  60. }
  61. pthread_mutex_unlock(&key_mutex);
  62. return(EAGAIN);
  63. }
  64. /* ==========================================================================
  65.  * pthread_key_delete()
  66.  */
  67. int pthread_key_delete(pthread_key_t key)
  68. {
  69. int ret;
  70. if (key < PTHREAD_DATAKEYS_MAX) {
  71. pthread_mutex_lock(&(key_table[key].mutex));
  72. switch (key_table[key].count) {
  73. case 1:
  74. pthread_mutex_destroy(&(key_table[key].mutex));
  75. key_table[key].destructor = NULL;
  76. key_table[key].count = 0;
  77. case 0:
  78. ret = OK;
  79. break;
  80. default:
  81. ret = EBUSY;
  82. }
  83. pthread_mutex_unlock(&(key_table[key].mutex));
  84. } else {
  85. ret = EINVAL;
  86. }
  87. return(ret);
  88. }
  89. /* ==========================================================================
  90.  * pthread_cleanupspecific()
  91.  */
  92. void pthread_cleanupspecific(void) 
  93. {
  94. void * data;
  95. int key;
  96. int itr;
  97. pthread_mutex_lock(&key_mutex);
  98. for (itr = 0; itr < _POSIX_THREAD_DESTRUTOR_ITERATIONS; itr++) {
  99. for (key = 0; key < PTHREAD_DATAKEYS_MAX; key++) {
  100. if (pthread_run->specific_data_count) {
  101. if (pthread_run->specific_data[key]) {
  102. data = (void *)pthread_run->specific_data[key];
  103. pthread_run->specific_data[key] = NULL;
  104. pthread_run->specific_data_count--;
  105. if (key_table[key].destructor) {
  106. pthread_mutex_unlock(&key_mutex);
  107. key_table[key].destructor(data);
  108. pthread_mutex_lock(&key_mutex);
  109. }
  110. key_table[key].count--;
  111. }
  112. } else {
  113. free(pthread_run->specific_data);
  114. pthread_mutex_unlock(&key_mutex);
  115. return;
  116. }
  117. }
  118. }
  119. free(pthread_run->specific_data);
  120. pthread_mutex_unlock(&key_mutex);
  121. }
  122. static inline const void ** pthread_key_allocate_data(void)
  123. {
  124. const void ** new_data;
  125. if(new_data = (const void**)malloc(sizeof(void *) * PTHREAD_DATAKEYS_MAX)) {
  126. memset((void *)new_data, 0, sizeof(void *) * PTHREAD_DATAKEYS_MAX);
  127. }
  128. return(new_data);
  129. }
  130. /* ==========================================================================
  131.  * pthread_setspecific()
  132.  */
  133. int pthread_setspecific(pthread_key_t key, const void * value)
  134. {
  135. int ret;
  136. if ((pthread_run->specific_data) ||
  137.   (pthread_run->specific_data = pthread_key_allocate_data())) {
  138. if ((key < PTHREAD_DATAKEYS_MAX) && (key_table)) {
  139. pthread_mutex_lock(&(key_table[key].mutex));
  140. if (key_table[key].count) {
  141. if (pthread_run->specific_data[key] == NULL) {
  142. if (value != NULL) {
  143. pthread_run->specific_data_count++;
  144. key_table[key].count++;
  145. }
  146. } else {
  147. if (value == NULL) {
  148. pthread_run->specific_data_count--;
  149. key_table[key].count--;
  150. }
  151. }
  152. pthread_run->specific_data[key] = value;
  153. ret = OK;
  154. } else {
  155. ret = EINVAL;
  156. }
  157. pthread_mutex_unlock(&(key_table[key].mutex));
  158. } else {
  159. ret = EINVAL;
  160. }
  161. } else {
  162. ret = ENOMEM;
  163. }
  164. return(ret);
  165. }
  166. /* ==========================================================================
  167.  * pthread_getspecific()
  168.  */
  169. void * pthread_getspecific(pthread_key_t key)
  170. {
  171. void *ret;
  172. if ((pthread_run->specific_data) && (key < PTHREAD_DATAKEYS_MAX)
  173.       && (key_table)) {
  174. pthread_mutex_lock(&(key_table[key].mutex));
  175. if (key_table[key].count) {
  176. ret = (void *)pthread_run->specific_data[key];
  177. } else {
  178. ret = NULL;
  179. }
  180. pthread_mutex_unlock(&(key_table[key].mutex));
  181. } else {
  182. ret = NULL;
  183. }
  184. return(ret);
  185. }