cpl_multiproc.cpp

来自「用于读取TAB、MIF、SHP文件的类」· C++ 代码 · 共 1,036 行 · 第 1/3 页

CPP
1,036
字号
/********************************************************************** * $Id: cpl_multiproc.cpp,v 1.19 2006/03/02 11:31:35 dron Exp $ * * Project:  CPL - Common Portability Library * Purpose:  CPL Multi-Threading, and process handling portability functions. * Author:   Frank Warmerdam, warmerdam@pobox.com * ********************************************************************** * Copyright (c) 2002, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: *  * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  * DEALINGS IN THE SOFTWARE. ********************************************************************** * * $Log: cpl_multiproc.cpp,v $ * Revision 1.19  2006/03/02 11:31:35  dron * CPLCreateOrAcquireMutex() should return a value. * * Revision 1.18  2006/02/19 21:54:34  mloskot * [WINCE] Changes related to Windows CE port of CPL. Most changes are #ifdef wrappers. * * Revision 1.17  2006/01/25 19:52:25  fwarmerdam * default to avoiding as much mutex overhead as opposed if MUTEX_NONE defined * * Revision 1.16  2005/08/31 01:00:51  fwarmerdam * Fixed assert limits. * * Revision 1.15  2005/08/24 21:51:06  fwarmerdam * added CPLCleanupTLS * * Revision 1.14  2005/08/01 18:58:42  fwarmerdam * Fixed problem with _NP mutex initializer. * * Revision 1.13  2005/07/31 02:14:49  fwarmerdam * improved recursive mutex creation for pthreads, works on macosx now * * Revision 1.12  2005/07/18 15:34:11  fwarmerdam * Fixed papTLSList sizing. * * Revision 1.11  2005/07/08 18:17:52  fwarmerdam * complete TLS implementation for win32 * * Revision 1.10  2005/07/08 16:30:25  fwarmerdam * real implementation of TLS for pthreads * * Revision 1.9  2005/07/08 14:35:26  fwarmerdam * preliminary TLS support * * Revision 1.8  2005/05/23 16:00:33  fwarmerdam * Make sure that stub implementation of mutex support recursive holds. * * Revision 1.7  2005/05/23 06:40:40  fwarmerdam * fixed flaw in CPLCreateOrAcquireMutex, added mutex holder * * Revision 1.6  2005/05/20 19:19:00  fwarmerdam * added CPLCreateOrAcquireMutex() * * Revision 1.5  2005/04/26 20:52:10  fwarmerdam * use a typedef type for thread mains (for Sun port) * * Revision 1.4  2003/05/06 18:30:54  warmerda * fix unix createmutex to implicitly acquire it * * Revision 1.3  2003/04/23 04:36:54  warmerda * pthreads based implementation * * Revision 1.2  2002/07/11 19:36:34  warmerda * CPLCreateMutex() should implicitly acquire it, fix stub version * * Revision 1.1  2002/05/24 04:01:01  warmerda * New * **********************************************************************/#include "cpl_multiproc.h"#include "cpl_conv.h"#if !defined(WIN32CE)#  include <time.h>#else#  include <wce_time.h>#endifCPL_CVSID("$Id: cpl_multiproc.cpp,v 1.19 2006/03/02 11:31:35 dron Exp $");#if defined(CPL_MULTIPROC_STUB) && !defined(DEBUG)#  define MUTEX_NONE#endif/************************************************************************//*                           CPLMutexHolder()                           *//************************************************************************/CPLMutexHolder::CPLMutexHolder( void **phMutex, double dfWaitInSeconds,                                const char *pszFileIn,                                 int nLineIn ){#ifndef MUTEX_NONE    pszFile = pszFileIn;    nLine = nLineIn;#ifdef DEBUG_MUTEX    CPLDebug( "MH", "Request %p for pid %d at %d/%s",               *phMutex, CPLGetPID(), nLine, pszFile );#endif    if( !CPLCreateOrAcquireMutex( phMutex, dfWaitInSeconds ) )    {        CPLDebug( "CPLMutexHolder", "failed to acquire mutex!" );        hMutex = NULL;    }    else    {#ifdef DEBUG_MUTEX        CPLDebug( "MH", "Acquired %p for pid %d at %d/%s",                   *phMutex, CPLGetPID(), nLine, pszFile );#endif        hMutex = *phMutex;    }#endif /* ndef MUTEX_NONE */}/************************************************************************//*                          ~CPLMutexHolder()                           *//************************************************************************/CPLMutexHolder::~CPLMutexHolder(){#ifndef MUTEX_NONE    if( hMutex != NULL )    {#ifdef DEBUG_MUTEX        CPLDebug( "MH", "Release %p for pid %d at %d/%s",                   hMutex, CPLGetPID(), nLine, pszFile );#endif        CPLReleaseMutex( hMutex );    }#endif /* ndef MUTEX_NONE */}/************************************************************************//*                      CPLCreateOrAcquireMutex()                       *//************************************************************************/int CPLCreateOrAcquireMutex( void **phMutex, double dfWaitInSeconds ){#ifndef MUTEX_NONE    static void *hCOAMutex = NULL;    /*    ** ironically, creation of this initial mutex is not threadsafe    ** even though we use it to ensure that creation of other mutexes    ** is threadsafe.     */    if( hCOAMutex == NULL )    {        hCOAMutex = CPLCreateMutex();    }    else    {        CPLAcquireMutex( hCOAMutex, dfWaitInSeconds );    }    if( *phMutex == NULL )    {        *phMutex = CPLCreateMutex();        CPLReleaseMutex( hCOAMutex );        return TRUE;    }    else    {        CPLReleaseMutex( hCOAMutex );        int bSuccess = CPLAcquireMutex( *phMutex, dfWaitInSeconds );                return bSuccess;    }#endif /* ndef MUTEX_NONE */    return TRUE;}/************************************************************************//*                        CPLCleanupTLSList()                           *//*                                                                      *//*      Free resources associated with a TLS vector (implementation     *//*      independent).                                                   *//************************************************************************/static void CPLCleanupTLSList( void **papTLSList ){    int i;//    printf( "CPLCleanupTLSList(%p)\n", papTLSList );        if( papTLSList == NULL )        return;    for( i = 0; i < CTLS_MAX; i++ )    {        if( papTLSList[i] != NULL && papTLSList[i+CTLS_MAX] != NULL )        {            CPLFree( papTLSList[i] );        }    }    CPLFree( papTLSList );}#ifdef CPL_MULTIPROC_STUB/************************************************************************//* ==================================================================== *//*                        CPL_MULTIPROC_STUB                            *//*                                                                      *//*      Stub implementation.  Mutexes don't provide exclusion, file     *//*      locking is achieved with extra "lock files", and thread         *//*      creation doesn't work.  The PID is always just one.             *//* ==================================================================== *//************************************************************************//************************************************************************//*                        CPLGetThreadingModel()                        *//************************************************************************/const char *CPLGetThreadingModel(){    return "stub";}/************************************************************************//*                           CPLCreateMutex()                           *//************************************************************************/void *CPLCreateMutex(){#ifndef MUTEX_NONE    unsigned char *pabyMutex = (unsigned char *) CPLMalloc( 4 );    pabyMutex[0] = 1;    pabyMutex[1] = 'r';    pabyMutex[2] = 'e';    pabyMutex[3] = 'd';    return (void *) pabyMutex;#else    return (void *) 0xdeadbeef;#endif }/************************************************************************//*                          CPLAcquireMutex()                           *//************************************************************************/int CPLAcquireMutex( void *hMutex, double dfWaitInSeconds ){#ifndef MUTEX_NONE    unsigned char *pabyMutex = (unsigned char *) hMutex;    CPLAssert( pabyMutex[1] == 'r' && pabyMutex[2] == 'e'                && pabyMutex[3] == 'd' );    pabyMutex[0] += 1;    return TRUE;#else    return TRUE;#endif}/************************************************************************//*                          CPLReleaseMutex()                           *//************************************************************************/void CPLReleaseMutex( void *hMutex ){#ifndef MUTEX_NONE    unsigned char *pabyMutex = (unsigned char *) hMutex;    CPLAssert( pabyMutex[1] == 'r' && pabyMutex[2] == 'e'                && pabyMutex[3] == 'd' );    if( pabyMutex[0] < 1 )        CPLDebug( "CPLMultiProc",                   "CPLReleaseMutex() called on mutex with %d as ref count!",                  pabyMutex[0] );    pabyMutex[0] -= 1;#endif}/************************************************************************//*                          CPLDestroyMutex()                           *//************************************************************************/void CPLDestroyMutex( void *hMutex ){#ifndef MUTEX_NONE    unsigned char *pabyMutex = (unsigned char *) hMutex;    CPLAssert( pabyMutex[1] == 'r' && pabyMutex[2] == 'e'                && pabyMutex[3] == 'd' );    CPLFree( pabyMutex );#endif}/************************************************************************//*                            CPLLockFile()                             *//*                                                                      *//*      Lock a file.  This implementation has a terrible race           *//*      condition.  If we don't succeed in opening the lock file, we    *//*      assume we can create one and own the target file, but other     *//*      processes might easily try creating the target file at the      *//*      same time, overlapping us.  Death!  Mayhem!  The traditional    *//*      solution is to use open() with _O_CREAT|_O_EXCL but this        *//*      function and these arguments aren't trivially portable.         *//*      Also, this still leaves a race condition on NFS drivers         *//*      (apparently).                                                   *//************************************************************************/

⌨️ 快捷键说明

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