GDALDestroyDriverManager 분석

5681 단어
삶이 있으면 죽음이 있다. 싱글톤 대상인 GDALdriverManger가 있는 이상, 메일 함수가 종료되기 전에 삭제해야 한다.
앞에서 GDAL singleton의 클래식 오류는 DCLP의 모델을 분석했고 마지막으로 포인터poDM이 만들어진 유일한 대상을 가리켰다.new에서 나왔기 때문에 당연히 delete를 찾아야 합니다.마찬가지로 gdaldrivermanager에서.cpp 파일, 마지막 위치에서 함수 GDALDestroyDriverManager를 제공하여 마지막 청소를 완료합니다.주석은 다른 스레드가 GDAL 내부의 객체를 사용하고 있을 때 이 함수를 호출하지 말라고 알립니다.나는 물러나기 전에만 호출할 것이다.
/**
 * \brief Destroy the driver manager.
 *
 * Incidently unloads all managed drivers.
 *
 * NOTE: This function is not thread safe.  It should not be called while
 * other threads are actively using GDAL. 
 */

void CPL_STDCALL GDALDestroyDriverManager( void )

{
    // THREADSAFETY: We would like to lock the mutex here, but it 
    // needs to be reacquired within the destructor during driver
    // deregistration.
    if( poDM != NULL )
        delete poDM;
}

poDM도 이 파일의 시작에 정적 바늘로 정의됩니다.
static volatile GDALDriverManager        *poDM = NULL;

delete poDM은 GDALdriverManager의 분석 함수를 실행하게 할 수 있습니다. 분석 함수 코드를 보면 많은 작업을 했습니다.그래서 그런 GDALDestroyDriverManager 함수는 호출할 필요가 없다는 관점은 잘못된 것이다.
/************************************************************************/
/*                         ~GDALDriverManager()                         */
/*                                                                      */
/*      Eventually this should also likely clean up all open            */
/*      datasets.  Or perhaps the drivers that own them should do       */
/*      that in their destructor?                                       */
/************************************************************************/

GDALDriverManager::~GDALDriverManager()

{
/* -------------------------------------------------------------------- */
/*      Destroy the existing drivers.                                   */
/* -------------------------------------------------------------------- */
    while( GetDriverCount() > 0 )
    {
        GDALDriver      *poDriver = GetDriver(0);

        DeregisterDriver(poDriver);
        delete poDriver;
    }

    m_NameDriverMap.clear();

/* -------------------------------------------------------------------- */
/*      Cleanup local memory.                                           */
/* -------------------------------------------------------------------- */
    VSIFree( papoDrivers );
    VSIFree( pszHome );

/* -------------------------------------------------------------------- */
/*      Cleanup any Proxy related memory.                               */
/* -------------------------------------------------------------------- */
    PamCleanProxyDB();

/* -------------------------------------------------------------------- */
/*      Blow away all the finder hints paths.  We really shouldn't      */
/*      be doing all of them, but it is currently hard to keep track    */
/*      of those that actually belong to us.                            */
/* -------------------------------------------------------------------- */
    CPLFinderClean();
    CPLFreeConfig();

/* -------------------------------------------------------------------- */
/*      Cleanup any memory allocated by the OGRSpatialReference         */
/*      related subsystem.                                              */
/* -------------------------------------------------------------------- */
    OSRCleanup();

/* -------------------------------------------------------------------- */
/*      Cleanup VSIFileManager.                                         */
/* -------------------------------------------------------------------- */
    VSICleanupFileManager();

/* -------------------------------------------------------------------- */
/*      Cleanup thread local storage ... I hope the program is all      */
/*      done with GDAL/OGR!                                             */
/* -------------------------------------------------------------------- */
    CPLCleanupTLS();

/* -------------------------------------------------------------------- */
/*      Ensure the global driver manager pointer is NULLed out.         */
/* -------------------------------------------------------------------- */
    if( poDM == this )
        poDM = NULL;
}

이 분석 함수의 주석은 매우 이상한데driver의 분석 함수로 하여금 청소 업무를 맡게 해야 하는지 물었다.당연히 그래야지.이것 또한 의문을 가져온다. 이러한driver의 분석 함수는 그래도 한번 볼 필요가 있다.
공식 API Reference 문서를 보면 공유 구성원의 설명만 볼 수 있기 때문에 GDAL 내부의 작동 원리를 파악하려면 코드를 보는 것만이 유효하다.
http://www.gdal.org/classGDALDriverManager.html
delete poDriver는 GDALdriver 분석 함수를 호출합니다.
4
GDALDriver::~GDALDriver()

{
    if( pfnUnloadDriver != NULL )
        pfnUnloadDriver( this );
}
이 GDALdriver는 일반적인 C++ 멀티태스킹 방식을 사용하지 않았다. 즉, 서로 다른 드라이브는 서로 다른 하위 클래스로 이루어지고 함수 바늘을 사용하는 방식이다.전형적인 C 스타일!
GeoTiff 드라이브일 경우 geotiff로 호출됩니다.cpp 파일의 함수:
/************************************************************************/
/*                        GDALDeregister_GTiff()                        */
/************************************************************************/

void GDALDeregister_GTiff( GDALDriver * )

{
    CPLDebug( "GDAL", "GDALDeregister_GTiff() called." );
    CSVDeaccess( NULL );

#if defined(LIBGEOTIFF_VERSION) && LIBGEOTIFF_VERSION > 1150
    GTIFDeaccessCSV();
#endif
}
void GTIFDeaccessCSV()

{
    CSVDeaccess( NULL );
}

결과적으로 추적되어 드라이버는 청소할 유효한 코드가 없었다.GDALdriver의 분석 함수가 기본적으로 정리된 것을 제외하고는
정말 정리할 것이 없기 때문에 버그일지도 모른다는 허락을 받았다.당분간은 확실하지 않다. 나는 단지 이런 C 함수 바늘로 허함수를 대체하는 디자인이 도대체 얼마나 많은 이익을 가져올 수 있는지에 대해 의심을 표시할 뿐이다.

좋은 웹페이지 즐겨찾기