diff options
Diffstat (limited to 'sal/osl/unx/conditn.cxx')
-rw-r--r-- | sal/osl/unx/conditn.cxx | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/sal/osl/unx/conditn.cxx b/sal/osl/unx/conditn.cxx new file mode 100644 index 000000000000..c6417bfb2f7a --- /dev/null +++ b/sal/osl/unx/conditn.cxx @@ -0,0 +1,360 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "sal/config.h" + +#include <assert.h> + +#include "system.h" +#include <sal/log.hxx> +#include <sal/types.h> + +#include <osl/conditn.h> +#include <osl/time.h> + + +typedef struct _oslConditionImpl +{ + pthread_cond_t m_Condition; + pthread_mutex_t m_Lock; + sal_Bool m_State; +} oslConditionImpl; + + +/*****************************************************************************/ +/* osl_createCondition */ +/*****************************************************************************/ +oslCondition SAL_CALL osl_createCondition() +{ + oslConditionImpl* pCond; + int nRet=0; + + pCond = (oslConditionImpl*) malloc(sizeof(oslConditionImpl)); + + if ( pCond == 0 ) + { + SAL_WARN("sal", "std::bad_alloc in C"); + return 0; + } + + pCond->m_State = sal_False; + + /* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */ + nRet = pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", + "pthread_cond_init failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + + free(pCond); + return 0; + } + + nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", + "pthread_mutex_init failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + + nRet = pthread_cond_destroy(&pCond->m_Condition); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_cond_destroy failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + + free(pCond); + pCond = 0; + } + + return (oslCondition)pCond; +} + +/*****************************************************************************/ +/* osl_destroyCondition */ +/*****************************************************************************/ +void SAL_CALL osl_destroyCondition(oslCondition Condition) +{ + oslConditionImpl* pCond; + int nRet = 0; + + if ( Condition ) + { + pCond = (oslConditionImpl*)Condition; + + nRet = pthread_cond_destroy(&pCond->m_Condition); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_cond_destroy failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + nRet = pthread_mutex_destroy(&pCond->m_Lock); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_mutex_destroy failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + + free(Condition); + } + + return; +} + +/*****************************************************************************/ +/* osl_setCondition */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_setCondition(oslCondition Condition) +{ + oslConditionImpl* pCond; + int nRet=0; + + assert(Condition); + pCond = (oslConditionImpl*)Condition; + + if ( pCond == 0 ) + { + return sal_False; + } + + nRet = pthread_mutex_lock(&pCond->m_Lock); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", + "pthread_mutex_lock failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + return sal_False; + } + + pCond->m_State = sal_True; + nRet = pthread_cond_broadcast(&pCond->m_Condition); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", + "pthread_cond_broadcast failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + return sal_False; + } + + nRet = pthread_mutex_unlock(&pCond->m_Lock); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", + "pthread_mutex_unlock failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + return sal_False; + } + + return sal_True; + +} + +/*****************************************************************************/ +/* osl_resetCondition */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition) +{ + oslConditionImpl* pCond; + int nRet=0; + + assert(Condition); + + pCond = (oslConditionImpl*)Condition; + + if ( pCond == 0 ) + { + return sal_False; + } + + nRet = pthread_mutex_lock(&pCond->m_Lock); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", + "pthread_mutex_lock failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + return sal_False; + } + + pCond->m_State = sal_False; + + nRet = pthread_mutex_unlock(&pCond->m_Lock); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", "pthread_mutex_unlock failed, errno " << nRet <<", \"" + << strerror(nRet) << '"'); + return sal_False; + } + + return sal_True; +} + +/*****************************************************************************/ +/* osl_waitCondition */ +/*****************************************************************************/ +oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout) +{ + oslConditionImpl* pCond; + int nRet=0; + oslConditionResult Result = osl_cond_result_ok; + + assert(Condition); + pCond = (oslConditionImpl*)Condition; + + if ( pCond == 0 ) + { + return osl_cond_result_error; + } + + nRet = pthread_mutex_lock(&pCond->m_Lock); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", "pthread_mutex_lock failed, errno " << nRet <<", \"" + << strerror(nRet) << '"'); + return osl_cond_result_error; + } + + if ( pTimeout ) + { + if ( ! pCond->m_State ) + { + int ret; + struct timeval tp; + struct timespec to; + + gettimeofday(&tp, NULL); + + SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds, + tp.tv_usec * 1000 + pTimeout->Nanosec ); + + /* spurious wake up prevention */ + do + { + ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to); + if ( ret != 0 ) + { + if ( ret == ETIME || ret == ETIMEDOUT ) + { + Result = osl_cond_result_timeout; + nRet = pthread_mutex_unlock(&pCond->m_Lock); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_mutex_unlock failed, errno " << nRet + << ", \"" << strerror(nRet) << '"'); + + return Result; + } + else if ( ret != EINTR ) + { + Result = osl_cond_result_error; + nRet = pthread_mutex_unlock(&pCond->m_Lock); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_mutex_unlock failed, errno " << nRet + << ", \"" << strerror(nRet) << '"'); + return Result; + } + } + } + while ( !pCond->m_State ); + } + } + else + { + while ( !pCond->m_State ) + { + nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock); + if ( nRet != 0 ) + { + SAL_WARN( + "sal", + "pthread_cond_wait failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + Result = osl_cond_result_error; + nRet = pthread_mutex_unlock(&pCond->m_Lock); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_mutex_unlock failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + + return Result; + } + } + } + + nRet = pthread_mutex_unlock(&pCond->m_Lock); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_mutex_unlock failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + + return Result; +} + +/*****************************************************************************/ +/* osl_checkCondition */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition) +{ + sal_Bool State; + oslConditionImpl* pCond; + int nRet=0; + + assert(Condition); + pCond = (oslConditionImpl*)Condition; + + if ( pCond == 0 ) + { + return sal_False; + } + + nRet = pthread_mutex_lock(&pCond->m_Lock); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_mutex_lock failed, errno " << nRet << ", \"" << strerror(nRet) + << '"'); + + State = pCond->m_State; + + nRet = pthread_mutex_unlock(&pCond->m_Lock); + SAL_WARN_IF( + nRet != 0, "sal", + "pthread_mutex_unlock failed, errno " << nRet << ", \"" + << strerror(nRet) << '"'); + + return State; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |