15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pthread_mutex_trylock.c 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Description: 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This translation unit implements mutual exclusion (mutex) primitives. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -------------------------------------------------------------------------- 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Pthreads-win32 - POSIX Threads Library for Win32 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright(C) 1998 John E. Bossom 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright(C) 1999,2005 Pthreads-win32 contributors 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contact Email: rpj@callisto.canberra.edu.au 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The current list of contributors is contained 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the file CONTRIBUTORS included with the source 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * code distribution. The list can also be seen at the 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * following World Wide Web location: 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://sources.redhat.com/pthreads-win32/contributors.html 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is free software; you can redistribute it and/or 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modify it under the terms of the GNU Lesser General Public 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License as published by the Free Software Foundation; either 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * version 2 of the License, or (at your option) any later version. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is distributed in the hope that it will be useful, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Lesser General Public License for more details. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You should have received a copy of the GNU Lesser General Public 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License along with this library in the file COPYING.LIB; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if not, write to the Free Software Foundation, Inc., 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pthread.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "implement.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pthread_mutex_trylock (pthread_mutex_t * mutex) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_mutex_t mx; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kind; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = 0; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Let the system deal with invalid pointers. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We do a quick check to see if we need to do more work 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to initialise a static mutex. We check 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * again inside the guarded section of ptw32_mutex_check_need_init() 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to avoid race conditions. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((result = ptw32_mutex_check_need_init (mutex)) != 0) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mx = *mutex; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kind = mx->kind; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kind >= 0) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Non-robust */ 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONG) 1, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONG) 0)) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kind != PTHREAD_MUTEX_NORMAL) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mx->recursive_count = 1; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mx->ownerThread = pthread_self (); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kind == PTHREAD_MUTEX_RECURSIVE && 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_equal (mx->ownerThread, pthread_self ())) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mx->recursive_count++; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = EBUSY; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Robust types 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All types record the current owner thread. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The mutex is added to a per thread list when ownership is acquired. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_t self; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONGPTR)statePtr, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONG)0)) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ENOTRECOVERABLE; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self = pthread_self(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kind = -kind - 1; /* Convert to non-robust range */ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ( 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONG) 1, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PTW32_INTERLOCKED_LONG) 0)) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kind != PTHREAD_MUTEX_NORMAL) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mx->recursive_count = 1; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_robust_mutex_add(mutex, self); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PTHREAD_MUTEX_RECURSIVE == kind && 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_equal (mx->ownerThread, pthread_self ())) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mx->recursive_count++; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (EOWNERDEAD == (result = ptw32_robust_mutex_inherit(mutex))) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mx->recursive_count = 1; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_robust_mutex_add(mutex, self); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == result) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = EBUSY; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 155