Coverage Report

Created: 2025-11-16 06:25

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