Coverage Report

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