2004-03-14 14:10:40 +01:00
|
|
|
/*
|
2008-01-23 16:52:40 +01:00
|
|
|
* PROGRAM: Common Access Method
|
2004-03-14 14:10:40 +01:00
|
|
|
* MODULE: init.h
|
|
|
|
* DESCRIPTION: InitMutex, InitInstance - templates to help with initialization
|
|
|
|
*
|
|
|
|
* 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) 2004 Alexander Peshkoff <peshkoff@mail.ru>
|
|
|
|
* and all contributors signed below.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef CLASSES_INIT_INSTANCE_H
|
|
|
|
#define CLASSES_INIT_INSTANCE_H
|
|
|
|
|
2008-01-23 16:52:40 +01:00
|
|
|
#include "fb_types.h"
|
|
|
|
#include "../common/classes/alloc.h"
|
|
|
|
|
2004-03-14 14:10:40 +01:00
|
|
|
namespace Firebird {
|
|
|
|
|
2008-01-23 16:52:40 +01:00
|
|
|
// InstanceControl - interface for almost all global variables
|
|
|
|
|
|
|
|
class InstanceControl
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
InstanceControl();
|
|
|
|
static void destructors();
|
|
|
|
static void registerGdsCleanup(FPTR_VOID cleanup);
|
|
|
|
protected:
|
|
|
|
virtual void dtor() = 0;
|
|
|
|
private:
|
|
|
|
static InstanceControl* instanceList;
|
|
|
|
static FPTR_VOID gdsCleanup;
|
|
|
|
InstanceControl* next;
|
|
|
|
};
|
|
|
|
|
|
|
|
// GlobalPtr - template to help declaring global varables
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class GlobalPtr : private InstanceControl
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T* instance;
|
|
|
|
void dtor()
|
|
|
|
{
|
|
|
|
delete instance;
|
|
|
|
instance = 0;
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
GlobalPtr()
|
|
|
|
: InstanceControl()
|
|
|
|
{
|
|
|
|
instance = FB_NEW(*getDefaultMemoryPool()) T(*getDefaultMemoryPool());
|
2008-01-23 20:03:16 +01:00
|
|
|
// This means - for objects with ctors/dtors that want to be global,
|
2008-01-23 16:52:40 +01:00
|
|
|
// provide ctor with MemoryPool& parameter. Even if it is ignored!
|
|
|
|
}
|
2008-01-31 11:53:18 +01:00
|
|
|
T* operator->() throw()
|
2008-01-23 16:52:40 +01:00
|
|
|
{
|
|
|
|
return instance;
|
|
|
|
}
|
2008-01-31 11:53:18 +01:00
|
|
|
operator T&() throw()
|
2008-01-23 16:52:40 +01:00
|
|
|
{
|
|
|
|
return *instance;
|
|
|
|
}
|
2008-01-31 11:53:18 +01:00
|
|
|
T* operator&() throw()
|
2008-01-23 16:52:40 +01:00
|
|
|
{
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
bool operator!() const throw()
|
|
|
|
{
|
|
|
|
return instance ? false : true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Support for common mutex for various inits
|
|
|
|
|
|
|
|
class StaticMutex
|
|
|
|
{
|
|
|
|
protected:
|
2008-02-05 09:21:18 +01:00
|
|
|
static Mutex* mutex;
|
2008-01-23 16:52:40 +01:00
|
|
|
public:
|
|
|
|
static void create();
|
|
|
|
static void release();
|
|
|
|
};
|
|
|
|
|
2004-03-14 14:10:40 +01:00
|
|
|
// InitMutex - executes static void C::init() once and only once
|
|
|
|
|
|
|
|
template <typename C>
|
2008-01-23 16:52:40 +01:00
|
|
|
class InitMutex : private StaticMutex
|
|
|
|
{
|
2004-03-14 14:10:40 +01:00
|
|
|
private:
|
|
|
|
volatile bool flag;
|
|
|
|
public:
|
2008-01-23 16:52:40 +01:00
|
|
|
InitMutex()
|
|
|
|
: flag(false) { }
|
|
|
|
void init()
|
|
|
|
{
|
2004-03-14 14:10:40 +01:00
|
|
|
if (!flag) {
|
2008-02-05 09:21:18 +01:00
|
|
|
MutexLockGuard guard(*mutex);
|
2008-02-04 12:59:42 +01:00
|
|
|
if (!flag) {
|
|
|
|
C::init();
|
|
|
|
flag = true;
|
2006-05-20 05:55:54 +02:00
|
|
|
}
|
2004-03-14 14:10:40 +01:00
|
|
|
}
|
|
|
|
}
|
2008-01-23 16:52:40 +01:00
|
|
|
void cleanup()
|
|
|
|
{
|
2004-06-08 15:41:08 +02:00
|
|
|
if (flag) {
|
2008-02-05 09:21:18 +01:00
|
|
|
MutexLockGuard guard(*mutex);
|
2008-02-04 12:59:42 +01:00
|
|
|
if (flag) {
|
|
|
|
C::cleanup();
|
|
|
|
flag = false;
|
2004-06-08 15:41:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-03-14 14:10:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// InitInstance - initialize pointer to class once and only once,
|
|
|
|
// DefaultInit uses default memory pool for it.
|
|
|
|
|
|
|
|
template <typename T>
|
2008-01-23 16:52:40 +01:00
|
|
|
class DefaultInit
|
|
|
|
{
|
2004-03-14 14:10:40 +01:00
|
|
|
public:
|
2008-01-23 16:52:40 +01:00
|
|
|
static T* init()
|
|
|
|
{
|
2004-03-14 14:10:40 +01:00
|
|
|
return FB_NEW(*getDefaultMemoryPool()) T(*getDefaultMemoryPool());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T,
|
2008-01-23 16:52:40 +01:00
|
|
|
typename I = DefaultInit<T> >
|
|
|
|
class InitInstance : private StaticMutex
|
|
|
|
{
|
2004-03-14 14:10:40 +01:00
|
|
|
private:
|
|
|
|
T* instance;
|
|
|
|
volatile bool flag;
|
|
|
|
public:
|
2008-01-23 16:52:40 +01:00
|
|
|
InitInstance()
|
|
|
|
: flag(false) { }
|
|
|
|
T& operator()()
|
|
|
|
{
|
2004-03-14 14:10:40 +01:00
|
|
|
if (!flag) {
|
2008-02-05 09:21:18 +01:00
|
|
|
MutexLockGuard guard(*mutex);
|
2008-02-04 12:59:42 +01:00
|
|
|
if (!flag) {
|
|
|
|
instance = I::init();
|
|
|
|
flag = true;
|
2004-03-14 14:10:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return *instance;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} //namespace Firebird
|
|
|
|
|
|
|
|
#endif // CLASSES_INIT_INSTANCE_H
|
|
|
|
|