⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pthreads.h

📁 MICO2.3.13 corba 环境平台
💻 H
📖 第 1 页 / 共 2 页
字号:
// -*- c++ -*-/* *  MICO --- an Open Source CORBA implementation *  Copyright (c) 1997-2008 by The Mico Team *  *  OSThread: An abstract Thread class for MICO *  Copyright (C) 1999 Andy Kersting & Andreas Schultz *  *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Library General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library 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 *  Library General Public License for more details. * *  You should have received a copy of the GNU Library General Public *  License along with this library; if not, write to the Free *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *  For more information, visit the MICO Home Page at *  http://www.mico.org/ * *  support for POSIX Draft 10ish Pthreads for Linux as developed by *  Xavier LeRoy@inria.fr * */#ifndef __OS_THREAD_PTHREADS_H__#define __OS_THREAD_PTHREADS_H__void _init ();//// Mutex//class CondVar;//!// \ingroup micomt//// The Mutex class is a simple synchronization object used to protect// critical sections.//class Mutex#ifdef DEBUG_NAMES    : public NamedObject#endif // DEBUG_NAMES{public:    friend class CondVar;    /*!     * \enum Attribute     *     * The Attribute enum defines a specific attribute for the Mutex     * class. An attribute may be either Normal or Recursive. A normal     * mutex may only be locked once by a thread. Attempts to lock it     * more than once will result in a deadlock. A recursive mutex may     * be locked multiple times by the same thread.     */    enum Attribute    {	Normal,	Recursive    };    /*!     * \enum ErrorType     *     * Error types associated with a mutex.     */    enum ErrorType    {	NoError,		//!< No error on the mutex	AlreadyLocked,		//!< The mutex is already locked.	TryAgain,		//!< Try locking again.	Invalid,		//!< Invalid mutex.	Fault,			//!< A fault occurred.	DeadLock,		//!< The operation would result in deadlock	UnknownError		//!< An unknown error occurred    };    //! \name Constructor/Destructor    //@{    Mutex(MICO_Boolean locked = FALSE, Attribute attr = Normal);    ~Mutex();    //@}    //! \name Mutex Operations    //@{    /*!     * The trylock method is used to sample the mutex to see if it     * is locked. If the mutex is not locked the thread will obtain     * the lock, returning true. Otherwise, an error condition will     * be returned, and the thread will not own the lock.     *     * \return  True if the thread obtains the lock.     */    MICO_ULong    trylock()    {	ErrorType ret = NoError;#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME (<< name ()) << ": Mutex::trylock ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	switch (pthread_mutex_trylock(&_mutex)) {	case 0:	    ret = MICOMT::Mutex::NoError;	    break;	case EBUSY:	    ret = MICOMT::Mutex::AlreadyLocked;	    break;	case EAGAIN:	    ret = MICOMT::Mutex::TryAgain;	    break;	case EINVAL:	    ret = MICOMT::Mutex::Invalid;	    break;	case EFAULT:	    ret = MICOMT::Mutex::Fault;	    break;	case EDEADLK:	    ret = MICOMT::Mutex::DeadLock;	    break;	default:	    ret = MICOMT::Mutex::UnknownError;	}	return ret;    }    /*!     * The lock method is used to lock the mutex. A thread locking     * the mutex will have ownership of the lock until it is unlocked.     * Any thread trying to subsequently lock the mutex will block     * until the owning thread has unlocked it.     */    void    lock()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": Mutex::lock ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG#ifdef SOLARIS_MUTEX	if (_rec) {	    if (_id == pthread_self()) {      // we already have the look		_cnt++;		return;	    }	    pthread_mutex_lock(&_mutex);	    assert(_cnt == 0);               // paranoia	    _id = pthread_self();	    _cnt = 1;	}	else {	    pthread_mutex_lock(&_mutex);	}#else // SOLARIS_MUTEX	pthread_mutex_lock(&_mutex);#endif // SOLARIS_MUTEX    }        /*!     * The unlock method is used to release the ownership of a mutex.     * Threads waiting on the locked mutex are re-woken and may attempt     * to lock the mutex themselves.     */    void    unlock()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": Mutex::unlock ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG#ifdef SOLARIS_MUTEX	if (_rec) {	    _cnt--;	    if (!_cnt) {		_id = 0;                    // hopefully 0 is not a valid thread id  		pthread_mutex_unlock(&_mutex);	    }	}	else {	    pthread_mutex_unlock(&_mutex);	}#else // SOLARIS_MUTEX	pthread_mutex_unlock(&_mutex);#endif // SOLARIS_MUTEX    }    //@}protected:    pthread_mutex_t _mutex;	//!< Pthread mutex object#ifdef SOLARIS_MUTEX    pthread_t _id;	//!< Id of thread which hold ownership    unsigned int _cnt;	//!< Counter of recursive mutex    unsigned int _rec;	//!< Is mutex recursive?#endif // SOLARIS_MUTEX};//// Conditional Variable///*! * \ingroup micomt * * A condition variable is a synchronization object that associates * a condition with a mutex. */class CondVar#ifdef DEBUG_NAMES    : public NamedObject#endif // DEBUG_NAMES{public:    //! \name Constructor/Destructor    //@{    CondVar(MICOMT::Mutex* mut);    ~CondVar();    //@}    //! \name Condition Variable Operations    //@{    /*!     * The wait method blocks the calling thread until it is woken     * up by another thread signalling or broadcasting to the condition     * variable.     *     * \return  True on success, false on failure     */    MICO_Boolean    wait()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": CondVar::wait ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	return (pthread_cond_wait(&_cond,&_mutex->_mutex) == 0);    };        /*!     * The timedwait method blocks the calling thread until it     * is woken up by another thread signalling or broadcasting to     * the condition variable. It can also be woken up after the     * elapsed time specified by tmout.     *     * \param tmout  Milliseconds to wait for a signal.     * \return  True on success, false on failure.     */    MICO_Boolean timedwait(MICO_ULong tmout);    /*!     * The broadcast method wakes up all threads waiting on the     * condition variable.     */    void broadcast()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": CondVar::broadcast ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	pthread_cond_broadcast(&_cond);    };        /*!     * The signal method wakes up exactly one thread waiting     * on the condition variable.     */    void signal()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": CondVar::signal ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	pthread_cond_signal(&_cond);    };    //@}protected:    pthread_cond_t  _cond;      //!< The pthread condition variable    MICOMT::Mutex* _mutex;	//!< The mutex which will condition use};//// reader/writer lock///*! * \ingroup micomt * * The RWLock class implements a mutex-like object that can be locked * for either reading or writing. */class RWLock#ifdef DEBUG_NAMES    : public NamedObject#endif // DEBUG_NAMES{public:    //! \name Constructor/Destructor    //@{    RWLock();    ~RWLock();    //@}    /*!     * The rdlock method locks the reading side of the lock.     */    void rdlock()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": RWLock::rdlock ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	pthread_rwlock_rdlock(&_rwlock);    }        /*!     * The wrlock method locks the writing side of the lock.     */    void wrlock()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": RWLock::wrlock ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	pthread_rwlock_wrlock(&_rwlock);    }        /*!     * The unlock method releases the lock.     */    void unlock()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": RWLock::unlock ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	pthread_rwlock_unlock(&_rwlock);    }private:    pthread_rwlock_t	_rwlock;	//!< The pthread read/write lock};//// Semaphore///*! * \ingroup micomt * * The semaphore class is a synchronization object. A semaphore is a * counter for resources shared between threads. */#if defined(HAVE_SEMAPHORE_H) && !(defined(__APPLE__) && defined(__MACH__))// the OS provides POSIX semaphore implementation// in semaphore.h header file// kcg: in the case of MacOS X 10.2 (Darwin 6.8) we have an issue with// POSIX semaphore initialization, so we use MICO's own semaphore// implementation on this platformclass Semaphore#ifdef DEBUG_NAMES    : public NamedObject#endif // DEBUG_NAMES{private:    sem_t _s;			//!< The system semaphorepublic:    /*!     * \enum ErrorType     *     * Error types associated with a semaphore.     */    enum ErrorType    {	NoError,		//!< No error on semaphore	NoPermission,		//!< Permission denied	TryAgain,		//!< Try again	SemInvalid,		//!< Invalide semaphore	Interrupted,		//!< Interrupted by signal	UnknownError		//!< Unknow error    };    //! \name Constructor/Destructor    //@{    Semaphore(unsigned int val = 0);    ~Semaphore();    //@}    //! \name Semaphore Operations    //@{    /*!     * The wait method waits until the semaphore count is non-zero,     * then decrement the count.     */    void    wait()    {#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME(<< name ()) << ": Semaphore::wait ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG	while (sem_wait(&_s) == EINTR) {	}    }    /*!     * If the semaphore count is zero, this method will not block.     * Instead it returns ErrorType::TryAgain.     */    Semaphore::ErrorType    trylock()    {	Semaphore::ErrorType ret = MICOMT::Semaphore::NoError;#ifdef MTDEBUG	if (MICO::Logger::IsLogged (MICO::Logger::Thread)) {	    __mtdebug_lock();	    MICO::Logger::Stream (MICO::Logger::Thread)		__NAME (<< name ()) << ": Semaphore::trylock ()" << endl;	    __mtdebug_unlock();	}#endif // MTDEBUG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -