Coverage Report

Created: 2026-07-25 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/gcore/gdaldllmain.cpp
Line
Count
Source
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
int GDALIsInGlobalDestructor()
31
0
{
32
0
    return bInGDALGlobalDestructor;
33
0
}
34
35
bool GDALIsInGlobalDestructorFromDLLMain()
36
0
{
37
0
    return bInGDALGlobalDestructorFromDLLMain;
38
0
}
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
void GDALDestroy(void)
62
0
{
63
0
    if (bGDALDestroyAlreadyCalled)
64
0
        return;
65
0
    bGDALDestroyAlreadyCalled = true;
66
67
0
    bInGDALGlobalDestructor = true;
68
69
    // logging/error handling may call GDALIsInGlobalDestructor()
70
0
    CPLDebug("GDAL", "In GDALDestroy - unloading GDAL shared library.");
71
72
0
    GDALDestroyDriverManager();
73
74
0
    OGRCleanupAll();
75
0
    GDALPythonFinalize();
76
0
    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
0
    CPLFreeConfig();
83
0
    CPLFinalizeTLS();
84
0
    CPLCleanupErrorMutex();
85
0
    CPLCleanupMasterMutex();
86
0
}
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
static void GDALInitialize()
103
5
{
104
    // nothing to do
105
    // CPLDebug("GDAL", "Library loaded");
106
5
#ifdef DEBUG
107
5
    const char *pszLocale = CPLGetConfigOption("GDAL_LOCALE", nullptr);
108
5
    if (pszLocale)
109
0
        CPLsetlocale(LC_ALL, pszLocale);
110
5
#endif
111
5
}
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