1/* 2 * pthread_cond_init.c 3 * 4 * Description: 5 * This translation unit implements condition variables and their primitives. 6 * 7 * 8 * -------------------------------------------------------------------------- 9 * 10 * Pthreads-win32 - POSIX Threads Library for Win32 11 * Copyright(C) 1998 John E. Bossom 12 * Copyright(C) 1999,2005 Pthreads-win32 contributors 13 * 14 * Contact Email: rpj@callisto.canberra.edu.au 15 * 16 * The current list of contributors is contained 17 * in the file CONTRIBUTORS included with the source 18 * code distribution. The list can also be seen at the 19 * following World Wide Web location: 20 * http://sources.redhat.com/pthreads-win32/contributors.html 21 * 22 * This library is free software; you can redistribute it and/or 23 * modify it under the terms of the GNU Lesser General Public 24 * License as published by the Free Software Foundation; either 25 * version 2 of the License, or (at your option) any later version. 26 * 27 * This library is distributed in the hope that it will be useful, 28 * but WITHOUT ANY WARRANTY; without even the implied warranty of 29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 * Lesser General Public License for more details. 31 * 32 * You should have received a copy of the GNU Lesser General Public 33 * License along with this library in the file COPYING.LIB; 34 * if not, write to the Free Software Foundation, Inc., 35 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 36 */ 37 38#include "pthread.h" 39#include "implement.h" 40 41 42int 43pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) 44 /* 45 * ------------------------------------------------------ 46 * DOCPUBLIC 47 * This function initializes a condition variable. 48 * 49 * PARAMETERS 50 * cond 51 * pointer to an instance of pthread_cond_t 52 * 53 * attr 54 * specifies optional creation attributes. 55 * 56 * 57 * DESCRIPTION 58 * This function initializes a condition variable. 59 * 60 * RESULTS 61 * 0 successfully created condition variable, 62 * EINVAL 'attr' is invalid, 63 * EAGAIN insufficient resources (other than 64 * memory, 65 * ENOMEM insufficient memory, 66 * EBUSY 'cond' is already initialized, 67 * 68 * ------------------------------------------------------ 69 */ 70{ 71 int result; 72 pthread_cond_t cv = NULL; 73 74 if (cond == NULL) 75 { 76 return EINVAL; 77 } 78 79 if ((attr != NULL && *attr != NULL) && 80 ((*attr)->pshared == PTHREAD_PROCESS_SHARED)) 81 { 82 /* 83 * Creating condition variable that can be shared between 84 * processes. 85 */ 86 result = ENOSYS; 87 goto DONE; 88 } 89 90 cv = (pthread_cond_t) calloc (1, sizeof (*cv)); 91 92 if (cv == NULL) 93 { 94 result = ENOMEM; 95 goto DONE; 96 } 97 98 cv->nWaitersBlocked = 0; 99 cv->nWaitersToUnblock = 0; 100 cv->nWaitersGone = 0; 101 102 if (sem_init (&(cv->semBlockLock), 0, 1) != 0) 103 { 104 result = errno; 105 goto FAIL0; 106 } 107 108 if (sem_init (&(cv->semBlockQueue), 0, 0) != 0) 109 { 110 result = errno; 111 goto FAIL1; 112 } 113 114 if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0) 115 { 116 goto FAIL2; 117 } 118 119 result = 0; 120 121 goto DONE; 122 123 /* 124 * ------------- 125 * Failed... 126 * ------------- 127 */ 128FAIL2: 129 (void) sem_destroy (&(cv->semBlockQueue)); 130 131FAIL1: 132 (void) sem_destroy (&(cv->semBlockLock)); 133 134FAIL0: 135 (void) free (cv); 136 cv = NULL; 137 138DONE: 139 if (0 == result) 140 { 141 ptw32_mcs_local_node_t node; 142 143 ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node); 144 145 cv->next = NULL; 146 cv->prev = ptw32_cond_list_tail; 147 148 if (ptw32_cond_list_tail != NULL) 149 { 150 ptw32_cond_list_tail->next = cv; 151 } 152 153 ptw32_cond_list_tail = cv; 154 155 if (ptw32_cond_list_head == NULL) 156 { 157 ptw32_cond_list_head = cv; 158 } 159 160 ptw32_mcs_lock_release(&node); 161 } 162 163 *cond = cv; 164 165 return result; 166 167} /* pthread_cond_init */ 168