/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: mutex.c,v $ * $Revision: 1.15 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "system.h" #include #include #include #include #if defined LINUX /* bad hack */ int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int); #define pthread_mutexattr_settype pthread_mutexattr_setkind_np #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP #endif /* Implementation notes: oslMutex hides a pointer to the oslMutexImpl structure, which ist needed to manage recursive locks on a mutex. */ typedef struct _oslMutexImpl { pthread_mutex_t mutex; } oslMutexImpl; /*****************************************************************************/ /* osl_createMutex */ /*****************************************************************************/ oslMutex SAL_CALL osl_createMutex() { oslMutexImpl* pMutex = (oslMutexImpl*) malloc(sizeof(oslMutexImpl)); pthread_mutexattr_t aMutexAttr; int nRet=0; OSL_ASSERT(pMutex); if ( pMutex == 0 ) { return 0; } pthread_mutexattr_init(&aMutexAttr); nRet = pthread_mutexattr_settype(&aMutexAttr, PTHREAD_MUTEX_RECURSIVE); nRet = pthread_mutex_init(&(pMutex->mutex), &aMutexAttr); if ( nRet != 0 ) { OSL_TRACE("osl_createMutex : mutex init failed. Errno: %d; %s\n", nRet, strerror(nRet)); free(pMutex); pMutex = 0; } pthread_mutexattr_destroy(&aMutexAttr); return (oslMutex) pMutex; } /*****************************************************************************/ /* osl_destroyMutex */ /*****************************************************************************/ void SAL_CALL osl_destroyMutex(oslMutex Mutex) { oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; OSL_ASSERT(pMutex); if ( pMutex != 0 ) { int nRet=0; nRet = pthread_mutex_destroy(&(pMutex->mutex)); if ( nRet != 0 ) { OSL_TRACE("osl_destroyMutex : mutex destroy failed. Errno: %d; %s\n", nRet, strerror(nRet)); } free(pMutex); } return; } /*****************************************************************************/ /* osl_acquireMutex */ /*****************************************************************************/ sal_Bool SAL_CALL osl_acquireMutex(oslMutex Mutex) { oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; OSL_ASSERT(pMutex); if ( pMutex != 0 ) { int nRet=0; nRet = pthread_mutex_lock(&(pMutex->mutex)); if ( nRet != 0 ) { OSL_TRACE("osl_acquireMutex : mutex lock failed. Errno: %d; %s\n", nRet, strerror(nRet)); return sal_False; } return sal_True; } /* not initialized */ return sal_False; } /*****************************************************************************/ /* osl_tryToAcquireMutex */ /*****************************************************************************/ sal_Bool SAL_CALL osl_tryToAcquireMutex(oslMutex Mutex) { oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; OSL_ASSERT(pMutex); if ( pMutex ) { int nRet = 0; nRet = pthread_mutex_trylock(&(pMutex->mutex)); if ( nRet != 0 ) return sal_False; return sal_True; } /* not initialized */ return sal_False; } /*****************************************************************************/ /* osl_releaseMutex */ /*****************************************************************************/ sal_Bool SAL_CALL osl_releaseMutex(oslMutex Mutex) { oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; OSL_ASSERT(pMutex); if ( pMutex ) { int nRet=0; nRet = pthread_mutex_unlock(&(pMutex->mutex)); if ( nRet != 0 ) { OSL_TRACE("osl_releaseMutex : mutex unlock failed. Errno: %d; %s\n", nRet, strerror(nRet)); return sal_False; } return sal_True; } /* not initialized */ return sal_False; } /*****************************************************************************/ /* osl_getGlobalMutex */ /*****************************************************************************/ static oslMutexImpl globalMutexImpl; static void globalMutexInitImpl(void) { pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr) != 0 || pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) || pthread_mutex_init(&globalMutexImpl.mutex, &attr) != 0 || pthread_mutexattr_destroy(&attr) != 0) { abort(); } } oslMutex * SAL_CALL osl_getGlobalMutex() { /* necessary to get a "oslMutex *" */ static oslMutex globalMutex = (oslMutex) &globalMutexImpl; static pthread_once_t once = PTHREAD_ONCE_INIT; if (pthread_once(&once, &globalMutexInitImpl) != 0) { abort(); } return &globalMutex; }