8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 18:43:02 +01:00

Used upgradeInterface() in a number of places.

Fixed memory leak when unloading module, related with upgraded interfaces.
Fixed timer on posix to be high resolution.
Better diagnostic in services.
This commit is contained in:
alexpeshkoff 2011-06-10 12:53:51 +00:00
parent 9d375fccfa
commit 40348295e1
42 changed files with 364 additions and 78 deletions

View File

@ -292,7 +292,7 @@ FB_DAEMON = $(BIN)/firebird$(EXEC_EXT)
# Per-library link rules # Per-library link rules
LINK_UDF = $(LIB_LINK) $(LIB_LINK_OPTIONS) $(call LIB_LINK_SONAME,$(1).$(SHRLIB_EXT)) $(UNDEF_FLAGS)\ LINK_UDF = $(LIB_LINK) $(LIB_LINK_OPTIONS) $(call LIB_LINK_SONAME,$(1).$(SHRLIB_EXT)) $(UNDEF_FLAGS)\
$(call LIB_LINK_RPATH,lib) -lm $(call LIB_LINK_RPATH,lib) $(SO_LINK_LIBS)
LINK_UDF_LIBS = $(THR_LIBS) -L$(LIB) -lib_util LINK_UDF_LIBS = $(THR_LIBS) -L$(LIB) -lib_util
LINK_IB_UTIL = $(LIB_LINK) $(LINK_IBUTIL_SYMBOLS) $(LIB_LINK_OPTIONS) $(UNDEF_FLAGS)\ LINK_IB_UTIL = $(LIB_LINK) $(LINK_IBUTIL_SYMBOLS) $(LIB_LINK_OPTIONS) $(UNDEF_FLAGS)\

View File

@ -793,6 +793,8 @@ dnl AC_CHECK_FUNCS(AO_compare_and_swap_full)
AC_COMPILE_IFELSE( AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#include <atomic_ops.h>]], [[AO_T x; AO_compare_and_swap_full(&x, 0, 0); return 0;]])], [AC_LANG_PROGRAM([[#include <atomic_ops.h>]], [[AO_T x; AO_compare_and_swap_full(&x, 0, 0); return 0;]])],
AC_DEFINE(HAVE_AO_COMPARE_AND_SWAP_FULL, 1, [Define this if AO_compare_and_swap_full() is defined in atomic_ops.h])) AC_DEFINE(HAVE_AO_COMPARE_AND_SWAP_FULL, 1, [Define this if AO_compare_and_swap_full() is defined in atomic_ops.h]))
AC_SEARCH_LIBS(clock_gettime, rt)
AC_CHECK_FUNCS(clock_gettime)
dnl Checks for pthread functions dnl Checks for pthread functions
AC_CHECK_FUNCS(pthread_mutexattr_setprotocol) AC_CHECK_FUNCS(pthread_mutexattr_setprotocol)

View File

@ -1460,6 +1460,8 @@ C --
PARAMETER (GDS__invalid_boolean_usage = 335545023) PARAMETER (GDS__invalid_boolean_usage = 335545023)
INTEGER*4 GDS__sysf_argscant_both_be_zero INTEGER*4 GDS__sysf_argscant_both_be_zero
PARAMETER (GDS__sysf_argscant_both_be_zero = 335545024) PARAMETER (GDS__sysf_argscant_both_be_zero = 335545024)
INTEGER*4 GDS__spb_no_id
PARAMETER (GDS__spb_no_id = 335545025)
INTEGER*4 GDS__gfix_db_name INTEGER*4 GDS__gfix_db_name
PARAMETER (GDS__gfix_db_name = 335740929) PARAMETER (GDS__gfix_db_name = 335740929)
INTEGER*4 GDS__gfix_invalid_sw INTEGER*4 GDS__gfix_invalid_sw

View File

@ -737,6 +737,7 @@ const
gds_cannot_copy_stmt = 335545022; gds_cannot_copy_stmt = 335545022;
gds_invalid_boolean_usage = 335545023; gds_invalid_boolean_usage = 335545023;
gds_sysf_argscant_both_be_zero = 335545024; gds_sysf_argscant_both_be_zero = 335545024;
gds_spb_no_id = 335545025;
gds_gfix_db_name = 335740929; gds_gfix_db_name = 335740929;
gds_gfix_invalid_sw = 335740930; gds_gfix_invalid_sw = 335740930;
gds_gfix_incmp_sw = 335740932; gds_gfix_incmp_sw = 335740932;

View File

