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 + -
显示快捷键?