1*7836SJohn.Forte@Sun.COM /* 2*7836SJohn.Forte@Sun.COM * CDDL HEADER START 3*7836SJohn.Forte@Sun.COM * 4*7836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 5*7836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 6*7836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 7*7836SJohn.Forte@Sun.COM * 8*7836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*7836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 11*7836SJohn.Forte@Sun.COM * and limitations under the License. 12*7836SJohn.Forte@Sun.COM * 13*7836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*7836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*7836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*7836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*7836SJohn.Forte@Sun.COM * 19*7836SJohn.Forte@Sun.COM * CDDL HEADER END 20*7836SJohn.Forte@Sun.COM */ 21*7836SJohn.Forte@Sun.COM /* 22*7836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7836SJohn.Forte@Sun.COM * Use is subject to license terms. 24*7836SJohn.Forte@Sun.COM */ 25*7836SJohn.Forte@Sun.COM 26*7836SJohn.Forte@Sun.COM 27*7836SJohn.Forte@Sun.COM 28*7836SJohn.Forte@Sun.COM #include "Lockable.h" 29*7836SJohn.Forte@Sun.COM #include <iostream> 30*7836SJohn.Forte@Sun.COM #include <cstdio> 31*7836SJohn.Forte@Sun.COM #include <cerrno> 32*7836SJohn.Forte@Sun.COM #include <unistd.h> 33*7836SJohn.Forte@Sun.COM 34*7836SJohn.Forte@Sun.COM using namespace std; 35*7836SJohn.Forte@Sun.COM 36*7836SJohn.Forte@Sun.COM #define DEADLOCK_WARNING 10 37*7836SJohn.Forte@Sun.COM #define LOCK_SLEEP 1 38*7836SJohn.Forte@Sun.COM 39*7836SJohn.Forte@Sun.COM /** 40*7836SJohn.Forte@Sun.COM * @memo Create a lockable instance and initialize internal locks 41*7836SJohn.Forte@Sun.COM */ Lockable()42*7836SJohn.Forte@Sun.COMLockable::Lockable() { 43*7836SJohn.Forte@Sun.COM if (pthread_mutex_init(&mutex, NULL)) { 44*7836SJohn.Forte@Sun.COM } 45*7836SJohn.Forte@Sun.COM } 46*7836SJohn.Forte@Sun.COM 47*7836SJohn.Forte@Sun.COM /** 48*7836SJohn.Forte@Sun.COM * @memo Free up a lockable instance 49*7836SJohn.Forte@Sun.COM */ ~Lockable()50*7836SJohn.Forte@Sun.COMLockable::~Lockable() { 51*7836SJohn.Forte@Sun.COM if (pthread_mutex_destroy(&mutex)) { 52*7836SJohn.Forte@Sun.COM } 53*7836SJohn.Forte@Sun.COM } 54*7836SJohn.Forte@Sun.COM 55*7836SJohn.Forte@Sun.COM /** 56*7836SJohn.Forte@Sun.COM * @memo Unlock the instance 57*7836SJohn.Forte@Sun.COM * @precondition This thread must have locked the instance 58*7836SJohn.Forte@Sun.COM * @postcondition The instance will be unlocked 59*7836SJohn.Forte@Sun.COM */ unlock()60*7836SJohn.Forte@Sun.COMvoid Lockable::unlock() { 61*7836SJohn.Forte@Sun.COM unlock(&mutex); 62*7836SJohn.Forte@Sun.COM } 63*7836SJohn.Forte@Sun.COM 64*7836SJohn.Forte@Sun.COM /** 65*7836SJohn.Forte@Sun.COM * @memo Unlock a given mutex lock 66*7836SJohn.Forte@Sun.COM * @precondition The lock must be held by this thread 67*7836SJohn.Forte@Sun.COM * @postcondition The lock will be released 68*7836SJohn.Forte@Sun.COM * @param myMutex The lock to unlock 69*7836SJohn.Forte@Sun.COM */ unlock(pthread_mutex_t * myMutex)70*7836SJohn.Forte@Sun.COMvoid Lockable::unlock(pthread_mutex_t *myMutex) { 71*7836SJohn.Forte@Sun.COM pthread_mutex_unlock(myMutex); 72*7836SJohn.Forte@Sun.COM } 73*7836SJohn.Forte@Sun.COM 74*7836SJohn.Forte@Sun.COM /** 75*7836SJohn.Forte@Sun.COM * @memo Lock the instance 76*7836SJohn.Forte@Sun.COM * @postcondition The lock will be held by this thread. 77*7836SJohn.Forte@Sun.COM */ lock()78*7836SJohn.Forte@Sun.COMvoid Lockable::lock() { 79*7836SJohn.Forte@Sun.COM lock(&mutex); 80*7836SJohn.Forte@Sun.COM } 81*7836SJohn.Forte@Sun.COM 82*7836SJohn.Forte@Sun.COM /** 83*7836SJohn.Forte@Sun.COM * @memo Lock the given mutex lock 84*7836SJohn.Forte@Sun.COM * @postcondition The lock will be held by this thread 85*7836SJohn.Forte@Sun.COM * @param myMutex The mutex lock to take 86*7836SJohn.Forte@Sun.COM */ lock(pthread_mutex_t * myMutex)87*7836SJohn.Forte@Sun.COMvoid Lockable::lock(pthread_mutex_t *myMutex) { 88*7836SJohn.Forte@Sun.COM int status; 89*7836SJohn.Forte@Sun.COM int loop = 0; 90*7836SJohn.Forte@Sun.COM do { 91*7836SJohn.Forte@Sun.COM loop++; 92*7836SJohn.Forte@Sun.COM status = pthread_mutex_trylock(myMutex); 93*7836SJohn.Forte@Sun.COM if (status) { 94*7836SJohn.Forte@Sun.COM switch (pthread_mutex_trylock(myMutex)) { 95*7836SJohn.Forte@Sun.COM case EFAULT: 96*7836SJohn.Forte@Sun.COM cerr << "Lock failed: Fault" << endl; 97*7836SJohn.Forte@Sun.COM break; 98*7836SJohn.Forte@Sun.COM case EINVAL: 99*7836SJohn.Forte@Sun.COM cerr << "Lock failed: Invalid" << endl; 100*7836SJohn.Forte@Sun.COM break; 101*7836SJohn.Forte@Sun.COM case EBUSY: 102*7836SJohn.Forte@Sun.COM if (loop > DEADLOCK_WARNING) { 103*7836SJohn.Forte@Sun.COM cerr << "Lock failed: Deadlock" << endl; 104*7836SJohn.Forte@Sun.COM } 105*7836SJohn.Forte@Sun.COM break; 106*7836SJohn.Forte@Sun.COM case EOWNERDEAD: 107*7836SJohn.Forte@Sun.COM cerr << "Lock failed: Owner died" << endl; 108*7836SJohn.Forte@Sun.COM break; 109*7836SJohn.Forte@Sun.COM case ELOCKUNMAPPED: 110*7836SJohn.Forte@Sun.COM cerr << "Lock failed: Unmapped" << endl; 111*7836SJohn.Forte@Sun.COM break; 112*7836SJohn.Forte@Sun.COM case ENOTRECOVERABLE: 113*7836SJohn.Forte@Sun.COM cerr << "Lock failed: not recoverable" << endl; 114*7836SJohn.Forte@Sun.COM default: 115*7836SJohn.Forte@Sun.COM if (loop > DEADLOCK_WARNING) { 116*7836SJohn.Forte@Sun.COM cerr << "Lock failed: " <<strerror(status) << endl; 117*7836SJohn.Forte@Sun.COM break; 118*7836SJohn.Forte@Sun.COM } 119*7836SJohn.Forte@Sun.COM } 120*7836SJohn.Forte@Sun.COM } else { 121*7836SJohn.Forte@Sun.COM break; // Lock taken succesfully 122*7836SJohn.Forte@Sun.COM } 123*7836SJohn.Forte@Sun.COM sleep(LOCK_SLEEP); 124*7836SJohn.Forte@Sun.COM } while (status); 125*7836SJohn.Forte@Sun.COM } 126