"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/jrd.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

jrd.cpp  (Firebird-3.0.2.32703-0.tar.bz2):jrd.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 135 skipping to change at line 135
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
#include "../common/classes/RefMutex.h" #include "../common/classes/RefMutex.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
#include "../jrd/DebugInterface.h" #include "../jrd/DebugInterface.h"
#include "../jrd/CryptoManager.h" #include "../jrd/CryptoManager.h"
#include "../jrd/DbCreators.h" #include "../jrd/DbCreators.h"
#include "../dsql/dsql.h" #include "../dsql/dsql.h"
#include "../dsql/dsql_proto.h" #include "../dsql/dsql_proto.h"
#ifdef WIN_NT
#include "../common/dllinst.h"
#endif
using namespace Jrd; using namespace Jrd;
using namespace Firebird; using namespace Firebird;
const SSHORT WAIT_PERIOD = -1; const SSHORT WAIT_PERIOD = -1;
#ifdef SUPPORT_RAW_DEVICES #ifdef SUPPORT_RAW_DEVICES
#define unlink PIO_unlink #define unlink PIO_unlink
#endif #endif
#ifdef DEV_BUILD #ifdef DEV_BUILD
skipping to change at line 380 skipping to change at line 384
{ {
if (--refCounter == 0) if (--refCounter == 0)
{ {
delete this; delete this;
return 0; return 0;
} }
return 1; return 1;
} }
static void threadDetach()
{
ThreadSync* thd = ThreadSync::findThread();
delete thd;
}
static void shutdownBeforeUnload() static void shutdownBeforeUnload()
{ {
LocalStatus status; LocalStatus status;
CheckStatusWrapper statusWrapper(&status); CheckStatusWrapper statusWrapper(&status);
JProvider::getInstance()->shutdown(&statusWrapper, 0, fb_shutrsn_exit_cal AutoPlugin<JProvider>(JProvider::getInstance())->shutdown(&statusWrapper,
led); 0, fb_shutrsn_exit_called);
threadDetach();
}; };
class EngineFactory : public AutoIface<IPluginFactoryImpl<EngineFactory, CheckSt atusWrapper> > class EngineFactory : public AutoIface<IPluginFactoryImpl<EngineFactory, CheckSt atusWrapper> >
{ {
public: public:
// IPluginFactory implementation // IPluginFactory implementation
IPluginBase* createPlugin(CheckStatusWrapper* status, IPluginConfig* fact oryParameter) IPluginBase* createPlugin(CheckStatusWrapper* status, IPluginConfig* fact oryParameter)
{ {
try try
{ {
skipping to change at line 417 skipping to change at line 428
ex.stuffException(status); ex.stuffException(status);
} }
return NULL; return NULL;
} }
}; };
static Static<EngineFactory> engineFactory; static Static<EngineFactory> engineFactory;
void registerEngine(IPluginManager* iPlugin) void registerEngine(IPluginManager* iPlugin)
{ {
getUnloadDetector()->setCleanup(shutdownBeforeUnload); UnloadDetectorHelper* module = getUnloadDetector();
module->setCleanup(shutdownBeforeUnload);
module->setThreadDetach(threadDetach);
iPlugin->registerPluginFactory(IPluginManager::TYPE_PROVIDER, CURRENT_ENG INE, &engineFactory); iPlugin->registerPluginFactory(IPluginManager::TYPE_PROVIDER, CURRENT_ENG INE, &engineFactory);
getUnloadDetector()->registerMe(); module->registerMe();
} }
} // namespace Jrd } // namespace Jrd
extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(IMaster* master) extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(IMaster* master)
{ {
CachedMasterInterface::set(master); CachedMasterInterface::set(master);
registerEngine(PluginManagerInterfacePtr()); registerEngine(PluginManagerInterfacePtr());
} }
skipping to change at line 663 skipping to change at line 677
static const unsigned ATT_DONT_LOCK = 2; static const unsigned ATT_DONT_LOCK = 2;
static const unsigned ATT_NO_SHUTDOWN_CHECK = 4; static const unsigned ATT_NO_SHUTDOWN_CHECK = 4;
static const unsigned ATT_NON_BLOCKING = 8; static const unsigned ATT_NON_BLOCKING = 8;
AttachmentHolder(thread_db* tdbb, StableAttachmentPart* sa, unsig ned lockFlags, const char* from) AttachmentHolder(thread_db* tdbb, StableAttachmentPart* sa, unsig ned lockFlags, const char* from)
: sAtt(sa), : sAtt(sa),
async(lockFlags & ATT_LOCK_ASYNC), async(lockFlags & ATT_LOCK_ASYNC),
nolock(lockFlags & ATT_DONT_LOCK), nolock(lockFlags & ATT_DONT_LOCK),
blocking(!(lockFlags & ATT_NON_BLOCKING)) blocking(!(lockFlags & ATT_NON_BLOCKING))
{ {
if (!sa)
Arg::Gds(isc_att_shutdown).raise();
if (blocking) if (blocking)
sAtt->getBlockingMutex()->enter(from); sAtt->getBlockingMutex()->enter(from);
try try
{ {
if (!nolock) if (!nolock)
sAtt->getMutex(async)->enter(from); sAtt->getMutex(async)->enter(from);
Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex
skipping to change at line 925 skipping to change at line 942
USHORT dpb_set_db_sql_dialect; USHORT dpb_set_db_sql_dialect;
SLONG dpb_remote_pid; SLONG dpb_remote_pid;
bool dpb_no_db_triggers; bool dpb_no_db_triggers;
bool dpb_gbak_attach; bool dpb_gbak_attach;
bool dpb_utf8_filename; bool dpb_utf8_filename;
ULONG dpb_ext_call_depth; ULONG dpb_ext_call_depth;
ULONG dpb_flags; // to OR'd with dbb_flags ULONG dpb_flags; // to OR'd with dbb_flags
bool dpb_nolinger; bool dpb_nolinger;
bool dpb_reset_icu; bool dpb_reset_icu;
bool dpb_map_attach; bool dpb_map_attach;
ULONG dpb_remote_flags;
// here begin compound objects // here begin compound objects
// for constructor to work properly dpb_user_name // for constructor to work properly dpb_user_name
// MUST be FIRST // MUST be FIRST
string dpb_user_name; string dpb_user_name;
AuthReader::AuthBlock dpb_auth_block; AuthReader::AuthBlock dpb_auth_block;
string dpb_role_name; string dpb_role_name;
string dpb_journal; string dpb_journal;
string dpb_lc_ctype; string dpb_lc_ctype;
PathName dpb_working_directory; PathName dpb_working_directory;
skipping to change at line 1583 skipping to change at line 1601
CCH_init(tdbb, options.dpb_buffers); CCH_init(tdbb, options.dpb_buffers);
dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_perman ent) TipCache(dbb); dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_perman ent) TipCache(dbb);
// Initialize backup difference subsystem. This m ust be done before WAL and shadowing // Initialize backup difference subsystem. This m ust be done before WAL and shadowing
// is enabled because nbackup it is a lower level subsystem // is enabled because nbackup it is a lower level subsystem
dbb->dbb_backup_manager = FB_NEW_POOL(*dbb->dbb_p ermanent) BackupManager(tdbb, dbb->dbb_backup_manager = FB_NEW_POOL(*dbb->dbb_p ermanent) BackupManager(tdbb,
dbb, Ods::hdr_nbak_unknown); dbb, Ods::hdr_nbak_unknown);
dbb->dbb_backup_manager->initializeAlloc(tdbb); dbb->dbb_backup_manager->initializeAlloc(tdbb);
dbb->dbb_crypto_manager = FB_NEW_POOL(*dbb->dbb_p ermanent) CryptoManager(tdbb); dbb->dbb_crypto_manager = FB_NEW_POOL(*dbb->dbb_p ermanent) CryptoManager(tdbb);
dbb->dbb_monitoring_data = FB_NEW_POOL(*dbb->dbb_ permanent) MonitoringData(dbb);
PAG_init2(tdbb, 0); PAG_init2(tdbb, 0);
PAG_header(tdbb, false); PAG_header(tdbb, false);
dbb->dbb_page_manager.initTempPageSpace(tdbb); dbb->dbb_page_manager.initTempPageSpace(tdbb);
dbb->dbb_crypto_manager->attach(tdbb, attachment) ; dbb->dbb_crypto_manager->attach(tdbb, attachment) ;
// initialize shadowing as soon as the database i s ready for it // initialize shadowing as soon as the database i s ready for it
// but before any real work is done // but before any real work is done
SDW_init(tdbb, options.dpb_activate_shadow, optio ns.dpb_delete_shadow); SDW_init(tdbb, options.dpb_activate_shadow, optio ns.dpb_delete_shadow);
skipping to change at line 2677 skipping to change at line 2696
dbb->dbb_database_name = dbb->dbb_filename; dbb->dbb_database_name = dbb->dbb_filename;
dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_permanent) Tip Cache(dbb); dbb->dbb_tip_cache = FB_NEW_POOL(*dbb->dbb_permanent) Tip Cache(dbb);
// Initialize backup difference subsystem. This must be d one before WAL and shadowing // Initialize backup difference subsystem. This must be d one before WAL and shadowing
// is enabled because nbackup it is a lower level subsyst em // is enabled because nbackup it is a lower level subsyst em
dbb->dbb_backup_manager = FB_NEW_POOL(*dbb->dbb_permanent ) BackupManager(tdbb, dbb->dbb_backup_manager = FB_NEW_POOL(*dbb->dbb_permanent ) BackupManager(tdbb,
dbb, Ods::hdr_nbak_normal); dbb, Ods::hdr_nbak_normal);
dbb->dbb_backup_manager->dbCreating = true; dbb->dbb_backup_manager->dbCreating = true;
dbb->dbb_crypto_manager = FB_NEW_POOL(*dbb->dbb_permanent ) CryptoManager(tdbb); dbb->dbb_crypto_manager = FB_NEW_POOL(*dbb->dbb_permanent ) CryptoManager(tdbb);
dbb->dbb_monitoring_data = FB_NEW_POOL(*dbb->dbb_permanen t) MonitoringData(dbb);
PAG_format_header(tdbb); PAG_format_header(tdbb);
INI_init2(tdbb); INI_init2(tdbb);
PAG_format_pip(tdbb, *pageSpace); PAG_format_pip(tdbb, *pageSpace);
dbb->dbb_page_manager.initTempPageSpace(tdbb); dbb->dbb_page_manager.initTempPageSpace(tdbb);
if (options.dpb_set_page_buffers) if (options.dpb_set_page_buffers)
PAG_set_page_buffers(tdbb, options.dpb_page_buffe rs); PAG_set_page_buffers(tdbb, options.dpb_page_buffe rs);
skipping to change at line 2848 skipping to change at line 2868
/************************************** /**************************************
* *
* g d s _ $ d e t a c h * g d s _ $ d e t a c h
* *
************************************** **************************************
* *
* Functional description * Functional description
* Close down a database. * Close down a database.
* *
**************************************/ **************************************/
if (!att->getHandle())
return; // already detached
RefDeb(DEB_RLS_JATT, "JAttachment::detach"); RefDeb(DEB_RLS_JATT, "JAttachment::detach");
freeEngineData(user_status, false); freeEngineData(user_status, false);
} }
void JAttachment::freeEngineData(CheckStatusWrapper* user_status, bool forceFree ) void JAttachment::freeEngineData(CheckStatusWrapper* user_status, bool forceFree )
{ {
/************************************** /**************************************
* *
* f r e e E n g i n e D a t a * f r e e E n g i n e D a t a
* *
skipping to change at line 2902 skipping to change at line 2925
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
transliterateException(tdbb, ex, user_status, "JAttachmen t::freeEngineData"); transliterateException(tdbb, ex, user_status, "JAttachmen t::freeEngineData");
return; return;
} }
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
ex.stuffException(user_status); ex.stuffException(user_status);
return; if (user_status->getErrors()[1] != isc_att_shutdown)
return;
else
{
user_status->init();
if (att)
{
att->release();
att = NULL;
}
}
} }
successful_completion(user_status); successful_completion(user_status);
} }
void JAttachment::dropDatabase(CheckStatusWrapper* user_status) void JAttachment::dropDatabase(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
* i s c _ d r o p _ d a t a b a s e * i s c _ d r o p _ d a t a b a s e
skipping to change at line 2947 skipping to change at line 2980
try try
{ {
Sync sync(&dbb->dbb_sync, "JAttachment::dropDatab ase()"); Sync sync(&dbb->dbb_sync, "JAttachment::dropDatab ase()");
if (attachment->att_in_use || attachment->att_use _count) if (attachment->att_in_use || attachment->att_use _count)
status_exception::raise(Arg::Gds(isc_atta chment_in_use)); status_exception::raise(Arg::Gds(isc_atta chment_in_use));
const PathName& file_name = attachment->att_filen ame; const PathName& file_name = attachment->att_filen ame;
if (!attachment->locksmith()) SCL_check_database(tdbb, SCL_drop);
{
ERR_post(Arg::Gds(isc_no_priv) << Arg::St
r("drop") <<
Arg::Str("database") <<
Arg::Str(file_name));
}
if (attachment->att_flags & ATT_shutdown) if (attachment->att_flags & ATT_shutdown)
{ {
if (dbb->dbb_ast_flags & DBB_shutdown) if (dbb->dbb_ast_flags & DBB_shutdown)
{ {
ERR_post(Arg::Gds(isc_shutdown) < < Arg::Str(file_name)); ERR_post(Arg::Gds(isc_shutdown) < < Arg::Str(file_name));
} }
else else
{ {
ERR_post(Arg::Gds(isc_att_shutdow n)); ERR_post(Arg::Gds(isc_att_shutdow n));
skipping to change at line 3191 skipping to change at line 3219
{ {
EngineContextHolder tdbb(user_status, this, FB_FUNCTION); EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
validateHandle(tdbb, getEngineTransaction(user_status, tra)); validateHandle(tdbb, getEngineTransaction(user_status, tra));
check_database(tdbb); check_database(tdbb);
try try
{ {
jrd_tra* const transaction = find_transaction(tdbb); jrd_tra* const transaction = find_transaction(tdbb);
blob = blb::open2(tdbb, transaction, reinterpret_cast<bid const bid* id = reinterpret_cast<bid*>(blob_id);
*>(blob_id),
bpb_length, bpb, true); if (blob_id->gds_quad_high)
transaction->checkBlob(tdbb, id, true);
blob = blb::open2(tdbb, transaction, id, bpb_length, bpb,
true);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
transliterateException(tdbb, ex, user_status, "JAttachmen t::openBlob"); transliterateException(tdbb, ex, user_status, "JAttachmen t::openBlob");
return NULL; return NULL;
} }
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
ex.stuffException(user_status); ex.stuffException(user_status);
skipping to change at line 4147 skipping to change at line 4179
start_transaction(tdbb, true, &tra, getHandle(), tpbLength, tpb); start_transaction(tdbb, true, &tra, getHandle(), tpbLength, tpb);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
ex.stuffException(user_status); ex.stuffException(user_status);
return NULL; return NULL;
} }
successful_completion(user_status); successful_completion(user_status);
JTransaction* jt = FB_NEW JTransaction(tra, getStable()); JTransaction* jt = tra->getInterface(false);
tra->setInterface(jt);
jt->addRef(); if (jt)
tra->tra_flags &= ~TRA_own_interface;
else
{
jt = FB_NEW JTransaction(tra, getStable());
tra->setInterface(jt);
jt->addRef();
}
return jt; return jt;
} }
void JAttachment::transactRequest(CheckStatusWrapper* user_status, ITransaction* tra, void JAttachment::transactRequest(CheckStatusWrapper* user_status, ITransaction* tra,
unsigned int blr_length, const unsigned char* blr, unsigned int blr_length, const unsigned char* blr,
unsigned int in_msg_length, const unsigned char* in_msg, unsigned int in_msg_length, const unsigned char* in_msg,
unsigned int out_msg_length, unsigned char* out_msg) unsigned int out_msg_length, unsigned char* out_msg)
{ {
/************************************** /**************************************
* *
skipping to change at line 5819 skipping to change at line 5859
while (!address.isEof()) while (!address.isEof())
{ {
switch (address.getClumpTag()) switch (address.getClumpTag())
{ {
case isc_dpb_addr_protoco l: case isc_dpb_addr_protoco l:
address.getString (dpb_network_protocol); address.getString (dpb_network_protocol);
break; break;
case isc_dpb_addr_endpoin t: case isc_dpb_addr_endpoin t:
address.getString (dpb_remote_address); address.getString (dpb_remote_address);
break; break;
case isc_dpb_addr_flags:
dpb_remote_flags
= address.getInt();
break;
default: default:
break; break;
} }
address.moveNext(); address.moveNext();
} }
break; break;
} }
} }
break; break;
skipping to change at line 6005 skipping to change at line 6048
ERR_post(Arg::Gds(isc_no_meta_update) << ERR_post(Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_obj_in_use) << Arg::Str("DATABASE")); Arg::Gds(isc_obj_in_use) << Arg::Str("DATABASE"));
} }
dbb = dbb->dbb_next; dbb = dbb->dbb_next;
} }
} }
Config::merge(config, &options.dpb_config); Config::merge(config, &options.dpb_config);
dbb = Database::create(pConf, provider, shared); dbb = Database::create(pConf, shared);
dbb->dbb_config = config; dbb->dbb_config = config;
dbb->dbb_filename = expanded_name; dbb->dbb_filename = expanded_name;
dbb->dbb_callback = provider->getCryptCallback();
#ifdef HAVE_ID_BY_NAME #ifdef HAVE_ID_BY_NAME
dbb->dbb_id = db_id; // will be reassigned in create d atabase after PIO operation dbb->dbb_id = db_id; // will be reassigned in create d atabase after PIO operation
#endif #endif
// safely take init lock on just created database // safely take init lock on just created database
initGuard.linkWith(dbb->dbb_init_fini); initGuard.linkWith(dbb->dbb_init_fini);
initGuard.enter(); initGuard.enter();
dbb->dbb_next = databases; dbb->dbb_next = databases;
databases = dbb; databases = dbb;
skipping to change at line 6097 skipping to change at line 6141
attachment = Jrd::Attachment::create(dbb); attachment = Jrd::Attachment::create(dbb);
attachment->att_next = dbb->dbb_attachments; attachment->att_next = dbb->dbb_attachments;
dbb->dbb_attachments = attachment; dbb->dbb_attachments = attachment;
} }
attachment->att_filename = alias_name; attachment->att_filename = alias_name;
attachment->att_network_protocol = options.dpb_network_protocol; attachment->att_network_protocol = options.dpb_network_protocol;
attachment->att_remote_address = options.dpb_remote_address; attachment->att_remote_address = options.dpb_remote_address;
attachment->att_remote_pid = options.dpb_remote_pid; attachment->att_remote_pid = options.dpb_remote_pid;
attachment->att_remote_flags = options.dpb_remote_flags;
attachment->att_remote_process = options.dpb_remote_process; attachment->att_remote_process = options.dpb_remote_process;
attachment->att_remote_host = options.dpb_remote_host; attachment->att_remote_host = options.dpb_remote_host;
attachment->att_remote_os_user = options.dpb_remote_os_user; attachment->att_remote_os_user = options.dpb_remote_os_user;
attachment->att_client_version = options.dpb_client_version; attachment->att_client_version = options.dpb_client_version;
attachment->att_remote_protocol = options.dpb_remote_protocol; attachment->att_remote_protocol = options.dpb_remote_protocol;
attachment->att_ext_call_depth = options.dpb_ext_call_depth; attachment->att_ext_call_depth = options.dpb_ext_call_depth;
StableAttachmentPart* sAtt = FB_NEW StableAttachmentPart(attachment); StableAttachmentPart* sAtt = FB_NEW StableAttachmentPart(attachment);
attachment->setStable(sAtt); attachment->setStable(sAtt);
sAtt->addRef(); sAtt->addRef();
skipping to change at line 6229 skipping to change at line 6274
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
fb_assert(!dbb->locked()); fb_assert(!dbb->locked());
if (!attachment) if (!attachment)
return; return;
if (dbb->dbb_crypto_manager)
dbb->dbb_crypto_manager->detach(tdbb, attachment);
Monitoring::cleanupAttachment(tdbb); Monitoring::cleanupAttachment(tdbb);
dbb->dbb_extManager.closeAttachment(tdbb, attachment); dbb->dbb_extManager.closeAttachment(tdbb, attachment);
if ((dbb->dbb_config->getServerMode() == MODE_SUPER) && attachment->att_r elations) if ((dbb->dbb_config->getServerMode() == MODE_SUPER) && attachment->att_r elations)
{ {
vec<jrd_rel*>& rels = *attachment->att_relations; vec<jrd_rel*>& rels = *attachment->att_relations;
for (FB_SIZE_T i = 1; i < rels.count(); i++) for (FB_SIZE_T i = 1; i < rels.count(); i++)
{ {
jrd_rel* relation = rels[i]; jrd_rel* relation = rels[i];
skipping to change at line 6652 skipping to change at line 6700
* *
************************************** **************************************
* *
* Functional description * Functional description
* Release or rollback transaction depending upon prepared it or not. * Release or rollback transaction depending upon prepared it or not.
* *
**************************************/ **************************************/
try try
{ {
EngineContextHolder tdbb(user_status, this, FB_FUNCTION); EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
check_database(tdbb); check_database(tdbb, true);
try try
{ {
if (transaction->tra_flags & TRA_prepared) if (transaction->tra_flags & TRA_prepared)
{ {
TraceTransactionEnd trace(transaction, false, fal se); TraceTransactionEnd trace(transaction, false, fal se);
EDS::Transaction::jrdTransactionEnd(tdbb, transac tion, false, false, false); EDS::Transaction::jrdTransactionEnd(tdbb, transac tion, false, false, false);
TRA_release_transaction(tdbb, transaction, &trace ); TRA_release_transaction(tdbb, transaction, &trace );
} }
else else
skipping to change at line 6675 skipping to change at line 6723
transaction = NULL; transaction = NULL;
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
transliterateException(tdbb, ex, user_status, "JTransacti on::freeEngineData"); transliterateException(tdbb, ex, user_status, "JTransacti on::freeEngineData");
return; return;
} }
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
transaction = NULL;
ex.stuffException(user_status); ex.stuffException(user_status);
return; return;
} }
successful_completion(user_status); successful_completion(user_status);
} }
static void purge_transactions(thread_db* tdbb, Jrd::Attachment* attachment, con st bool force_flag) static void purge_transactions(thread_db* tdbb, Jrd::Attachment* attachment, con st bool force_flag)
{ {
/************************************** /**************************************
skipping to change at line 6929 skipping to change at line 6978
if (!sAtt->getHandle()) if (!sAtt->getHandle())
return; return;
bool overwriteCheck = attachment->att_flags & ATT_overwrite_check; bool overwriteCheck = attachment->att_flags & ATT_overwrite_check;
// Unlink attachment from database // Unlink attachment from database
release_attachment(tdbb, attachment); release_attachment(tdbb, attachment);
asyncGuard.leave(); asyncGuard.leave();
MutexUnlockGuard cout(*attMutex, FB_FUNCTION); MutexUnlockGuard cout(*attMutex, FB_FUNCTION);
MutexUnlockGuard coutBlocking(*sAtt->getBlockingMutex(), FB_FUNCTION);
// Try to close database if there are no attachments // Try to close database if there are no attachments
JRD_shutdown_database(dbb, SHUT_DBB_RELEASE_POOLS | (flags & PURGE_LINGER ? SHUT_DBB_LINGER : 0) | JRD_shutdown_database(dbb, SHUT_DBB_RELEASE_POOLS | (flags & PURGE_LINGER ? SHUT_DBB_LINGER : 0) |
(overwriteCheck ? SHUT_DBB_OVERWRITE_CHECK : 0)); (overwriteCheck ? SHUT_DBB_OVERWRITE_CHECK : 0));
} }
static void run_commit_triggers(thread_db* tdbb, jrd_tra* transaction) static void run_commit_triggers(thread_db* tdbb, jrd_tra* transaction)
{ {
/************************************** /**************************************
* *
skipping to change at line 7151 skipping to change at line 7201
RefDeb(DEB_RLS_JATT, "unwindAttach"); RefDeb(DEB_RLS_JATT, "unwindAttach");
RefDeb(DEB_AR_JATT, "unwindAttach"); RefDeb(DEB_AR_JATT, "unwindAttach");
transliterateException(tdbb, ex, userStatus, NULL); transliterateException(tdbb, ex, userStatus, NULL);
try try
{ {
if (dbb) if (dbb)
{ {
fb_assert(!dbb->locked()); fb_assert(!dbb->locked());
ThreadStatusGuard temp_status(tdbb); ThreadStatusGuard temp_status(tdbb);
StableAttachmentPart* sAtt = NULL;
if (attachment) if (attachment)
{ {
// A number of holders to make Attachment::destro y() happy // A number of holders to make Attachment::destro y() happy
// See also addRef() in create_attachment() // StablePart will be released in JAttachment::re
sAtt = attachment->getStable(); lease
RefPtr<StableAttachmentPart> sAtt(attachment->get
Stable());
// Will release addRef() addedin create_attachme
nt()
RefPtr<JAttachment> jAtt(REF_NO_INCR, sAtt->getIn terface()); RefPtr<JAttachment> jAtt(REF_NO_INCR, sAtt->getIn terface());
// This unlocking/locking order guarantees stable release of attachment // This unlocking/locking order guarantees stable release of attachment
sAtt->manualUnlock(attachment->att_flags); sAtt->manualUnlock(attachment->att_flags);
ULONG flags = 0; // att_flags may already not exist here! ULONG flags = 0; // att_flags may already not exist here!
sAtt->manualLock(flags); sAtt->manualLock(flags);
if (sAtt->getHandle()) if (sAtt->getHandle())
{ {
attachment->att_flags |= flags; attachment->att_flags |= flags;
release_attachment(tdbb, attachment); release_attachment(tdbb, attachment);
} }
else else
{ {
sAtt->manualUnlock(flags); sAtt->manualUnlock(flags);
} }
} }
if (sAtt)
{
sAtt->release();
}
JRD_shutdown_database(dbb, SHUT_DBB_RELEASE_POOLS | JRD_shutdown_database(dbb, SHUT_DBB_RELEASE_POOLS |
(internalFlag ? SHUT_DBB_OVERWRITE_CHECK : 0)); (internalFlag ? SHUT_DBB_OVERWRITE_CHECK : 0));
} }
} }
catch (const Exception&) catch (const Exception&)
{ {
// no-op // no-op
} }
return; return;
skipping to change at line 7210 skipping to change at line 7255
if (signal) if (signal)
{ {
// Set terminate flag for all attachments // Set terminate flag for all attachments
for (AttachmentsRefHolder::Iterator iter(attachments); *i ter; ++iter) for (AttachmentsRefHolder::Iterator iter(attachments); *i ter; ++iter)
{ {
StableAttachmentPart* const sAtt = *iter; StableAttachmentPart* const sAtt = *iter;
MutexLockGuard guard(*(sAtt->getMutex(true)), FB_ FUNCTION); MutexLockGuard guard(*(sAtt->getMutex(true)), FB_ FUNCTION);
Attachment* attachment = sAtt->getHandle(); Attachment* const attachment = sAtt->getHandle();
if (attachment) if (attachment && !(attachment->att_flags & ATT_s hutdown))
attachment->signalShutdown(); attachment->signalShutdown();
} }
} }
// Purge all attachments // Purge all attachments
for (AttachmentsRefHolder::Iterator iter(attachments); *iter; ++i ter) for (AttachmentsRefHolder::Iterator iter(attachments); *iter; ++i ter)
{ {
StableAttachmentPart* const sAtt = *iter; StableAttachmentPart* const sAtt = *iter;
MutexLockGuard guardBlocking(*(sAtt->getBlockingMutex()), FB_FUNCTION);
MutexLockGuard guard(*(sAtt->getMutex()), FB_FUNCTION); MutexLockGuard guard(*(sAtt->getMutex()), FB_FUNCTION);
Attachment* attachment = sAtt->getHandle(); Attachment* attachment = sAtt->getHandle();
if (attachment) if (attachment)
{ {
ThreadContextHolder tdbb; ThreadContextHolder tdbb;
tdbb->setAttachment(attachment); tdbb->setAttachment(attachment);
tdbb->setDatabase(attachment->att_database); tdbb->setDatabase(attachment->att_database);
try try
skipping to change at line 7256 skipping to change at line 7302
if (attachment) if (attachment)
attachment->att_use_count--; attachment->att_use_count--;
} }
} }
return success; return success;
} }
THREAD_ENTRY_DECLARE attachmentShutdownThread(THREAD_ENTRY_PARAM arg) THREAD_ENTRY_DECLARE attachmentShutdownThread(THREAD_ENTRY_PARAM arg)
{ {
#ifdef WIN_NT
ThreadModuleRef thdRef(attachmentShutdownThread, &engineShutdown)
;
#endif
try try
{ {
MutexLockGuard guard(shutdownMutex, FB_FUNCTION); MutexLockGuard guard(shutdownMutex, FB_FUNCTION);
if (engineShutdown) if (engineShutdown)
{ {
// Shutdown was done, all attachmnets are gone // Shutdown was done, all attachments are gone
return 0; return 0;
} }
shutdownAttachments(static_cast<AttachmentsRefHolder*>(ar g), false); shutdownAttachments(static_cast<AttachmentsRefHolder*>(ar g), false);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
iscLogException("attachmentShutdownThread", ex); iscLogException("attachmentShutdownThread", ex);
} }
skipping to change at line 7338 skipping to change at line 7388
// No need in databases_mutex any more // No need in databases_mutex any more
} }
for (unsigned n = 0; n < dbArray.getCount(); ++n) for (unsigned n = 0; n < dbArray.getCount(); ++n)
{ {
JRD_shutdown_database(dbArray[n], SHUT_DBB_RELEASE_POOLS) ; JRD_shutdown_database(dbArray[n], SHUT_DBB_RELEASE_POOLS) ;
} }
// Extra shutdown operations // Extra shutdown operations
Service::shutdownServices(); Service::shutdownServices();
} }
catch (const Exception&) catch (const Exception& ex)
{ {
success = false; success = false;
iscLogException("Error at shutdown_thread", ex);
} }
if (success && semaphore) if (success && semaphore)
{ {
semaphore->release(); semaphore->release();
} }
return 0; return 0;
} }
skipping to change at line 7684 skipping to change at line 7735
check_autocommit(tdbb, request); check_autocommit(tdbb, request);
if (request->req_flags & req_warning) if (request->req_flags & req_warning)
{ {
request->req_flags &= ~req_warning; request->req_flags &= ~req_warning;
ERR_punt(); ERR_punt();
} }
} }
void JRD_run_trans_start_triggers(thread_db* tdbb, jrd_tra* transaction)
{
/**************************************
*
* Run TRIGGER_TRANS_START, rollback transaction on failure.
* Handle rollback error, re-throw trigger error
*
**************************************/
try
{
EXE_execute_db_triggers(tdbb, transaction, TRIGGER_TRANS_START);
}
catch (const Exception&)
{
try
{
TRA_rollback(tdbb, transaction, false, false);
}
catch (const Exception& ex2)
{
if (tdbb->getDatabase()->dbb_flags & DBB_bugcheck)
throw;
iscLogException("Error rolling back new transaction", ex2
);
}
throw;
}
}
static void start_transaction(thread_db* tdbb, bool transliterate, jrd_tra** tra _handle, static void start_transaction(thread_db* tdbb, bool transliterate, jrd_tra** tra _handle,
Jrd::Attachment* attachment, unsigned int tpb_length, const UCHAR* tpb) Jrd::Attachment* attachment, unsigned int tpb_length, const UCHAR* tpb)
{ {
/************************************** /**************************************
* *
* s t a r t _ m u l t i p l e * s t a r t _ m u l t i p l e
* *
************************************** **************************************
* *
* Functional description * Functional description
skipping to change at line 7711 skipping to change at line 7793
if (*tra_handle) if (*tra_handle)
status_exception::raise(Arg::Gds(isc_bad_trans_handle)); status_exception::raise(Arg::Gds(isc_bad_trans_handle));
try try
{ {
if (tpb_length > 0 && !tpb) if (tpb_length > 0 && !tpb)
status_exception::raise(Arg::Gds(isc_bad_tpb_form )); status_exception::raise(Arg::Gds(isc_bad_tpb_form ));
jrd_tra* transaction = TRA_start(tdbb, tpb_length, tpb); jrd_tra* transaction = TRA_start(tdbb, tpb_length, tpb);
*tra_handle = transaction;
// run ON TRANSACTION START triggers // run ON TRANSACTION START triggers
EXE_execute_db_triggers(tdbb, transaction, TRIGGER_TRANS_ JRD_run_trans_start_triggers(tdbb, transaction);
START);
*tra_handle = transaction;
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
if (transliterate) if (transliterate)
{ {
FbLocalStatus tempStatus; FbLocalStatus tempStatus;
transliterateException(tdbb, ex, &tempStatus, "st artTransaction"); transliterateException(tdbb, ex, &tempStatus, "st artTransaction");
status_exception::raise(&tempStatus); status_exception::raise(&tempStatus);
} }
throw; throw;
skipping to change at line 7864 skipping to change at line 7946
************************************** **************************************
* *
* Functional description * Functional description
* Schedule the attachment marked as shutdown for disconnection. * Schedule the attachment marked as shutdown for disconnection.
* *
**************************************/ **************************************/
fb_assert(attachment); fb_assert(attachment);
try try
{ {
fb_assert(attachment->att_flags & ATT_shutdown);
MemoryPool& pool = *getDefaultMemoryPool(); MemoryPool& pool = *getDefaultMemoryPool();
AttachmentsRefHolder* queue = FB_NEW_POOL(pool) AttachmentsRefHol der(pool); AutoPtr<AttachmentsRefHolder> queue(FB_NEW_POOL(pool) Attachments RefHolder(pool));
fb_assert(attachment->getStable());
attachment->getStable()->addRef();
queue->add(attachment->getStable()); queue->add(attachment->getStable());
Thread::start(attachmentShutdownThread, queue, 0); if (!(attachment->att_flags & ATT_shutdown))
attachment->signalShutdown();
Thread::start(attachmentShutdownThread, queue.release(), THREAD_h
igh);
} }
catch (const Exception&) catch (const Exception&)
{} // no-op {} // no-op
} }
void JRD_shutdown_attachments(Database* dbb) void JRD_shutdown_attachments(Database* dbb)
{ {
/************************************** /**************************************
* *
* J R D _ s h u t d o w n _ a t t a c h m e n t s * J R D _ s h u t d o w n _ a t t a c h m e n t s
skipping to change at line 7898 skipping to change at line 7979
* Schedule the attachments marked as shutdown for disconnection. * Schedule the attachments marked as shutdown for disconnection.
* *
**************************************/ **************************************/
fb_assert(dbb); fb_assert(dbb);
try try
{ {
MemoryPool& pool = *getDefaultMemoryPool(); MemoryPool& pool = *getDefaultMemoryPool();
AutoPtr<AttachmentsRefHolder> queue(FB_NEW_POOL(pool) Attachments RefHolder(pool)); AutoPtr<AttachmentsRefHolder> queue(FB_NEW_POOL(pool) Attachments RefHolder(pool));
// Collect attachments to shut down
{ // scope { // scope
Sync guard(&dbb->dbb_sync, "JRD_shutdown_attachments"); Sync guard(&dbb->dbb_sync, FB_FUNCTION);
if (!dbb->dbb_sync.ourExclusiveLock()) if (!dbb->dbb_sync.ourExclusiveLock())
guard.lock(SYNC_SHARED); guard.lock(SYNC_SHARED);
for (Jrd::Attachment* attachment = dbb->dbb_attachments; for (Jrd::Attachment* attachment = dbb->dbb_attachments;
attachment; attachment; attachment = attachment->att_next)
attachment = attachment->att_next)
{ {
if (attachment->att_flags & ATT_shutdown) if (!(attachment->att_flags & ATT_shutdown_manage
{ r))
fb_assert(attachment->getStable());
attachment->getStable()->addRef();
queue->add(attachment->getStable()); queue->add(attachment->getStable());
}
} }
} }
if (queue.hasData()) if (queue->hasData())
Thread::start(attachmentShutdownThread, queue.release(), {
0); // Signal attachments for termination
for (AttachmentsRefHolder::Iterator iter(*queue); *iter;
++iter)
{
StableAttachmentPart* const sAtt = *iter;
MutexLockGuard guard(*(sAtt->getMutex(true)), FB_
FUNCTION);
Attachment* const attachment = sAtt->getHandle();
if (attachment && !(attachment->att_flags & ATT_s
hutdown))
attachment->signalShutdown();
}
Thread::start(attachmentShutdownThread, queue.release(),
THREAD_high);
}
} }
catch (const Exception&) catch (const Exception&)
{} // no-op {} // no-op
} }
void JRD_cancel_operation(thread_db* /*tdbb*/, Jrd::Attachment* attachment, int option) void JRD_cancel_operation(thread_db* /*tdbb*/, Jrd::Attachment* attachment, int option)
{ {
/************************************** /**************************************
* *
* J R D _ c a n c e l _ o p e r a t i o n * J R D _ c a n c e l _ o p e r a t i o n
skipping to change at line 7956 skipping to change at line 8049
// to avoid unexpected CANCEL (though it should not be se t, but...) // to avoid unexpected CANCEL (though it should not be se t, but...)
attachment->att_flags &= ~(ATT_cancel_disable | ATT_cance l_raise); attachment->att_flags &= ~(ATT_cancel_disable | ATT_cance l_raise);
} }
break; break;
case fb_cancel_raise: case fb_cancel_raise:
if (!(attachment->att_flags & ATT_cancel_disable)) if (!(attachment->att_flags & ATT_cancel_disable))
attachment->signalCancel(); attachment->signalCancel();
break; break;
case fb_cancel_abort:
if (!(attachment->att_flags & ATT_shutdown))
attachment->signalShutdown();
break;
default: default:
fb_assert(false); fb_assert(false);
} }
} }
void TrigVector::release() const void TrigVector::release() const
{ {
release(JRD_get_thread_data()); release(JRD_get_thread_data());
} }
 End of changes. 46 change blocks. 
55 lines changed or deleted 160 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)