dss源码分析1:OSMutex

来源:互联网 发布:什么软件收二手手机 编辑:程序博客网 时间:2024/06/18 11:03

OSMutex 内部通过当前线程id来判断是否多次锁定,fHolder记录的当前线程id, fHolderCount代表锁定次数。
RecursiveTryLock 如果没有锁定,直接锁定。如果已经锁定,直接退出。
OSMutexLocker内部维护了OSMutex指针,在构造函数锁定,在析构函数释放。实用时比较方便。

/* * * @APPLE_LICENSE_HEADER_START@ *  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved. *  * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. *  * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. *  * @APPLE_LICENSE_HEADER_END@ * *//*    File:       OSMutex.h    Contains:   Platform - independent mutex header. The implementation of this object                is platform - specific. Each platform must define an independent                OSMutex.h & OSMutex.cpp file.                                This file is for Mac OS X Server only    */#ifndef _OSMUTEX_H_#define _OSMUTEX_H_#include <stdlib.h>#include "SafeStdLib.h"#ifndef __Win32__#include <sys/errno.h>    #if __PTHREADS_MUTEXES__        #if __MacOSX__            #ifndef _POSIX_PTHREAD_H                #include <pthread.h>            #endif        #else            #include <pthread.h>        #endif        #include <unistd.h>            #else        #include "mymutex.h"    #endif#endif#include "OSHeaders.h"#include "OSThread.h"#include "MyAssert.h"class OSCond;class OSMutex{    public:        OSMutex();        ~OSMutex();        inline void Lock();        inline void Unlock();                // Returns true on successful grab of the lock, false on failure        inline Bool16 TryLock();    private:#ifdef __Win32__        CRITICAL_SECTION fMutex;                DWORD       fHolder;        UInt32      fHolderCount;        #elif !__PTHREADS_MUTEXES__        mymutex_t fMutex;#else        pthread_mutex_t fMutex;        // These two platforms don't implement pthreads recursive mutexes, so        // we have to do it manually        pthread_t   fHolder;        UInt32      fHolderCount;#endif#if __PTHREADS_MUTEXES__ || __Win32__               void        RecursiveLock();        void        RecursiveUnlock();        Bool16      RecursiveTryLock();#endif        friend class OSCond;};class   OSMutexLocker{    public:        OSMutexLocker(OSMutex *inMutexP) : fMutex(inMutexP) { if (fMutex != NULL) fMutex->Lock(); }        ~OSMutexLocker() {  if (fMutex != NULL) fMutex->Unlock(); }                void Lock()         { if (fMutex != NULL) fMutex->Lock(); }        void Unlock()       { if (fMutex != NULL) fMutex->Unlock(); }            private:        OSMutex*    fMutex;};void OSMutex::Lock(){#if __PTHREADS_MUTEXES__ || __Win32__    this->RecursiveLock();#else    mymutex_lock(fMutex);#endif //!__PTHREADS__}void OSMutex::Unlock(){#if __PTHREADS_MUTEXES__ || __Win32__    this->RecursiveUnlock();#else    mymutex_unlock(fMutex);#endif //!__PTHREADS__}Bool16 OSMutex::TryLock(){#if __PTHREADS_MUTEXES__ || __Win32__    return this->RecursiveTryLock();#else    return (Bool16)mymutex_try_lock(fMutex);#endif //!__PTHREADS__}#endif //_OSMUTEX_H_

/* * * @APPLE_LICENSE_HEADER_START@ *  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved. *  * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. *  * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. *  * @APPLE_LICENSE_HEADER_END@ * *//*    File:       OSMutex.cpp    Contains:   Platform - independent mutex header. The implementation of this object                is platform - specific. Each platform must define an independent                QTSSMutex.h & QTSSMutex.cpp file.                                This file is for Mac OS X Server only    */#include "OSMutex.h"#include <stdlib.h>#include "SafeStdLib.h"#include <string.h>// Private globals#if __PTHREADS_MUTEXES__    static pthread_mutexattr_t  *sMutexAttr=NULL;    static void MutexAttrInit();        #if __solaris__            static pthread_once_t sMutexAttrInit = {PTHREAD_ONCE_INIT};    #else            static pthread_once_t sMutexAttrInit = PTHREAD_ONCE_INIT;    #endif    #endifOSMutex::OSMutex(){#ifdef __Win32__    ::InitializeCriticalSection(&fMutex);    fHolder = 0;    fHolderCount = 0;#elif __PTHREADS_MUTEXES__    (void)pthread_once(&sMutexAttrInit, MutexAttrInit);    (void)pthread_mutex_init(&fMutex, sMutexAttr);        fHolder = 0;    fHolderCount = 0;#else    fMutex = mymutex_alloc();#endif}#if __PTHREADS_MUTEXES__void MutexAttrInit(){    sMutexAttr = (pthread_mutexattr_t*)malloc(sizeof(pthread_mutexattr_t));    ::memset(sMutexAttr, 0, sizeof(pthread_mutexattr_t));    pthread_mutexattr_init(sMutexAttr);}#endifOSMutex::~OSMutex(){#ifdef __Win32__    ::DeleteCriticalSection(&fMutex);#elif __PTHREADS_MUTEXES__    pthread_mutex_destroy(&fMutex);#else    mymutex_free(fMutex);#endif}#if __PTHREADS_MUTEXES__ || __Win32__void        OSMutex::RecursiveLock(){    // We already have this mutex. Just refcount and return    if (OSThread::GetCurrentThreadID() == fHolder)    {        fHolderCount++;        return;    }#ifdef __Win32__    ::EnterCriticalSection(&fMutex);#else    (void)pthread_mutex_lock(&fMutex);#endif    Assert(fHolder == 0);    fHolder = OSThread::GetCurrentThreadID();    fHolderCount++;    Assert(fHolderCount == 1);}void        OSMutex::RecursiveUnlock(){    if (OSThread::GetCurrentThreadID() != fHolder)        return;            Assert(fHolderCount > 0);    fHolderCount--;    if (fHolderCount == 0)    {        fHolder = 0;#ifdef __Win32__        ::LeaveCriticalSection(&fMutex);#else        pthread_mutex_unlock(&fMutex);#endif    }}Bool16      OSMutex::RecursiveTryLock(){    // We already have this mutex. Just refcount and return    if (OSThread::GetCurrentThreadID() == fHolder)    {        fHolderCount++;        return true;    }#ifdef __Win32__    Bool16 theErr = (Bool16)::TryEnterCriticalSection(&fMutex); // Return values of this function match our API    if (!theErr)        return theErr;#else    int theErr = pthread_mutex_trylock(&fMutex);    if (theErr != 0)    {        Assert(theErr == EBUSY);        return false;    }#endif    Assert(fHolder == 0);    fHolder = OSThread::GetCurrentThreadID();    fHolderCount++;    Assert(fHolderCount == 1);    return true;}#endif //__PTHREADS_MUTEXES__ || __Win32__

0 0
原创粉丝点击