@ -33,6 +33,8 @@
//#define AUTH_VERBOSE //#define AUTH_VERBOSE
static Firebird::MakeUpgradeInfo<> upInfo;
// register plugin // register plugin
static Firebird::SimpleFactory<Auth::DebugClient> clientFactory; static Firebird::SimpleFactory<Auth::DebugClient> clientFactory;
static Firebird::SimpleFactory<Auth::DebugServer> serverFactory; static Firebird::SimpleFactory<Auth::DebugServer> serverFactory;
@ -60,6 +62,7 @@ Result FB_CARG DebugServer::startAuthentication(Firebird::IStatus* status, bool
{ {
try try
{ {
Firebird::MasterInterfacePtr()->upgradeInterface(writerInterface, FB_AUTH_WRITER_VERSION, upInfo);
str.erase(); str.erase();
Firebird::ClumpletReader rdr(isService ? Firebird::ClumpletReader rdr(isService ?
Firebird::ClumpletReader::spbList : Firebird::ClumpletReader::spbList :
@ -88,6 +91,7 @@ Result FB_CARG DebugServer::contAuthentication(Firebird::IStatus* status, IWrite
#ifdef AUTH_VERBOSE #ifdef AUTH_VERBOSE
fprintf(stderr, "DebugServerInstance::contAuthentication: %.*s\n", size, data); fprintf(stderr, "DebugServerInstance::contAuthentication: %.*s\n", size, data);
#endif #endif
Firebird::MasterInterfacePtr()->upgradeInterface(writerInterface, FB_AUTH_WRITER_VERSION, upInfo);
writerInterface->add(Firebird::string((const char*) data, size).c_str(), "DEBUG", ""); writerInterface->add(Firebird::string((const char*) data, size).c_str(), "DEBUG", "");
return AUTH_SUCCESS; return AUTH_SUCCESS;
} }
@ -126,6 +130,7 @@ Result FB_CARG DebugClient::startAuthentication(Firebird::IStatus* status, bool
{ {
try try
{ {
Firebird::MasterInterfacePtr()->upgradeInterface(dpb, FB_AUTH_DPB_READER_VERSION, upInfo);
str = "HAND"; str = "HAND";
if (dpb) if (dpb)
{ {

View File

@ -42,6 +42,8 @@
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
#include "firebird/Plugin.h" #include "firebird/Plugin.h"
static Firebird::MakeUpgradeInfo<> upInfo;
// Here we use version-independent symbolic link (or copy) of actual database // Here we use version-independent symbolic link (or copy) of actual database
DATABASE database = STATIC FILENAME "security.fdb"; DATABASE database = STATIC FILENAME "security.fdb";
@ -124,6 +126,8 @@ void FB_CARG SecurityDatabaseManagement::start(Firebird::IStatus* st, ILogonInfo
{ {
try try
{ {
Firebird::MasterInterfacePtr()->upgradeInterface(logonInfo, FB_AUTH_LOGON_INFO_VERSION, upInfo);
st->init(); st->init();
if (secDbKey == INIT_KEY) if (secDbKey == INIT_KEY)
@ -310,6 +314,8 @@ int FB_CARG SecurityDatabaseManagement::execute(Firebird::IStatus* st, IUser* us
try try
{ {
Firebird::MasterInterfacePtr()->upgradeInterface(user, FB_AUTH_USER_VERSION, upInfo);
ISC_STATUS_ARRAY isc_status; ISC_STATUS_ARRAY isc_status;
fb_utils::init_status(isc_status); fb_utils::init_status(isc_status);
st->init(); st->init();
@ -668,12 +674,11 @@ int FB_CARG SecurityDatabaseManagement::execute(Firebird::IStatus* st, IUser* us
// register plugin // register plugin
static Firebird::SimpleFactory<Auth::SecurityDatabaseManagement> factory; static Firebird::SimpleFactory<Auth::SecurityDatabaseManagement> factory;
static Firebird::UnloadDetector unloadDetector;
extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master) extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
{ {
Firebird::PluginManagerInterfacePtr pi(master); Firebird::PluginManagerInterfacePtr pi(master);
pi->registerPluginFactory(Firebird::PluginType::AuthUserManagement, "Legacy_Auth", &factory); pi->registerPluginFactory(Firebird::PluginType::AuthUserManagement, "Legacy_Auth", &factory);
pi->registerModule(&unloadDetector); pi->registerModule(&Firebird::myModule);
} }

View File

@ -49,6 +49,8 @@ using namespace Firebird;
namespace { namespace {
MakeUpgradeInfo<> upInfo;
// BLR to search database for user name record // BLR to search database for user name record
const UCHAR PWD_REQUEST[] = const UCHAR PWD_REQUEST[] =
@ -367,6 +369,7 @@ Result SecurityDatabase::verify(IWriter* authBlock, ClumpletReader& originalDpb)
} }
} }
MasterInterfacePtr()->upgradeInterface(authBlock, FB_AUTH_WRITER_VERSION, upInfo);
authBlock->add(login.c_str(), "SecDB", secureDbName); authBlock->add(login.c_str(), "SecDB", secureDbName);
return AUTH_SUCCESS; return AUTH_SUCCESS;
} }
@ -517,7 +520,7 @@ Result SecurityDatabaseServer::startAuthentication(Firebird::IStatus* status,
ClumpletReader rdr(isService ? ClumpletReader::spbList : ClumpletReader::dpbList, dpb, dpbSize); ClumpletReader rdr(isService ? ClumpletReader::spbList : ClumpletReader::dpbList, dpb, dpbSize);
Result rc = instance->verify(writerInterface, rdr); Result rc = instance->verify(writerInterface, rdr);
Firebird::TimerInterfacePtr()->start(instance, 10 * 1000 * 1000); TimerInterfacePtr()->start(instance, 10 * 1000 * 1000);
return rc; return rc;
} }
catch (const Firebird::Exception& ex) catch (const Firebird::Exception& ex)

View File

@ -69,6 +69,8 @@ namespace
*data = name; *data = name;
*dataSize = strlen(name); *dataSize = strlen(name);
} }
MakeUpgradeInfo<> upInfo;
} }
namespace Auth { namespace Auth {
@ -380,6 +382,7 @@ Result WinSspiServer::contAuthentication(Firebird::IStatus* status,
bool wheel = false; bool wheel = false;
string login; string login;
sspi.getLogin(login, wheel); sspi.getLogin(login, wheel);
MasterInterfacePtr()->upgradeInterface(writerInterface, FB_AUTH_WRITER_VERSION, upInfo);
writerInterface->add(login.c_str(), "WIN_SSPI", ""); writerInterface->add(login.c_str(), "WIN_SSPI", "");
if (wheel) if (wheel)
{ {
@ -417,6 +420,8 @@ Result WinSspiClient::startAuthentication(Firebird::IStatus* status,
if (dpb) if (dpb)
{ {
MasterInterfacePtr()->upgradeInterface(dpb, FB_AUTH_DPB_READER_VERSION, upInfo);
UCHAR tag = isService ? isc_spb_trusted_role : isc_dpb_trusted_role; UCHAR tag = isService ? isc_spb_trusted_role : isc_dpb_trusted_role;
while (dpb->find(tag)) while (dpb->find(tag))
{ {

View File

@ -34,36 +34,27 @@
namespace Firebird { namespace Firebird {
// Default replacement for missing virtual functions
class DefaultMissingEntrypoint
{
public:
virtual void FB_CARG noEntrypoint()
{
Arg::Gds(isc_wish_list).raise();
}
};
// Template to help with loop in the set of plugins // Template to help with loop in the set of plugins
template <typename P, typename M = DefaultMissingEntrypoint> template <typename P>
class GetPlugins class GetPlugins
{ {
public: public:
GetPlugins(unsigned int interfaceType, unsigned int desiredVersion, const char* namesList = NULL) GetPlugins(unsigned int interfaceType, unsigned int desiredVersion,
: masterInterface(), pluginInterface(masterInterface), missing(), UpgradeInfo* ui, const char* namesList = NULL)
: masterInterface(), pluginInterface(masterInterface),
pluginSet(pluginInterface->getPlugins(interfaceType, namesList ? namesList : Config::getPlugins(interfaceType), pluginSet(pluginInterface->getPlugins(interfaceType, namesList ? namesList : Config::getPlugins(interfaceType),
desiredVersion, &missing, NULL)), desiredVersion, ui, NULL)),
currentPlugin(NULL) currentPlugin(NULL)
{ {
pluginSet->release(); pluginSet->release();
getPlugin(); getPlugin();
} }
GetPlugins(unsigned int interfaceType, unsigned int desiredVersion, GetPlugins(unsigned int interfaceType, unsigned int desiredVersion, UpgradeInfo* ui,
Config* knownConfig, const char* namesList = NULL) Config* knownConfig, const char* namesList = NULL)
: masterInterface(), pluginInterface(masterInterface), missing(), : masterInterface(), pluginInterface(masterInterface),
pluginSet(pluginInterface->getPlugins(interfaceType, namesList ? namesList : Config::getPlugins(interfaceType), pluginSet(pluginInterface->getPlugins(interfaceType, namesList ? namesList : Config::getPlugins(interfaceType),
desiredVersion, &missing, new FirebirdConf(knownConfig))), desiredVersion, ui, new FirebirdConf(knownConfig))),
currentPlugin(NULL) currentPlugin(NULL)
{ {
pluginSet->release(); pluginSet->release();
@ -124,7 +115,6 @@ public:
private: private:
MasterInterfacePtr masterInterface; MasterInterfacePtr masterInterface;
PluginManagerInterfacePtr pluginInterface; PluginManagerInterfacePtr pluginInterface;
M missing;
RefPtr<IPluginSet> pluginSet; RefPtr<IPluginSet> pluginSet;
P* currentPlugin; P* currentPlugin;

View File

@ -0,0 +1,34 @@
/*
* PROGRAM: Firebird interface.
* MODULE: ImplementHelper.cpp
* DESCRIPTION: Tools to help create interfaces.
*
* 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 Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2010 Alex Peshkov <peshkoff at mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*
*/
#include "../common/classes/ImplementHelper.h"
namespace Firebird
{
UnloadDetector myModule;
}

View File

@ -71,6 +71,8 @@ public:
return V; return V;
} }
IPluginModule* getModule();
private: private:
VersionedIface(const VersionedIface&); VersionedIface(const VersionedIface&);
VersionedIface& operator=(const VersionedIface&); VersionedIface& operator=(const VersionedIface&);
@ -249,7 +251,10 @@ public:
if (flagOsUnload) if (flagOsUnload)
{ {
PluginManagerInterfacePtr pi; PluginManagerInterfacePtr pi;
pi->unregisterModule(this); if (pi)
{
pi->unregisterModule(this);
}
doClean(); doClean();
} }
@ -282,6 +287,44 @@ private:
}; };
typedef GlobalPtr<UnloadDetectorHelper, InstanceControl::PRIORITY_DETECT_UNLOAD> UnloadDetector; typedef GlobalPtr<UnloadDetectorHelper, InstanceControl::PRIORITY_DETECT_UNLOAD> UnloadDetector;
extern UnloadDetector myModule;
template <class C, int V> IPluginModule* VersionedIface<C, V>::getModule()
{
return &myModule;
}
// Default replacement for missing virtual functions
class DefaultMissingEntrypoint
{
public:
virtual void FB_CARG noEntrypoint()
{
Arg::Gds(isc_wish_list).raise();
}
};
// Helps to create update information
template <typename M = DefaultMissingEntrypoint>
class MakeUpgradeInfo
{
public:
MakeUpgradeInfo()
{
ui.missingFunctionClass = &missing;
ui.clientModule = &myModule;
}
operator UpgradeInfo*()
{
return &ui;
}
private:
M missing;
struct UpgradeInfo ui;
};
class InternalMessageBuffer : public FbMessage class InternalMessageBuffer : public FbMessage

View File

@ -36,12 +36,14 @@ void raise()
(Arg::Gds(isc_random) << "Missing user management plugin").raise(); (Arg::Gds(isc_random) << "Missing user management plugin").raise();
} }
MakeUpgradeInfo<> ui;
} // anonymous namespace } // anonymous namespace
namespace Auth { namespace Auth {
Get::Get(Config* firebirdConf) Get::Get(Config* firebirdConf)
: GetPlugins<Auth::IManagement>(PluginType::AuthUserManagement, FB_AUTH_MANAGE_VERSION, firebirdConf) : GetPlugins<Auth::IManagement>(PluginType::AuthUserManagement, FB_AUTH_MANAGE_VERSION, ui, firebirdConf)
{ {
if (!hasData()) if (!hasData())
{ {

View File

@ -807,7 +807,7 @@ SINT64 query_performance_counter()
return counter.QuadPart; return counter.QuadPart;
#elif defined(HAVE_CLOCK_GETTIME) #elif defined(HAVE_CLOCK_GETTIME)
// Use high-resultion clock // Use high-resolution clock
struct timespec tp; struct timespec tp;
if (clock_gettime(CLOCK_REALTIME, &tp) != 0) if (clock_gettime(CLOCK_REALTIME, &tp) != 0)
return 0; return 0;

View File

@ -683,6 +683,11 @@ public:
return FB_MASTER_VERSION; return FB_MASTER_VERSION;
} }
virtual IPluginModule* FB_CARG getModule()
{
return NULL;
}
virtual IStatus* FB_CARG getStatus() virtual IStatus* FB_CARG getStatus()
{ {
fb_assert(false); fb_assert(false);
@ -697,12 +702,12 @@ public:
virtual IPluginManager* FB_CARG getPluginManager() virtual IPluginManager* FB_CARG getPluginManager()
{ {
fb_assert(false); //fb_assert(false);
return NULL; return NULL;
} }
virtual int FB_CARG upgradeInterface(IVersioned* /*toUpgrade*/, int /*desiredVersion*/, virtual int FB_CARG upgradeInterface(IVersioned* /*toUpgrade*/, int /*desiredVersion*/,
void* /*missingFunctionClass*/) struct UpgradeInfo* /*upInfo*/)
{ {
fb_assert(false); fb_assert(false);
return 0; return 0;

View File

@ -33,6 +33,7 @@
#include "./Plugin.h" #include "./Plugin.h"
#include "./Provider.h" #include "./Provider.h"
#include "firebird.h" //// FIXME:
namespace Firebird { namespace Firebird {

View File

@ -39,14 +39,18 @@
namespace Firebird { namespace Firebird {
// Forward declaration - used to identify client and provider of upgraded interface
class IPluginModule;
// Versioned interface - base for all FB interfaces // Versioned interface - base for all FB interfaces
class IVersioned class IVersioned
{ {
public: public:
virtual int FB_CARG getVersion() = 0; virtual int FB_CARG getVersion() = 0;
virtual IPluginModule* getModule() = 0;
}; };
// If this is changed, types of all interfaces must be changed // If this is changed, types of all interfaces must be changed
#define FB_VERSIONED_VERSION 1 #define FB_VERSIONED_VERSION 2
// Reference counted interface - base for refCounted FB interfaces // Reference counted interface - base for refCounted FB interfaces
class IRefCounted : public IVersioned class IRefCounted : public IVersioned
@ -89,6 +93,12 @@ class IAttachment;
class ITransaction; class ITransaction;
class IDtc; class IDtc;
struct UpgradeInfo
{
void* missingFunctionClass;
IPluginModule* clientModule;
};
// Master interface is used to access almost all other interfaces. // Master interface is used to access almost all other interfaces.
class IMaster : public IVersioned class IMaster : public IVersioned
{ {
@ -96,7 +106,8 @@ public:
virtual IStatus* FB_CARG getStatus() = 0; virtual IStatus* FB_CARG getStatus() = 0;
virtual IProvider* FB_CARG getDispatcher() = 0; virtual IProvider* FB_CARG getDispatcher() = 0;
virtual IPluginManager* FB_CARG getPluginManager() = 0; virtual IPluginManager* FB_CARG getPluginManager() = 0;
virtual int FB_CARG upgradeInterface(IVersioned* toUpgrade, int desiredVersion, void* missingFunctionClass) = 0; virtual int FB_CARG upgradeInterface(IVersioned* toUpgrade, int desiredVersion,
struct UpgradeInfo* upgradeInfo) = 0;
virtual const char* FB_CARG circularAlloc(const char* s, size_t len, intptr_t thr) = 0; virtual const char* FB_CARG circularAlloc(const char* s, size_t len, intptr_t thr) = 0;
virtual ITimerControl* FB_CARG getTimerControl() = 0; virtual ITimerControl* FB_CARG getTimerControl() = 0;
virtual IDtc* FB_CARG getDtc() = 0; virtual IDtc* FB_CARG getDtc() = 0;

View File

@ -187,7 +187,7 @@ public:
// If caller already has an interface for firebird.conf, it may be passed here // If caller already has an interface for firebird.conf, it may be passed here
// If parameter is missing, plugins will get access to default (non database specific) config // If parameter is missing, plugins will get access to default (non database specific) config
virtual IPluginSet* FB_CARG getPlugins(unsigned int interfaceType, const char* namesList, virtual IPluginSet* FB_CARG getPlugins(unsigned int interfaceType, const char* namesList,
int desiredVersion, void* missingFunctionClass, int desiredVersion, UpgradeInfo* ui,
IFirebirdConf* firebirdConf) = 0; IFirebirdConf* firebirdConf) = 0;
// Get generic config interface for given file // Get generic config interface for given file
virtual IConfig* FB_CARG getConfig(const char* filename) = 0; virtual IConfig* FB_CARG getConfig(const char* filename) = 0;

View File

@ -29,7 +29,6 @@
#ifndef FB_PROVIDER_INTERFACE #ifndef FB_PROVIDER_INTERFACE
#define FB_PROVIDER_INTERFACE #define FB_PROVIDER_INTERFACE
#include "firebird.h" //// FIXME:
#include "./Plugin.h" #include "./Plugin.h"
namespace Firebird { namespace Firebird {

View File

@ -726,6 +726,7 @@ static const struct {
{"cannot_copy_stmt", 335545022}, {"cannot_copy_stmt", 335545022},
{"invalid_boolean_usage", 335545023}, {"invalid_boolean_usage", 335545023},
{"sysf_argscant_both_be_zero", 335545024}, {"sysf_argscant_both_be_zero", 335545024},
{"spb_no_id", 335545025},
{"gfix_db_name", 335740929}, {"gfix_db_name", 335740929},
{"gfix_invalid_sw", 335740930}, {"gfix_invalid_sw", 335740930},
{"gfix_incmp_sw", 335740932}, {"gfix_incmp_sw", 335740932},

View File

@ -760,6 +760,7 @@ const ISC_STATUS isc_bad_events_handle = 335545021L;
const ISC_STATUS isc_cannot_copy_stmt = 335545022L; const ISC_STATUS isc_cannot_copy_stmt = 335545022L;
const ISC_STATUS isc_invalid_boolean_usage = 335545023L; const ISC_STATUS isc_invalid_boolean_usage = 335545023L;
const ISC_STATUS isc_sysf_argscant_both_be_zero = 335545024L; const ISC_STATUS isc_sysf_argscant_both_be_zero = 335545024L;
const ISC_STATUS isc_spb_no_id = 335545025L;
const ISC_STATUS isc_gfix_db_name = 335740929L; const ISC_STATUS isc_gfix_db_name = 335740929L;
const ISC_STATUS isc_gfix_invalid_sw = 335740930L; const ISC_STATUS isc_gfix_invalid_sw = 335740930L;
const ISC_STATUS isc_gfix_incmp_sw = 335740932L; const ISC_STATUS isc_gfix_incmp_sw = 335740932L;
@ -1179,7 +1180,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L;
const ISC_STATUS isc_trace_switch_param_miss = 337182758L; const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L; const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L; const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
const ISC_STATUS isc_err_max = 1123; const ISC_STATUS isc_err_max = 1124;
#else /* c definitions */ #else /* c definitions */
@ -1909,6 +1910,7 @@ const ISC_STATUS isc_err_max = 1123;
#define isc_cannot_copy_stmt 335545022L #define isc_cannot_copy_stmt 335545022L
#define isc_invalid_boolean_usage 335545023L #define isc_invalid_boolean_usage 335545023L
#define isc_sysf_argscant_both_be_zero 335545024L #define isc_sysf_argscant_both_be_zero 335545024L
#define isc_spb_no_id 335545025L
#define isc_gfix_db_name 335740929L #define isc_gfix_db_name 335740929L
#define isc_gfix_invalid_sw 335740930L #define isc_gfix_invalid_sw 335740930L
#define isc_gfix_incmp_sw 335740932L #define isc_gfix_incmp_sw 335740932L
@ -2328,7 +2330,7 @@ const ISC_STATUS isc_err_max = 1123;
#define isc_trace_switch_param_miss 337182758L #define isc_trace_switch_param_miss 337182758L
#define isc_trace_param_act_notcompat 337182759L #define isc_trace_param_act_notcompat 337182759L
#define isc_trace_mandatory_switch_miss 337182760L #define isc_trace_mandatory_switch_miss 337182760L
#define isc_err_max 1123 #define isc_err_max 1124
#endif #endif

View File

@ -729,6 +729,7 @@ Data source : @4"}, /* eds_statement */
{335545022, "Cannot copy statement @1"}, /* cannot_copy_stmt */ {335545022, "Cannot copy statement @1"}, /* cannot_copy_stmt */
{335545023, "Invalid usage of boolean expression"}, /* invalid_boolean_usage */ {335545023, "Invalid usage of boolean expression"}, /* invalid_boolean_usage */
{335545024, "Arguments for @1 cannot both be zero"}, /* sysf_argscant_both_be_zero */ {335545024, "Arguments for @1 cannot both be zero"}, /* sysf_argscant_both_be_zero */
{335545025, "missing service ID in spb"}, /* spb_no_id */
{335740929, "data base file name (@1) already given"}, /* gfix_db_name */ {335740929, "data base file name (@1) already given"}, /* gfix_db_name */
{335740930, "invalid switch @1"}, /* gfix_invalid_sw */ {335740930, "invalid switch @1"}, /* gfix_invalid_sw */
{335740932, "incompatible switch combination"}, /* gfix_incmp_sw */ {335740932, "incompatible switch combination"}, /* gfix_incmp_sw */

View File

@ -725,6 +725,7 @@ static const struct {
{335545022, -104}, /* 702 cannot_copy_stmt */ {335545022, -104}, /* 702 cannot_copy_stmt */
{335545023, -104}, /* 703 invalid_boolean_usage */ {335545023, -104}, /* 703 invalid_boolean_usage */
{335545024, -833}, /* 704 sysf_argscant_both_be_zero */ {335545024, -833}, /* 704 sysf_argscant_both_be_zero */
{335545025, -901}, /* 705 spb_no_id */
{335740929, -901}, /* 1 gfix_db_name */ {335740929, -901}, /* 1 gfix_db_name */
{335740930, -901}, /* 2 gfix_invalid_sw */ {335740930, -901}, /* 2 gfix_invalid_sw */
{335740932, -901}, /* 4 gfix_incmp_sw */ {335740932, -901}, /* 4 gfix_incmp_sw */

View File

@ -725,6 +725,7 @@ static const struct {
{335545022, "XX000"}, // 702 cannot_copy_stmt {335545022, "XX000"}, // 702 cannot_copy_stmt
{335545023, "22000"}, // 703 invalid_boolean_usage {335545023, "22000"}, // 703 invalid_boolean_usage
{335545024, "42000"}, // 704 sysf_argscant_both_be_zero {335545024, "42000"}, // 704 sysf_argscant_both_be_zero
{335545025, "HY000"}, // 705 spb_no_id
{335740929, "00000"}, // 1 gfix_db_name {335740929, "00000"}, // 1 gfix_db_name
{335740930, "00000"}, // 2 gfix_invalid_sw {335740930, "00000"}, // 2 gfix_invalid_sw
{335740932, "00000"}, // 4 gfix_incmp_sw {335740932, "00000"}, // 4 gfix_incmp_sw

View File

@ -58,6 +58,7 @@ using namespace Firebird;
namespace Jrd { namespace Jrd {
MakeUpgradeInfo<> upInfo;
template <typename T> class ExtEngineManager::ContextManager template <typename T> class ExtEngineManager::ContextManager
{ {
@ -826,7 +827,7 @@ ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const MetaName& nam
if (!engines.get(name, engine)) if (!engines.get(name, engine))
{ {
GetPlugins<ExternalEngine> engineControl(PluginType::ExternalEngine, GetPlugins<ExternalEngine> engineControl(PluginType::ExternalEngine,
FB_EXTERNAL_ENGINE_VERSION, name.c_str()); FB_EXTERNAL_ENGINE_VERSION, upInfo, name.c_str());
if (engineControl.hasData()) if (engineControl.hasData())
{ {

View File

@ -36,6 +36,7 @@
using namespace Jrd; using namespace Jrd;
using namespace Firebird; using namespace Firebird;
static MakeUpgradeInfo<> upInfo;
const Format* UsersTableScan::getFormat(thread_db* tdbb, jrd_rel* relation) const const Format* UsersTableScan::getFormat(thread_db* tdbb, jrd_rel* relation) const
{ {
@ -212,6 +213,7 @@ void UserManagement::execute(USHORT id)
void UserManagement::Display::list(Auth::IUser* u) void UserManagement::Display::list(Auth::IUser* u)
{ {
MasterInterfacePtr()->upgradeInterface(u, FB_AUTH_USER_VERSION, upInfo);
userManagement->list(u); userManagement->list(u);
} }

View File

@ -296,8 +296,6 @@ int JProvider::release()
} }
static UnloadDetector unloadDetector;
static void shutdownBeforeUnload() static void shutdownBeforeUnload()
{ {
LocalStatus status; LocalStatus status;
@ -310,7 +308,7 @@ public:
// IPluginFactory implementation // IPluginFactory implementation
IPluginBase* FB_CARG createPlugin(IPluginConfig* factoryParameter) IPluginBase* FB_CARG createPlugin(IPluginConfig* factoryParameter)
{ {
if (unloadDetector->unloadStarted()) if (myModule->unloadStarted())
{ {
return NULL; return NULL;
} }
@ -325,9 +323,9 @@ static Static<EngineFactory> engineFactory;
void registerEngine(IPluginManager* iPlugin) void registerEngine(IPluginManager* iPlugin)
{ {
unloadDetector->setCleanup(shutdownBeforeUnload); myModule->setCleanup(shutdownBeforeUnload);
iPlugin->registerPluginFactory(PluginType::Provider, "Engine12", &engineFactory); iPlugin->registerPluginFactory(PluginType::Provider, "Engine12", &engineFactory);
iPlugin->registerModule(&unloadDetector); iPlugin->registerModule(&myModule);
} }
} // namespace Jrd } // namespace Jrd

View File

@ -1890,6 +1890,10 @@ void Service::start(USHORT spb_length, const UCHAR* spb_data)
ClumpletReader spb(ClumpletReader::SpbStart, spb_data, spb_length); ClumpletReader spb(ClumpletReader::SpbStart, spb_data, spb_length);
// The name of the service is the first element of the buffer // The name of the service is the first element of the buffer
if (spb.isEof())
{
status_exception::raise(Arg::Gds(isc_service_att_err) << Arg::Gds(isc_spb_no_id));
}
const UCHAR svc_id = spb.getClumpTag(); const UCHAR svc_id = spb.getClumpTag();
const serv_entry* serv; const serv_entry* serv;
for (serv = services; serv->serv_action; serv++) for (serv = services; serv->serv_action; serv++)

View File

@ -64,6 +64,9 @@ namespace
return 1; return 1;
} }
}; };
MakeUpgradeInfo<IgnoreMissing> upgradePlugin;
MakeUpgradeInfo<> upgradeFactory;
} }
namespace Jrd { namespace Jrd {
@ -156,7 +159,7 @@ void TraceManager::load_plugins()
init_factories = true; init_factories = true;
factories = FB_NEW(*getDefaultMemoryPool()) TraceManager::Factories(*getDefaultMemoryPool()); factories = FB_NEW(*getDefaultMemoryPool()) TraceManager::Factories(*getDefaultMemoryPool());
for (GetPlugins<TraceFactory, IgnoreMissing> traceItr(PluginType::Trace, FB_TRACE_PLUGIN_VERSION); for (GetPlugins<TraceFactory> traceItr(PluginType::Trace, FB_TRACE_FACTORY_VERSION, upgradeFactory);
traceItr.hasData(); traceItr.next()) traceItr.hasData(); traceItr.next())
{ {
FactoryInfo info; FactoryInfo info;
@ -259,6 +262,8 @@ void TraceManager::update_session(const TraceSession& session)
} }
} }
MasterInterfacePtr master;
for (FactoryInfo* info = factories->begin(); info != factories->end(); ++info) for (FactoryInfo* info = factories->begin(); info != factories->end(); ++info)
{ {
TraceInitInfoImpl attachInfo(session, attachment, filename); TraceInitInfoImpl attachInfo(session, attachment, filename);
@ -267,6 +272,8 @@ void TraceManager::update_session(const TraceSession& session)
if (plugin) if (plugin)
{ {
master->upgradeInterface(plugin, FB_TRACE_PLUGIN_VERSION, upgradePlugin);
plugin->addRef(); plugin->addRef();
SessionInfo sesInfo; SessionInfo sesInfo;
sesInfo.plugin = plugin; sesInfo.plugin = plugin;

View File

@ -1,7 +1,7 @@
/* MAX_NUMBER is the next number to be used, always one more than the highest message number. */ /* MAX_NUMBER is the next number to be used, always one more than the highest message number. */
set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?); set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?);
-- --
('2011-02-02 12:45:00', 'JRD', 0, 705) ('2011-06-10 16:23:31', 'JRD', 0, 706)
('2010-03-15 06:59:09', 'QLI', 1, 531) ('2010-03-15 06:59:09', 'QLI', 1, 531)
-- --
--('2008-11-28 20:27:04', 'GDEF', 2, 346) --('2008-11-28 20:27:04', 'GDEF', 2, 346)

View File

@ -812,6 +812,7 @@ Data source : @4', NULL, NULL)
('cannot_copy_stmt', NULL, NULL, NULL, 0, 702, NULL, 'Cannot copy statement @1', NULL, NULL); ('cannot_copy_stmt', NULL, NULL, NULL, 0, 702, NULL, 'Cannot copy statement @1', NULL, NULL);
('invalid_boolean_usage', NULL, NULL, NULL, 0, 703, NULL, 'Invalid usage of boolean expression', NULL, NULL); ('invalid_boolean_usage', NULL, NULL, NULL, 0, 703, NULL, 'Invalid usage of boolean expression', NULL, NULL);
('sysf_argscant_both_be_zero', 'evlAtan2', 'SysFunction.cpp', NULL, 0, 704, NULL, 'Arguments for @1 cannot both be zero', NULL, NULL) ('sysf_argscant_both_be_zero', 'evlAtan2', 'SysFunction.cpp', NULL, 0, 704, NULL, 'Arguments for @1 cannot both be zero', NULL, NULL)
('spb_no_id', 'Service::start', 'svc.c', NULL, 0, 705, NULL, 'missing service ID in spb', NULL, NULL);
-- QLI -- QLI
(NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL); (NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL);
(NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL); (NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL);

View File

@ -710,6 +710,7 @@ set bulk_insert INSERT INTO SYSTEM_ERRORS (SQL_CODE, SQL_CLASS, SQL_SUBCLASS, FA
(-104, 'XX', '000', 0, 702, 'cannot_copy_stmt', NULL, NULL) (-104, 'XX', '000', 0, 702, 'cannot_copy_stmt', NULL, NULL)
(-104, '22', '000', 0, 703, 'invalid_boolean_usage', NULL, NULL) (-104, '22', '000', 0, 703, 'invalid_boolean_usage', NULL, NULL)
(-833, '42', '000', 0, 704, 'sysf_argscant_both_be_zero', NULL, NULL) (-833, '42', '000', 0, 704, 'sysf_argscant_both_be_zero', NULL, NULL)
(-901, 'HY', '000', 0, 705, 'spb_no_id', NULL, NULL)
-- GFIX -- GFIX
(-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL) (-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL)
(-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL) (-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL)

View File

@ -754,13 +754,12 @@ public:
class ExternalEngineFactoryImpl : public SimpleFactory<Engine> class ExternalEngineFactoryImpl : public SimpleFactory<Engine>
{ {
} factory; } factory;
static Firebird::UnloadDetector unloadDetector;
extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master) extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
{ {
PluginManagerInterfacePtr pi; PluginManagerInterfacePtr pi;
pi->registerPluginFactory(PluginType::ExternalEngine, "UDR", &factory); pi->registerPluginFactory(PluginType::ExternalEngine, "UDR", &factory);
pi->registerModule(&unloadDetector); pi->registerModule(&myModule);
libraryName->assign("fbclient"); libraryName->assign("fbclient");
ModuleLoader::doctorModuleExtension(libraryName); ModuleLoader::doctorModuleExtension(libraryName);

View File

@ -5779,6 +5779,7 @@ static void info(IStatus* status,
response->p_resp_data = temp; response->p_resp_data = temp;
} }
static MakeUpgradeInfo<> upInfo;
static void init(IStatus* status, static void init(IStatus* status,
rem_port* port, rem_port* port,
@ -5808,7 +5809,7 @@ static void init(IStatus* status,
// Let plugins try to add data to DPB in order to avoid extra network roundtrip // Let plugins try to add data to DPB in order to avoid extra network roundtrip
Auth::DpbImplementation di(dpb); Auth::DpbImplementation di(dpb);
LocalStatus s; LocalStatus s;
GetPlugins<Auth::IClient> authItr(PluginType::AuthClient, FB_AUTH_CLIENT_VERSION); GetPlugins<Auth::IClient> authItr(PluginType::AuthClient, FB_AUTH_CLIENT_VERSION, upInfo);
bool working = true; bool working = true;

View File

@ -217,6 +217,8 @@ public:
GlobalPtr<FailedLogins> usernameFailedLogins; GlobalPtr<FailedLogins> usernameFailedLogins;
GlobalPtr<FailedLogins> remoteFailedLogins; GlobalPtr<FailedLogins> remoteFailedLogins;
MakeUpgradeInfo<> upInfo;
// delayed authentication block for auth callback // delayed authentication block for auth callback
class ServerAuth : public GlobalStorage, public ServerAuthBase class ServerAuth : public GlobalStorage, public ServerAuthBase
{ {
@ -231,7 +233,7 @@ public:
wrt(getPool(), op == op_service_attach ? ClumpletReader::spbList : ClumpletReader::dpbList, wrt(getPool(), op == op_service_attach ? ClumpletReader::spbList : ClumpletReader::dpbList,
MAX_DPB_SIZE, pb, pbLen), MAX_DPB_SIZE, pb, pbLen),
authBlockInterface(op == op_service_attach), authBlockInterface(op == op_service_attach),
authItr(PluginType::AuthServer, FB_AUTH_SERVER_VERSION, config), authItr(PluginType::AuthServer, FB_AUTH_SERVER_VERSION, upInfo, config),
remoteId(getPool()), userName(getPool()), authServer(NULL), remoteId(getPool()), userName(getPool()), authServer(NULL),
part2(p2), operation(op) part2(p2), operation(op)
{ {

View File

@ -38,12 +38,14 @@
#include "../../common/os/path_utils.h" #include "../../common/os/path_utils.h"
#include "../../jrd/inf_pub.h" #include "../../jrd/inf_pub.h"
#include "../../dsql/sqlda_pub.h" #include "../../dsql/sqlda_pub.h"
#include "../common/classes/ImplementHelper.h"
using namespace Firebird; using namespace Firebird;
using namespace Jrd; using namespace Jrd;
static const char* const DEFAULT_LOG_NAME = "default_trace.log"; static const char* const DEFAULT_LOG_NAME = "default_trace.log";
static MakeUpgradeInfo<> upInfo;
#ifdef WIN_NT #ifdef WIN_NT
#define NEWLINE "\r\n" #define NEWLINE "\r\n"
@ -89,6 +91,7 @@ TracePluginImpl::TracePluginImpl(const TracePluginConfig &configuration, TraceIn
services(getDefaultMemoryPool()), services(getDefaultMemoryPool()),
unicodeCollation(*getDefaultMemoryPool()) unicodeCollation(*getDefaultMemoryPool())
{ {
MasterInterfacePtr()->upgradeInterface(logWriter, FB_TRACE_LOG_WRITER_VERSION, upInfo);
const char* ses_name = initInfo->getTraceSessionName(); const char* ses_name = initInfo->getTraceSessionName();
session_name = ses_name && *ses_name ? ses_name : " "; session_name = ses_name && *ses_name ? ses_name : " ";
@ -1937,6 +1940,8 @@ ntrace_boolean_t TracePluginImpl::trace_attach(TraceConnection* connection,
{ {
try try
{ {
MasterInterfacePtr()->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
log_event_attach(connection, create_db, att_result); log_event_attach(connection, create_db, att_result);
return true; return true;
} }
@ -1951,6 +1956,8 @@ ntrace_boolean_t TracePluginImpl::trace_detach(TraceConnection* connection, ntra
{ {
try try
{ {
MasterInterfacePtr()->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
log_event_detach(connection, drop_db); log_event_detach(connection, drop_db);
return true; return true;
} }
@ -1967,6 +1974,10 @@ ntrace_boolean_t TracePluginImpl::trace_transaction_start(TraceConnection* conne
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
log_event_transaction_start(connection, transaction, tpb_length, tpb, tra_result); log_event_transaction_start(connection, transaction, tpb_length, tpb, tra_result);
return true; return true;
} }
@ -1982,6 +1993,10 @@ ntrace_boolean_t TracePluginImpl::trace_transaction_end(TraceConnection* connect
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
log_event_transaction_end(connection, transaction, commit, retain_context, tra_result); log_event_transaction_end(connection, transaction, commit, retain_context, tra_result);
return true; return true;
} }
@ -1998,6 +2013,11 @@ ntrace_boolean_t TracePluginImpl::trace_set_context(TraceConnection* connection,
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(variable, FB_TRACE_CONTEXT_VARIABLE_VERSION, upInfo);
log_event_set_context(connection, transaction, variable); log_event_set_context(connection, transaction, variable);
return true; return true;
} }
@ -2015,6 +2035,11 @@ ntrace_boolean_t TracePluginImpl::trace_proc_execute(TraceConnection* connection
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(procedure, FB_TRACE_PROCEDURE_VERSION, upInfo);
log_event_proc_execute(connection, transaction, procedure, started, proc_result); log_event_proc_execute(connection, transaction, procedure, started, proc_result);
return true; return true;
} }
@ -2031,6 +2056,11 @@ ntrace_boolean_t TracePluginImpl::trace_trigger_execute(TraceConnection* connect
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(trigger, FB_TRACE_TRIGGER_VERSION, upInfo);
log_event_trigger_execute(connection, transaction, trigger, started, trig_result); log_event_trigger_execute(connection, transaction, trigger, started, trig_result);
return true; return true;
} }
@ -2048,6 +2078,11 @@ ntrace_boolean_t TracePluginImpl::trace_dsql_prepare(TraceConnection* connection
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(statement, FB_TRACE_SQL_STATEMENT_VERSION, upInfo);
log_event_dsql_prepare(connection, transaction, statement, time_millis, req_result); log_event_dsql_prepare(connection, transaction, statement, time_millis, req_result);
return true; return true;
} }
@ -2063,6 +2098,10 @@ ntrace_boolean_t TracePluginImpl::trace_dsql_free(TraceConnection* connection,
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(statement, FB_TRACE_SQL_STATEMENT_VERSION, upInfo);
log_event_dsql_free(connection, statement, option); log_event_dsql_free(connection, statement, option);
return true; return true;
} }
@ -2079,6 +2118,11 @@ ntrace_boolean_t TracePluginImpl::trace_dsql_execute(TraceConnection* connection
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(statement, FB_TRACE_SQL_STATEMENT_VERSION, upInfo);
log_event_dsql_execute(connection, transaction, statement, started, req_result); log_event_dsql_execute(connection, transaction, statement, started, req_result);
return true; return true;
} }
@ -2096,6 +2140,11 @@ ntrace_boolean_t TracePluginImpl::trace_blr_compile(TraceConnection* connection,
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(statement, FB_TRACE_BLR_STATEMENT_VERSION, upInfo);
log_event_blr_compile(connection, transaction, statement, time_millis, req_result); log_event_blr_compile(connection, transaction, statement, time_millis, req_result);
return true; return true;
} }
@ -2111,6 +2160,11 @@ ntrace_boolean_t TracePluginImpl::trace_blr_execute(TraceConnection* connection,
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(statement, FB_TRACE_BLR_STATEMENT_VERSION, upInfo);
log_event_blr_execute(connection, transaction, statement, req_result); log_event_blr_execute(connection, transaction, statement, req_result);
return true; return true;
} }
@ -2127,6 +2181,11 @@ ntrace_boolean_t TracePluginImpl::trace_dyn_execute(TraceConnection* connection,
{ {
try try
{ {
MasterInterfacePtr master;
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
master->upgradeInterface(transaction, FB_TRACE_TRANSACTION_VERSION, upInfo);
master->upgradeInterface(request, FB_TRACE_DYN_REQUEST_VERSION, upInfo);
log_event_dyn_execute(connection, transaction, request, time_millis, req_result); log_event_dyn_execute(connection, transaction, request, time_millis, req_result);
return true; return true;
} }
@ -2142,6 +2201,7 @@ ntrace_boolean_t TracePluginImpl::trace_service_attach(TraceService* service, nt
{ {
try try
{ {
MasterInterfacePtr()->upgradeInterface(service, FB_TRACE_SERVICE_VERSION, upInfo);
log_event_service_attach(service, att_result); log_event_service_attach(service, att_result);
return true; return true;
} }
@ -2157,6 +2217,7 @@ ntrace_boolean_t TracePluginImpl::trace_service_start(TraceService* service, siz
{ {
try try
{ {
MasterInterfacePtr()->upgradeInterface(service, FB_TRACE_SERVICE_VERSION, upInfo);
log_event_service_start(service, switches_length, switches, start_result); log_event_service_start(service, switches_length, switches, start_result);
return true; return true;
} }
@ -2173,6 +2234,7 @@ ntrace_boolean_t TracePluginImpl::trace_service_query(TraceService* service, siz
{ {
try try
{ {
MasterInterfacePtr()->upgradeInterface(service, FB_TRACE_SERVICE_VERSION, upInfo);
log_event_service_query(service, send_item_length, send_items, log_event_service_query(service, send_item_length, send_items,
recv_item_length, recv_items, query_result); recv_item_length, recv_items, query_result);
return true; return true;
@ -2189,6 +2251,7 @@ ntrace_boolean_t TracePluginImpl::trace_service_detach(TraceService* service, nt
{ {
try try
{ {
MasterInterfacePtr()->upgradeInterface(service, FB_TRACE_SERVICE_VERSION, upInfo);
log_event_service_detach(service, detach_result); log_event_service_detach(service, detach_result);
return true; return true;
} }

View File

@ -26,6 +26,8 @@
* 2008 Khorsun Vladyslav * 2008 Khorsun Vladyslav
*/ */
#include "../common/classes/ImplementHelper.h"
#include "TraceConfiguration.h" #include "TraceConfiguration.h"
#include "TracePluginImpl.h" #include "TracePluginImpl.h"
@ -51,6 +53,8 @@ int FB_CARG TraceFactoryImpl::release()
return 1; return 1;
} }
static Firebird::MakeUpgradeInfo<> upInfo;
ntrace_mask_t FB_CARG TraceFactoryImpl::trace_needs() ntrace_mask_t FB_CARG TraceFactoryImpl::trace_needs()
{ {
return (1 << TRACE_EVENT_MAX) - 1; return (1 << TRACE_EVENT_MAX) - 1;
@ -58,9 +62,12 @@ ntrace_mask_t FB_CARG TraceFactoryImpl::trace_needs()
TracePlugin* FB_CARG TraceFactoryImpl::trace_create(Firebird::IStatus* status, TraceInitInfo* initInfo) TracePlugin* FB_CARG TraceFactoryImpl::trace_create(Firebird::IStatus* status, TraceInitInfo* initInfo)
{ {
Firebird::MasterInterfacePtr master;
const char* dbname = NULL; const char* dbname = NULL;
try try
{ {
master->upgradeInterface(initInfo, FB_TRACE_INIT_INFO_VERSION, upInfo);
dbname = initInfo->getDatabaseName(); dbname = initInfo->getDatabaseName();
if (!dbname) if (!dbname)
dbname = ""; dbname = "";
@ -69,6 +76,11 @@ TracePlugin* FB_CARG TraceFactoryImpl::trace_create(Firebird::IStatus* status, T
TraceCfgReader::readTraceConfiguration(initInfo->getConfigText(), dbname, config); TraceCfgReader::readTraceConfiguration(initInfo->getConfigText(), dbname, config);
TraceConnection* connection = initInfo->getConnection(); TraceConnection* connection = initInfo->getConnection();
if (connection)
{
master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);
}
if (!config.enabled || if (!config.enabled ||
(config.connection_id && connection && (config.connection_id && connection &&
(connection->getConnectionID() != SLONG(config.connection_id)))) (connection->getConnectionID() != SLONG(config.connection_id))))
@ -90,6 +102,7 @@ TracePlugin* FB_CARG TraceFactoryImpl::trace_create(Firebird::IStatus* status, T
TraceLogWriter* logWriter = initInfo->getLogWriter(); TraceLogWriter* logWriter = initInfo->getLogWriter();
if (logWriter) if (logWriter)
{ {
master->upgradeInterface(logWriter, FB_TRACE_LOG_WRITER_VERSION, upInfo);
const char* strEx = TracePluginImpl::marshal_exception(ex); const char* strEx = TracePluginImpl::marshal_exception(ex);
Firebird::string err; Firebird::string err;
if (dbname) if (dbname)
@ -111,12 +124,11 @@ TracePlugin* FB_CARG TraceFactoryImpl::trace_create(Firebird::IStatus* status, T
static Firebird::SimpleFactory<TraceFactoryImpl> traceFactory; static Firebird::SimpleFactory<TraceFactoryImpl> traceFactory;
static Firebird::UnloadDetector unloadDetector;
void registerTrace(Firebird::IPluginManager* iPlugin) void registerTrace(Firebird::IPluginManager* iPlugin)
{ {
iPlugin->registerPluginFactory(Firebird::PluginType::Trace, "fbtrace", &traceFactory); iPlugin->registerPluginFactory(Firebird::PluginType::Trace, "fbtrace", &traceFactory);
iPlugin->registerModule(&unloadDetector); iPlugin->registerModule(&Firebird::myModule);
} }

View File

@ -30,6 +30,8 @@
#include "firebird/Interface.h" #include "firebird/Interface.h"
#include "firebird/Timer.h" #include "firebird/Timer.h"
#include <string.h>
#include "../yvalve/MasterImplementation.h" #include "../yvalve/MasterImplementation.h"
#include "../common/classes/init.h" #include "../common/classes/init.h"
#include "../common/StatusHolder.h" #include "../common/StatusHolder.h"
@ -113,14 +115,50 @@ namespace
FunctionPtr* vTab; FunctionPtr* vTab;
}; };
typedef Firebird::Pair<Firebird::NonPooled<U_IPTR, FunctionPtr*> > FunctionPair; class UpgradeKey
{
public:
UpgradeKey(FunctionPtr* aFunc, IPluginModule* aModuleA, IPluginModule* aModuleB)
: func(aFunc), moduleA(aModuleA), moduleB(aModuleB)
{ }
UpgradeKey(const UpgradeKey& el)
: func(el.func), moduleA(el.moduleA), moduleB(el.moduleB)
{ }
UpgradeKey()
: func(NULL), moduleA(NULL), moduleB(NULL)
{ }
bool operator<(const UpgradeKey& el) const
{
return memcmp(this, &el, sizeof(UpgradeKey)) < 0;
}
bool operator>(const UpgradeKey& el) const
{
return memcmp(this, &el, sizeof(UpgradeKey)) > 0;
}
bool contains(IPluginModule* module)
{
return moduleA == module || moduleB == module;
}
private:
FunctionPtr* func;
IPluginModule* moduleA;
IPluginModule* moduleB;
};
typedef Firebird::Pair<Firebird::NonPooled<UpgradeKey, FunctionPtr*> > FunctionPair;
GlobalPtr<GenericMap<FunctionPair> > functionMap; GlobalPtr<GenericMap<FunctionPair> > functionMap;
GlobalPtr<RWLock> mapLock; GlobalPtr<RWLock> mapLock;
} }
int FB_CARG MasterImplementation::upgradeInterface(IVersioned* toUpgrade, int FB_CARG MasterImplementation::upgradeInterface(IVersioned* toUpgrade,
int desiredVersion, int desiredVersion,
void* missingFunctionClass) struct UpgradeInfo* upgradeInfo)
{ {
int existingVersion = toUpgrade->getVersion(); int existingVersion = toUpgrade->getVersion();
@ -132,9 +170,11 @@ int FB_CARG MasterImplementation::upgradeInterface(IVersioned* toUpgrade,
{ {
CVirtualClass* target = (CVirtualClass*) toUpgrade; CVirtualClass* target = (CVirtualClass*) toUpgrade;
UpgradeKey key(target->vTab, toUpgrade->getModule(), upgradeInfo->clientModule);
{ // sync scope { // sync scope
ReadLockGuard sync(mapLock); ReadLockGuard sync(mapLock);
if (functionMap->get((U_IPTR) target->vTab, newTab)) if (functionMap->get(key, newTab))
{ {
target->vTab = newTab; target->vTab = newTab;
return 0; return 0;
@ -143,9 +183,9 @@ int FB_CARG MasterImplementation::upgradeInterface(IVersioned* toUpgrade,
WriteLockGuard sync(mapLock); WriteLockGuard sync(mapLock);
if (!functionMap->get((U_IPTR) target->vTab, newTab)) if (!functionMap->get(key, newTab))
{ {
CVirtualClass* miss = (CVirtualClass*) missingFunctionClass; CVirtualClass* miss = (CVirtualClass*) (upgradeInfo->missingFunctionClass);
newTab = FB_NEW(*getDefaultMemoryPool()) FunctionPtr[desiredVersion]; newTab = FB_NEW(*getDefaultMemoryPool()) FunctionPtr[desiredVersion];
for (int i = 0; i < desiredVersion; ++i) for (int i = 0; i < desiredVersion; ++i)
@ -153,7 +193,7 @@ int FB_CARG MasterImplementation::upgradeInterface(IVersioned* toUpgrade,
newTab[i] = i < existingVersion ? target->vTab[i] : miss->vTab[0]; newTab[i] = i < existingVersion ? target->vTab[i] : miss->vTab[0];
} }
functionMap->put((U_IPTR) target->vTab, newTab); functionMap->put(key, newTab);
} }
target->vTab = newTab; target->vTab = newTab;
@ -173,6 +213,29 @@ int FB_CARG MasterImplementation::upgradeInterface(IVersioned* toUpgrade,
return 0; return 0;
} }
void releaseUpgradeTabs(IPluginModule* module)
{
HalfStaticArray<UpgradeKey, 16> removeList;
WriteLockGuard sync(mapLock);
GenericMap<FunctionPair>::Accessor scan(&functionMap);
if (scan.getFirst()) do
{
UpgradeKey& cur(scan.current()->first);
if (cur.contains(module))
{
removeList.add(cur);
}
}
while (scan.getNext());
for(unsigned int i = 0; i < removeList.getCount(); ++i)
{
functionMap->remove(removeList[i]);
}
}
} // namespace Why } // namespace Why
// //
@ -415,7 +478,7 @@ void TimerEntry::cleanup()
TimerDelay curTime() TimerDelay curTime()
{ {
return fb_utils::query_performance_counter() / fb_utils::query_performance_frequency(); return fb_utils::query_performance_counter() / (fb_utils::query_performance_frequency() / 1000000);
} }
TimerEntry* getTimer(ITimer* timer) TimerEntry* getTimer(ITimer* timer)

View File

@ -57,7 +57,8 @@ namespace Why
Firebird::IStatus* FB_CARG getStatus(); Firebird::IStatus* FB_CARG getStatus();
Firebird::IProvider* FB_CARG getDispatcher(); Firebird::IProvider* FB_CARG getDispatcher();
Firebird::IPluginManager* FB_CARG getPluginManager(); Firebird::IPluginManager* FB_CARG getPluginManager();
int FB_CARG upgradeInterface(Firebird::IVersioned* toUpgrade, int desiredVersion, void* missingFunctionClass); int FB_CARG upgradeInterface(Firebird::IVersioned* toUpgrade, int desiredVersion,
Firebird::UpgradeInfo* upgradeInfo);
const char* FB_CARG circularAlloc(const char* s, size_t len, intptr_t thr); const char* FB_CARG circularAlloc(const char* s, size_t len, intptr_t thr);
Firebird::ITimerControl* FB_CARG getTimerControl(); Firebird::ITimerControl* FB_CARG getTimerControl();
Firebird::IAttachment* registerAttachment(Firebird::IProvider* provider, Firebird::IAttachment* registerAttachment(Firebird::IProvider* provider,
@ -68,6 +69,7 @@ namespace Why
}; };
void shutdownTimers(); void shutdownTimers();
void releaseUpgradeTabs(Firebird::IPluginModule* module);
} // namespace Why } // namespace Why
#endif // YVALVE_MASTER_IMPLEMENTATION_H #endif // YVALVE_MASTER_IMPLEMENTATION_H

View File

@ -24,6 +24,7 @@
#include "consts_pub.h" #include "consts_pub.h"
#include "iberror.h" #include "iberror.h"
#include "../yvalve/PluginManager.h" #include "../yvalve/PluginManager.h"
#include "../yvalve/MasterImplementation.h"
#include "../dsql/sqlda_pub.h" #include "../dsql/sqlda_pub.h"
#include "../yvalve/why_proto.h" #include "../yvalve/why_proto.h"
@ -344,6 +345,7 @@ namespace
if (cleanup) if (cleanup)
{ {
cleanup->doClean(); cleanup->doClean();
Why::releaseUpgradeTabs(cleanup);
} }
} }
@ -442,6 +444,11 @@ namespace
~ConfiguredPlugin(); ~ConfiguredPlugin();
const char* getPlugName()
{
return plugName.c_str();
}
// ITimer implementation // ITimer implementation
void FB_CARG handler() void FB_CARG handler()
{ } { }
@ -501,6 +508,9 @@ namespace
private: private:
~FactoryParameter() ~FactoryParameter()
{ {
#ifdef DEBUG_PLUGINS
fprintf(stderr, "~FactoryParameter places configuredPlugin %s in unload query\n", configuredPlugin->getPlugName());
#endif
TimerInterfacePtr()->start(configuredPlugin, 1000000); // 1 sec TimerInterfacePtr()->start(configuredPlugin, 1000000); // 1 sec
} }
@ -645,10 +655,10 @@ namespace
void FB_CARG next(); void FB_CARG next();
PluginSet(unsigned int pinterfaceType, const char* pnamesList, PluginSet(unsigned int pinterfaceType, const char* pnamesList,
int pdesiredVersion, void* pmissingFunctionClass, int pdesiredVersion, UpgradeInfo* pui,
IFirebirdConf* fbConf) IFirebirdConf* fbConf)
: interfaceType(pinterfaceType), namesList(getPool()), : interfaceType(pinterfaceType), namesList(getPool()),
desiredVersion(pdesiredVersion), missingFunctionClass(pmissingFunctionClass), desiredVersion(pdesiredVersion), ui(pui),
currentName(getPool()), currentPlugin(NULL), currentName(getPool()), currentPlugin(NULL),
firebirdConf(fbConf) firebirdConf(fbConf)
{ {
@ -672,7 +682,7 @@ namespace
unsigned int interfaceType; unsigned int interfaceType;
PathName namesList; PathName namesList;
int desiredVersion; int desiredVersion;
void* missingFunctionClass; UpgradeInfo* ui;
PathName currentName; PathName currentName;
RefPtr<ConfiguredPlugin> currentPlugin; // Missing data in this field indicates EOF RefPtr<ConfiguredPlugin> currentPlugin; // Missing data in this field indicates EOF
@ -807,7 +817,7 @@ namespace
IPluginBase* p = currentPlugin->factory(firebirdConf); IPluginBase* p = currentPlugin->factory(firebirdConf);
if (p) if (p)
{ {
if (masterInterface->upgradeInterface(p, desiredVersion, missingFunctionClass) >= 0) if (masterInterface->upgradeInterface(p, desiredVersion, ui) >= 0)
{ {
return p; return p;
} }
@ -895,13 +905,13 @@ void FB_CARG PluginManager::unregisterModule(IPluginModule* cleanup)
} }
IPluginSet* FB_CARG PluginManager::getPlugins(unsigned int interfaceType, const char* namesList, IPluginSet* FB_CARG PluginManager::getPlugins(unsigned int interfaceType, const char* namesList,
int desiredVersion, void* missingFunctionClass, int desiredVersion, UpgradeInfo* ui,
IFirebirdConf* firebirdConf) IFirebirdConf* firebirdConf)
{ {
MutexLockGuard g(plugins->mutex); MutexLockGuard g(plugins->mutex);
IPluginSet* rc = new PluginSet(interfaceType, namesList, desiredVersion, IPluginSet* rc = new PluginSet(interfaceType, namesList, desiredVersion,
missingFunctionClass, firebirdConf); ui, firebirdConf);
rc->addRef(); rc->addRef();
return rc; return rc;
} }

View File

@ -43,14 +43,14 @@ class PluginManager : public AutoIface<IPluginManager, FB_PLUGIN_MANAGER_VERSION
public: public:
// IPluginManager implementation // IPluginManager implementation
IPluginSet* FB_CARG getPlugins(unsigned int interfaceType, const char* namesList, IPluginSet* FB_CARG getPlugins(unsigned int interfaceType, const char* namesList,
int desiredVersion, void* missingFunctionClass, int desiredVersion, UpgradeInfo* ui,
IFirebirdConf* firebirdConf); IFirebirdConf* firebirdConf);
void FB_CARG registerPluginFactory(unsigned int interfaceType, const char* defaultName, void FB_CARG registerPluginFactory(unsigned int interfaceType, const char* defaultName,
IPluginFactory* factory); IPluginFactory* factory);
IConfig* FB_CARG getConfig(const char* filename); IConfig* FB_CARG getConfig(const char* filename);
void FB_CARG releasePlugin(IPluginBase* plugin); void FB_CARG releasePlugin(IPluginBase* plugin);
void FB_CARG registerModule(IPluginModule* cleanup); void FB_CARG registerModule(IPluginModule* module);
void FB_CARG unregisterModule(IPluginModule* cleanup); void FB_CARG unregisterModule(IPluginModule* module);
PluginManager(); PluginManager();

View File

@ -117,10 +117,7 @@ template <typename Impl, typename Intf, int Vers>
class YHelper : public Firebird::StdPlugin<Intf, Vers>, public YObject class YHelper : public Firebird::StdPlugin<Intf, Vers>, public YObject
{ {
public: public:
YHelper(Intf* aNext) : next(aNext) YHelper(Intf* aNext);
{
this->addRef();
}
int FB_CARG release() int FB_CARG release()
{ {
@ -426,7 +423,7 @@ public:
{ {
if (--refCounter == 0) if (--refCounter == 0)
{ {
delete this; //delete this;
return 0; return 0;
} }

View File

@ -557,10 +557,12 @@ namespace Why
public: public:
virtual void FB_CARG noEntrypoint(IStatus* s) virtual void FB_CARG noEntrypoint(IStatus* s)
{ {
s->set(Arg::Gds(isc_unavailable).value()); s->set(Arg::Gds(isc_wish_list).value());
} }
}; };
MakeUpgradeInfo<NoEntrypoint> upInfo;
template <typename T, typename CleanupRoutine> // T = YAttachment or YTransaction template <typename T, typename CleanupRoutine> // T = YAttachment or YTransaction
class CleanupCallbackImpl : public CleanupCallback class CleanupCallbackImpl : public CleanupCallback
{ {
@ -3269,6 +3271,13 @@ ITransaction* MasterImplementation::registerTransaction(IAttachment* attachment,
return new YTransaction(static_cast<YAttachment*>(attachment), transaction); return new YTransaction(static_cast<YAttachment*>(attachment), transaction);
} }
template <typename Impl, typename Intf, int Vers>
YHelper<Impl, Intf, Vers>::YHelper(Intf* aNext)
{
MasterInterfacePtr()->upgradeInterface(aNext, Vers, upInfo);
next = aNext;
this->addRef();
}
//------------------------------------- //-------------------------------------
@ -4640,8 +4649,8 @@ YAttachment* Dispatcher::attachDatabase(IStatus* status, const char* filename,
RefPtr<Config> config; RefPtr<Config> config;
ResolveDatabaseAlias(expandedFilename, dummy, &config); ResolveDatabaseAlias(expandedFilename, dummy, &config);
for (GetPlugins<IProvider, NoEntrypoint> providerIterator(PluginType::Provider, for (GetPlugins<IProvider> providerIterator(PluginType::Provider,
FB_PROVIDER_VERSION, config); FB_PROVIDER_VERSION, upInfo, config);
providerIterator.hasData(); providerIterator.hasData();
providerIterator.next()) providerIterator.next())
{ {
@ -4763,8 +4772,8 @@ YAttachment* Dispatcher::createDatabase(IStatus* status, const char* filename,
ResolveDatabaseAlias(expandedFilename, dummy, &config); ResolveDatabaseAlias(expandedFilename, dummy, &config);
***/ ***/
for (GetPlugins<IProvider, NoEntrypoint> providerIterator(PluginType::Provider, for (GetPlugins<IProvider> providerIterator(PluginType::Provider,
FB_PROVIDER_VERSION/***, config***/); FB_PROVIDER_VERSION, upInfo/***, config***/);
providerIterator.hasData(); providerIterator.hasData();
providerIterator.next()) providerIterator.next())
{ {
@ -4827,8 +4836,8 @@ YService* Dispatcher::attachServiceManager(IStatus* status, const char* serviceN
try try
{ {
for (GetPlugins<IProvider, NoEntrypoint> providerIterator(PluginType::Provider, for (GetPlugins<IProvider> providerIterator(PluginType::Provider,
FB_PROVIDER_VERSION); FB_PROVIDER_VERSION, upInfo);
providerIterator.hasData(); providerIterator.hasData();
providerIterator.next()) providerIterator.next())
{ {
@ -4916,8 +4925,8 @@ void Dispatcher::shutdown(IStatus* userStatus, unsigned int timeout, const int r
shutdownStarted = true; shutdownStarted = true;
// Shutdown providers (if any present). // Shutdown providers (if any present).
for (GetPlugins<IProvider, NoEntrypoint> providerIterator( for (GetPlugins<IProvider> providerIterator(PluginType::Provider,
PluginType::Provider, FB_PROVIDER_VERSION); FB_PROVIDER_VERSION, upInfo);
providerIterator.hasData(); providerIterator.hasData();
providerIterator.next()) providerIterator.next())
{ {