Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL Core 4 : * Purpose: The library set-up/clean-up routines. 5 : * Author: Mateusz Loskot <mateusz@loskot.net> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2010, Mateusz Loskot <mateusz@loskot.net> 9 : * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #include "cpl_port.h" 15 : #include "gdal.h" 16 : #include "gdalpython.h" 17 : 18 : #include "cpl_conv.h" 19 : #include "cpl_error.h" 20 : #include "cpl_multiproc.h" 21 : #include "cpl_string.h" 22 : #include "ogr_api.h" 23 : 24 : static bool bInGDALGlobalDestructor = false; 25 : static bool bInGDALGlobalDestructorFromDLLMain = false; 26 : 27 : extern "C" int CPL_DLL GDALIsInGlobalDestructor(); 28 : extern "C" bool CPL_DLL GDALIsInGlobalDestructorFromDLLMain(); 29 : 30 5061 : int GDALIsInGlobalDestructor() 31 : { 32 5061 : return bInGDALGlobalDestructor; 33 : } 34 : 35 0 : bool GDALIsInGlobalDestructorFromDLLMain() 36 : { 37 0 : return bInGDALGlobalDestructorFromDLLMain; 38 : } 39 : 40 : void CPLFinalizeTLS(); 41 : 42 : static bool bGDALDestroyAlreadyCalled = FALSE; 43 : 44 : /************************************************************************/ 45 : /* GDALDestroy() */ 46 : /************************************************************************/ 47 : 48 : /** Finalize GDAL/OGR library. 49 : * 50 : * This function calls GDALDestroyDriverManager() and OGRCleanupAll() and 51 : * finalize Thread Local Storage variables. 52 : * 53 : * This function may be called by application code, since 54 : * it is no longer called automatically, on non-MSVC builds, due to ordering 55 : * problems with respect to automatic destruction of global C++ objects. 56 : * 57 : * Note: no GDAL/OGR code should be called after this call! 58 : * 59 : */ 60 : 61 548 : void GDALDestroy(void) 62 : { 63 548 : if (bGDALDestroyAlreadyCalled) 64 0 : return; 65 548 : bGDALDestroyAlreadyCalled = true; 66 : 67 548 : bInGDALGlobalDestructor = true; 68 : 69 : // logging/error handling may call GDALIsInGlobalDestructor() 70 548 : CPLDebug("GDAL", "In GDALDestroy - unloading GDAL shared library."); 71 : 72 548 : GDALDestroyDriverManager(); 73 : 74 548 : OGRCleanupAll(); 75 548 : GDALPythonFinalize(); 76 548 : bInGDALGlobalDestructor = false; 77 : 78 : /* See corresponding bug reports: */ 79 : /* https://trac.osgeo.org/gdal/ticket/6139 */ 80 : /* https://trac.osgeo.org/gdal/ticket/6868 */ 81 : /* Needed in case no driver manager has been instantiated. */ 82 548 : CPLFreeConfig(); 83 548 : CPLFinalizeTLS(); 84 548 : CPLCleanupErrorMutex(); 85 548 : CPLCleanupMasterMutex(); 86 : } 87 : 88 : /************************************************************************/ 89 : /* The library set-up/clean-up routines implemented with */ 90 : /* GNU C/C++ extensions. */ 91 : /* TODO: Is it Linux-only solution or Unix portable? */ 92 : /************************************************************************/ 93 : #ifdef __GNUC__ 94 : 95 : static void GDALInitialize() __attribute__((constructor)); 96 : 97 : /************************************************************************/ 98 : /* Called when GDAL is loaded by loader or by dlopen(), */ 99 : /* and before dlopen() returns. */ 100 : /************************************************************************/ 101 : 102 1805 : static void GDALInitialize() 103 : { 104 : // nothing to do 105 : // CPLDebug("GDAL", "Library loaded"); 106 : #ifdef DEBUG 107 1805 : const char *pszLocale = CPLGetConfigOption("GDAL_LOCALE", nullptr); 108 1805 : if (pszLocale) 109 0 : CPLsetlocale(LC_ALL, pszLocale); 110 : #endif 111 1805 : } 112 : 113 : #endif // __GNUC__ 114 : 115 : /************************************************************************/ 116 : /* The library set-up/clean-up routine implemented as DllMain entry */ 117 : /* point specific for Windows. */ 118 : /************************************************************************/ 119 : #ifdef _MSC_VER 120 : #ifndef CPL_DISABLE_DLL 121 : 122 : #include <windows.h> 123 : 124 : extern "C" int WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, 125 : LPVOID /* lpReserved */) 126 : { 127 : if (dwReason == DLL_PROCESS_ATTACH) 128 : { 129 : // nothing to do 130 : } 131 : else if (dwReason == DLL_THREAD_ATTACH) 132 : { 133 : // nothing to do 134 : } 135 : else if (dwReason == DLL_THREAD_DETACH) 136 : { 137 : ::CPLCleanupTLS(); 138 : } 139 : else if (dwReason == DLL_PROCESS_DETACH) 140 : { 141 : bInGDALGlobalDestructorFromDLLMain = true; 142 : GDALDestroy(); 143 : } 144 : 145 : return 1; // ignored for all reasons but DLL_PROCESS_ATTACH 146 : } 147 : 148 : #endif // CPL_DISABLE_DLL 149 : #endif // _MSC_VER