8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-01 08:03:02 +01:00
firebird-mirror/src/common/classes/init.cpp

167 lines
3.1 KiB
C++
Raw Normal View History

2008-01-23 16:55:21 +01:00
/*
* PROGRAM: Common Access Method
* MODULE: init.cpp
* DESCRIPTION: InstanceControl - class to control global ctors/dtors
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alexander Peshkoff
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2008 Alexander Peshkoff <peshkoff@mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "init.h"
#include "alloc.h"
// Setting this define helps (with AV at exit time) detect globals
// with destructors, declared not using InstanceControl.
// The reason for AV is that process memory pool (from where globals should allocate memory)
// is destoyed in atexit(), before destructors are called. Therefore each delete
// operator in destructor will cause AV.
#undef DEBUG_INIT
namespace
{
void cleanError()
{
#ifdef DEV_BUILD
// we do not have big choice in error reporting when running destructors
abort();
#endif
}
2008-01-23 16:55:21 +01:00
// This helps initialize globals, needed before regular ctors run
bool initDone = false;
void allClean()
{
Firebird::InstanceControl::destructors();
try
{
Firebird::StaticMutex::release();
}
2008-02-01 18:33:14 +01:00
catch (...)
{
cleanError();
}
2008-02-01 18:33:14 +01:00
try
{
Firebird::MemoryPool::cleanup();
}
2008-02-01 18:33:14 +01:00
catch (...)
{
cleanError();
}
2008-01-23 16:55:21 +01:00
}
#ifndef DEBUG_INIT
// This class with it's single instance ensures global cleanup
class Cleanup
{
public:
~Cleanup()
{
allClean();
}
};
Cleanup global;
#endif //DEBUG_INIT
void init()
{
if (initDone)
{
return;
}
2008-02-01 18:33:14 +01:00
Firebird::Mutex::initMutexes();
2008-01-23 16:55:21 +01:00
Firebird::MemoryPool::init();
Firebird::StaticMutex::create();
#ifdef DEBUG_INIT
atexit(allClean);
#endif //DEBUG_INIT
initDone = true;
}
}
namespace Firebird
{
InstanceControl* InstanceControl::instanceList = 0;
FPTR_VOID InstanceControl::gdsCleanup = 0;
InstanceControl::InstanceControl()
{
init();
next = instanceList;
instanceList = this;
}
void InstanceControl::destructors()
{
// Call gds__cleanup() if present
if (gdsCleanup)
{
try
{
gdsCleanup();
}
2008-02-01 18:33:14 +01:00
catch (...)
{
cleanError();
}
2008-01-23 16:55:21 +01:00
}
// Destroy global objects
for (InstanceControl* i = instanceList; i; i = i->next)
{
try
{
i->dtor();
}
2008-02-01 18:33:14 +01:00
catch (...)
{
cleanError();
}
2008-01-23 16:55:21 +01:00
}
}
void InstanceControl::registerGdsCleanup(FPTR_VOID cleanup)
{
fb_assert((!gdsCleanup) || (!cleanup));
gdsCleanup = cleanup;
}
Mutex* StaticMutex::mutex = 0;
2008-01-23 16:55:21 +01:00
void StaticMutex::create()
{
mutex = FB_NEW(*getDefaultMemoryPool()) Mutex;
2008-01-23 16:55:21 +01:00
}
void StaticMutex::release()
{
delete mutex;
}
}