Coverage Report

Created: 2025-06-13 06:29

/src/gdal/gcore/gdaldllmain.cpp
Line
Count
Source (jump to first uncovered line)
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
extern "C" int CPL_DLL GDALIsInGlobalDestructor();
26
27
int GDALIsInGlobalDestructor()
28
0
{
29
0
    return bInGDALGlobalDestructor;
30
0
}
31
32
void CPLFinalizeTLS();
33
34
static bool bGDALDestroyAlreadyCalled = FALSE;
35
36
/************************************************************************/
37
/*                           GDALDestroy()                              */
38
/************************************************************************/
39
40
/** Finalize GDAL/OGR library.
41
 *
42
 * This function calls GDALDestroyDriverManager() and OGRCleanupAll() and
43
 * finalize Thread Local Storage variables.
44
 *
45
 * Prior to GDAL 2.4.0, this function should normally be explicitly called by
46
 * application code if GDAL is dynamically linked (but that does not hurt),
47
 * since it was automatically called through
48
 * the unregistration mechanisms of dynamic library loading.
49
 *
50
 * Since GDAL 2.4.0, this function may be called by application code, since
51
 * it is no longer called automatically, on non-MSVC builds, due to ordering
52
 * problems with respect to automatic destruction of global C++ objects.
53
 *
54
 * Note: no GDAL/OGR code should be called after this call!
55
 *
56
 * @since GDAL 2.0
57
 */
58
59
void GDALDestroy(void)
60
0
{
61
0
    if (bGDALDestroyAlreadyCalled)
62
0
        return;
63
0
    bGDALDestroyAlreadyCalled = true;
64
65
0
    bInGDALGlobalDestructor = true;
66
67
    // logging/error handling may call GDALIsInGlobalDestructor()
68
0
    CPLDebug("GDAL", "In GDALDestroy - unloading GDAL shared library.");
69
70
0
    GDALDestroyDriverManager();
71
72
0
    OGRCleanupAll();
73
0
    GDALPythonFinalize();
74
0
    bInGDALGlobalDestructor = false;
75
76
    /* See corresponding bug reports: */
77
    /* https://trac.osgeo.org/gdal/ticket/6139 */
78
    /* https://trac.osgeo.org/gdal/ticket/6868 */
79
    /* Needed in case no driver manager has been instantiated. */
80
0
    CPLFreeConfig();
81
0
    CPLFinalizeTLS();
82
0
    CPLCleanupErrorMutex();
83
0
    CPLCleanupMasterMutex();
84
0
}
85
86
/************************************************************************/
87
/*  The library set-up/clean-up routines implemented with               */
88
/*  GNU C/C++ extensions.                                               */
89
/*  TODO: Is it Linux-only solution or Unix portable?                   */
90
/************************************************************************/
91
#ifdef __GNUC__
92
93
static void GDALInitialize() __attribute__((constructor));
94
95
/************************************************************************/
96
/* Called when GDAL is loaded by loader or by dlopen(),                 */
97
/* and before dlopen() returns.                                         */
98
/************************************************************************/
99
100
static void GDALInitialize()
101
6
{
102
    // nothing to do
103
    // CPLDebug("GDAL", "Library loaded");
104
6
#ifdef DEBUG
105
6
    const char *pszLocale = CPLGetConfigOption("GDAL_LOCALE", nullptr);
106
6
    if (pszLocale)
107
0
        CPLsetlocale(LC_ALL, pszLocale);
108
6
#endif
109
6
}
110
111
#endif  // __GNUC__
112
113
/************************************************************************/
114
/*  The library set-up/clean-up routine implemented as DllMain entry    */
115
/*  point specific for Windows.                                         */
116
/************************************************************************/
117
#ifdef _MSC_VER
118
#ifndef CPL_DISABLE_DLL
119
120
#include <windows.h>
121
122
extern "C" int WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason,
123
                              LPVOID /* lpReserved */)
124
{
125
    if (dwReason == DLL_PROCESS_ATTACH)
126
    {
127
        // nothing to do
128
    }
129
    else if (dwReason == DLL_THREAD_ATTACH)
130
    {
131
        // nothing to do
132
    }
133
    else if (dwReason == DLL_THREAD_DETACH)
134
    {
135
        ::CPLCleanupTLS();
136
    }
137
    else if (dwReason == DLL_PROCESS_DETACH)
138
    {
139
        GDALDestroy();
140
    }
141
142
    return 1;  // ignored for all reasons but DLL_PROCESS_ATTACH
143
}
144
145
#endif  // CPL_DISABLE_DLL
146
#endif  // _MSC_VER