1 /* 2 * pthread_mutex_trylock.c 3 * 4 * Description: 5 * This translation unit implements mutual exclusion (mutex) primitives. 6 * 7 * -------------------------------------------------------------------------- 8 * 9 * Pthreads-win32 - POSIX Threads Library for Win32 10 * Copyright(C) 1998 John E. Bossom 11 * Copyright(C) 1999,2005 Pthreads-win32 contributors 12 * 13 * Contact Email: rpj (at) callisto.canberra.edu.au 14 * 15 * The current list of contributors is contained 16 * in the file CONTRIBUTORS included with the source 17 * code distribution. The list can also be seen at the 18 * following World Wide Web location: 19 * http://sources.redhat.com/pthreads-win32/contributors.html 20 * 21 * This library is free software; you can redistribute it and/or 22 * modify it under the terms of the GNU Lesser General Public 23 * License as published by the Free Software Foundation; either 24 * version 2 of the License, or (at your option) any later version. 25 * 26 * This library is distributed in the hope that it will be useful, 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29 * Lesser General Public License for more details. 30 * 31 * You should have received a copy of the GNU Lesser General Public 32 * License along with this library in the file COPYING.LIB; 33 * if not, write to the Free Software Foundation, Inc., 34 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 35 */ 36 37 #include "pthread.h" 38 #include "implement.h" 39 40 41 int 42 pthread_mutex_trylock (pthread_mutex_t * mutex) 43 { 44 pthread_mutex_t mx; 45 int kind; 46 int result = 0; 47 48 /* 49 * Let the system deal with invalid pointers. 50 */ 51 52 /* 53 * We do a quick check to see if we need to do more work 54 * to initialise a static mutex. We check 55 * again inside the guarded section of ptw32_mutex_check_need_init() 56 * to avoid race conditions. 57 */ 58 if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) 59 { 60 if ((result = ptw32_mutex_check_need_init (mutex)) != 0) 61 { 62 return (result); 63 } 64 } 65 66 mx = *mutex; 67 kind = mx->kind; 68 69 if (kind >= 0) 70 { 71 /* Non-robust */ 72 if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ( 73 (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, 74 (PTW32_INTERLOCKED_LONG) 1, 75 (PTW32_INTERLOCKED_LONG) 0)) 76 { 77 if (kind != PTHREAD_MUTEX_NORMAL) 78 { 79 mx->recursive_count = 1; 80 mx->ownerThread = pthread_self (); 81 } 82 } 83 else 84 { 85 if (kind == PTHREAD_MUTEX_RECURSIVE && 86 pthread_equal (mx->ownerThread, pthread_self ())) 87 { 88 mx->recursive_count++; 89 } 90 else 91 { 92 result = EBUSY; 93 } 94 } 95 } 96 else 97 { 98 /* 99 * Robust types 100 * All types record the current owner thread. 101 * The mutex is added to a per thread list when ownership is acquired. 102 */ 103 pthread_t self; 104 ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent; 105 106 if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == 107 PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( 108 (PTW32_INTERLOCKED_LONGPTR)statePtr, 109 (PTW32_INTERLOCKED_LONG)0)) 110 { 111 return ENOTRECOVERABLE; 112 } 113 114 self = pthread_self(); 115 kind = -kind - 1; /* Convert to non-robust range */ 116 117 if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ( 118 (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, 119 (PTW32_INTERLOCKED_LONG) 1, 120 (PTW32_INTERLOCKED_LONG) 0)) 121 { 122 if (kind != PTHREAD_MUTEX_NORMAL) 123 { 124 mx->recursive_count = 1; 125 } 126 ptw32_robust_mutex_add(mutex, self); 127 } 128 else 129 { 130 if (PTHREAD_MUTEX_RECURSIVE == kind && 131 pthread_equal (mx->ownerThread, pthread_self ())) 132 { 133 mx->recursive_count++; 134 } 135 else 136 { 137 if (EOWNERDEAD == (result = ptw32_robust_mutex_inherit(mutex))) 138 { 139 mx->recursive_count = 1; 140 ptw32_robust_mutex_add(mutex, self); 141 } 142 else 143 { 144 if (0 == result) 145 { 146 result = EBUSY; 147 } 148 } 149 } 150 } 151 } 152 153 return (result); 154 } 155