mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 03:23:03 +01:00
1) Make enumeration and shutdown routines SuperClassic friendly.
2) Cleanup and minor refactoring of the Classic shutdown routines.
This commit is contained in:
parent
8291af3c5c
commit
7ae3eb5977
@ -254,6 +254,21 @@ public:
|
|||||||
data = this->getStorage();
|
data = this->getStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool find(const T& item, size_t& pos) const {
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (data[i] == item) {
|
||||||
|
pos = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exist(const T& item) const {
|
||||||
|
size_t pos; // ignored
|
||||||
|
return find(item, pos);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t count, capacity;
|
size_t count, capacity;
|
||||||
T* data;
|
T* data;
|
||||||
@ -289,8 +304,6 @@ public:
|
|||||||
explicit SortedArray(size_t s) : Array<Value, Storage>(s) {}
|
explicit SortedArray(size_t s) : Array<Value, Storage>(s) {}
|
||||||
SortedArray() : Array<Value, Storage>() {}
|
SortedArray() : Array<Value, Storage>() {}
|
||||||
|
|
||||||
// NOTE: find method must be signal safe
|
|
||||||
// Used as such in GlobalRWLock::blockingAstHandler
|
|
||||||
bool find(const Key& item, size_t& pos) const {
|
bool find(const Key& item, size_t& pos) const {
|
||||||
size_t highBound = this->count, lowBound = 0;
|
size_t highBound = this->count, lowBound = 0;
|
||||||
while (highBound > lowBound) {
|
while (highBound > lowBound) {
|
||||||
|
183
src/jrd/jrd.cpp
183
src/jrd/jrd.cpp
@ -4895,10 +4895,8 @@ static Database* init(thread_db* tdbb,
|
|||||||
// provide context pool for the rest stuff
|
// provide context pool for the rest stuff
|
||||||
Jrd::ContextPoolHolder context(tdbb, perm);
|
Jrd::ContextPoolHolder context(tdbb, perm);
|
||||||
|
|
||||||
#ifdef SUPERSERVER
|
|
||||||
dbb->dbb_next = databases;
|
dbb->dbb_next = databases;
|
||||||
databases = dbb;
|
databases = dbb;
|
||||||
#endif
|
|
||||||
|
|
||||||
dbb->dbb_mutexes = FB_NEW(*dbb->dbb_permanent) Firebird::Mutex[DBB_MUTX_max];
|
dbb->dbb_mutexes = FB_NEW(*dbb->dbb_permanent) Firebird::Mutex[DBB_MUTX_max];
|
||||||
dbb->dbb_internal = vec<jrd_req*>::newVector(*dbb->dbb_permanent, irq_MAX);
|
dbb->dbb_internal = vec<jrd_req*>::newVector(*dbb->dbb_permanent, irq_MAX);
|
||||||
@ -5431,7 +5429,7 @@ static void strip_quotes(Firebird::string& out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool shutdown_dbb(thread_db* tdbb, Database* dbb, Attachment** released)
|
static bool shutdown_dbb(thread_db* tdbb, Database* dbb)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -5471,26 +5469,11 @@ static bool shutdown_dbb(thread_db* tdbb, Database* dbb, Attachment** released)
|
|||||||
}
|
}
|
||||||
catch (const Firebird::Exception&)
|
catch (const Firebird::Exception&)
|
||||||
{
|
{
|
||||||
if (released)
|
|
||||||
{
|
|
||||||
*released = NULL;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// attach became invalid pointer
|
|
||||||
// if we have someone interested in that fact, inform him
|
|
||||||
if (released)
|
|
||||||
{
|
|
||||||
*released++ = attach;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (released)
|
|
||||||
{
|
|
||||||
*released = NULL;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5511,7 +5494,8 @@ static bool shutdown_all()
|
|||||||
**************************************/
|
**************************************/
|
||||||
ThreadContextHolder tdbb;
|
ThreadContextHolder tdbb;
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
Firebird::MutexLockGuard guard(databases_mutex);
|
Firebird::MutexLockGuard guard(databases_mutex);
|
||||||
|
|
||||||
Database* dbb_next;
|
Database* dbb_next;
|
||||||
@ -5519,7 +5503,7 @@ static bool shutdown_all()
|
|||||||
{
|
{
|
||||||
dbb_next = dbb->dbb_next;
|
dbb_next = dbb->dbb_next;
|
||||||
|
|
||||||
if (!shutdown_dbb(tdbb, dbb, NULL))
|
if (!shutdown_dbb(tdbb, dbb))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -5534,7 +5518,6 @@ static bool shutdown_all()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SERVER_SHUTDOWN
|
|
||||||
TEXT* JRD_num_attachments(TEXT* const buf, USHORT buf_len, USHORT flag,
|
TEXT* JRD_num_attachments(TEXT* const buf, USHORT buf_len, USHORT flag,
|
||||||
ULONG* atts, ULONG* dbs)
|
ULONG* atts, ULONG* dbs)
|
||||||
{
|
{
|
||||||
@ -5573,86 +5556,82 @@ TEXT* JRD_num_attachments(TEXT* const buf, USHORT buf_len, USHORT flag,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ULONG num_dbs = 0;
|
|
||||||
ULONG num_att = 0;
|
ULONG num_att = 0;
|
||||||
ULONG drive_mask = 0L;
|
ULONG drive_mask = 0L;
|
||||||
USHORT total = 0;
|
USHORT total = 0;
|
||||||
Firebird::HalfStaticArray<Firebird::PathName, 8> dbFiles;
|
Firebird::HalfStaticArray<Firebird::PathName, 8> dbFiles;
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
|
||||||
databases_mutex->enter();
|
|
||||||
|
|
||||||
// Zip through the list of databases and count the number of local
|
|
||||||
// connections. If buf is not NULL then copy all the database names
|
|
||||||
// that will fit into it.
|
|
||||||
|
|
||||||
for (Database* dbb = databases; dbb; dbb = dbb->dbb_next)
|
|
||||||
{
|
{
|
||||||
Database::SyncGuard dsGuard(dbb);
|
Firebird::MutexLockGuard guard(databases_mutex);
|
||||||
|
|
||||||
|
// Zip through the list of databases and count the number of local
|
||||||
|
// connections. If buf is not NULL then copy all the database names
|
||||||
|
// that will fit into it.
|
||||||
|
|
||||||
|
for (Database* dbb = databases; dbb; dbb = dbb->dbb_next)
|
||||||
|
{
|
||||||
|
Database::SyncGuard dsGuard(dbb);
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
// Get drive letters for db files
|
// Get drive letters for db files
|
||||||
|
|
||||||
if (flag == JRD_info_drivemask)
|
if (flag == JRD_info_drivemask)
|
||||||
{
|
|
||||||
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
|
||||||
for (jrd_file* files = pageSpace->file; files; files = files->fil_next)
|
|
||||||
ExtractDriveLetter(files->fil_string, &drive_mask);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!(dbb->dbb_flags & (DBB_bugcheck | DBB_not_in_use | DBB_security_db)) &&
|
|
||||||
!(dbb->dbb_ast_flags & DBB_shutdown
|
|
||||||
&& dbb->dbb_ast_flags & DBB_shutdown_locks))
|
|
||||||
{
|
|
||||||
num_dbs++;
|
|
||||||
if (flag == JRD_info_dbnames) {
|
|
||||||
dbFiles.push(dbb->dbb_database_name);
|
|
||||||
total += sizeof(USHORT) + dbb->dbb_database_name.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const Attachment* attach = dbb->dbb_attachments; attach;
|
|
||||||
attach = attach->att_next)
|
|
||||||
{
|
{
|
||||||
num_att++;
|
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||||
|
for (jrd_file* files = pageSpace->file; files; files = files->fil_next)
|
||||||
|
ExtractDriveLetter(files->fil_string, &drive_mask);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(dbb->dbb_flags & (DBB_bugcheck | DBB_not_in_use | DBB_security_db)) &&
|
||||||
|
!(dbb->dbb_ast_flags & DBB_shutdown
|
||||||
|
&& dbb->dbb_ast_flags & DBB_shutdown_locks))
|
||||||
|
{
|
||||||
|
if (!dbFiles.exist(dbb->dbb_filename))
|
||||||
|
dbFiles.add(dbb->dbb_filename);
|
||||||
|
total += sizeof(USHORT) + dbb->dbb_filename.length();
|
||||||
|
|
||||||
|
for (const Attachment* attach = dbb->dbb_attachments; attach;
|
||||||
|
attach = attach->att_next)
|
||||||
|
{
|
||||||
|
num_att++;
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
// Get drive letters for temp directories
|
// Get drive letters for temp directories
|
||||||
|
|
||||||
if (flag == JRD_info_drivemask) {
|
if (flag == JRD_info_drivemask) {
|
||||||
const Firebird::TempDirectoryList dirList;
|
const Firebird::TempDirectoryList dirList;
|
||||||
for (size_t i = 0; i < dirList.getCount(); i++) {
|
for (size_t i = 0; i < dirList.getCount(); i++) {
|
||||||
const Firebird::PathName& path = dirList[i];
|
const Firebird::PathName& path = dirList[i];
|
||||||
ExtractDriveLetter(path.c_str(), &drive_mask);
|
ExtractDriveLetter(path.c_str(), &drive_mask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
databases_mutex->leave();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (const Firebird::Exception&)
|
catch (const Firebird::Exception&)
|
||||||
{
|
{
|
||||||
// Here we ignore possible errors from databases_rec_mutex.
|
// Here we ignore possible errors from databases_mutex.
|
||||||
// They were always silently ignored, and for this function
|
// They were always silently ignored, and for this function
|
||||||
// we really have no way to notify world about mutex problem.
|
// we really have no way to notify world about mutex problem.
|
||||||
// AP. 2008.
|
// AP. 2008.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ULONG num_dbs = dbFiles.getCount();
|
||||||
|
|
||||||
*atts = num_att;
|
*atts = num_att;
|
||||||
*dbs = num_dbs;
|
*dbs = num_dbs;
|
||||||
|
|
||||||
if (dbFiles.getCount() > 0)
|
if (num_dbs > 0)
|
||||||
{
|
{
|
||||||
if (flag == JRD_info_dbnames)
|
if (flag == JRD_info_dbnames)
|
||||||
{
|
{
|
||||||
if (buf_len < (sizeof(USHORT) + total))
|
if (buf_len < (sizeof(USHORT) + total))
|
||||||
{
|
{
|
||||||
lbuf = (TEXT *) gds__alloc((SLONG) (sizeof(USHORT) + total));
|
lbuf = (TEXT *) gds__alloc(sizeof(USHORT) + total);
|
||||||
}
|
}
|
||||||
TEXT* lbufp = lbuf;
|
TEXT* lbufp = lbuf;
|
||||||
if (lbufp)
|
if (lbufp)
|
||||||
@ -5669,19 +5648,15 @@ TEXT* JRD_num_attachments(TEXT* const buf, USHORT buf_len, USHORT flag,
|
|||||||
last db name
|
last db name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lbufp += sizeof(USHORT);
|
*lbufp++ = (TEXT) num_dbs;
|
||||||
total = 0;
|
*lbufp++ = (TEXT) (num_dbs >> 8);
|
||||||
for (size_t n = 0; n < dbFiles.getCount(); ++n) {
|
|
||||||
|
for (size_t n = 0; n < num_dbs; ++n) {
|
||||||
*lbufp++ = (TEXT) dbFiles[n].length();
|
*lbufp++ = (TEXT) dbFiles[n].length();
|
||||||
*lbufp++ = (TEXT) (dbFiles[n].length() >> 8);
|
*lbufp++ = (TEXT) (dbFiles[n].length() >> 8);
|
||||||
memcpy(lbufp, dbFiles[n].c_str(), dbFiles[n].length());
|
memcpy(lbufp, dbFiles[n].c_str(), dbFiles[n].length());
|
||||||
lbufp += dbFiles[n].length();
|
lbufp += dbFiles[n].length();
|
||||||
total++;
|
|
||||||
}
|
}
|
||||||
fb_assert(total == num_dbs);
|
|
||||||
lbufp = lbuf;
|
|
||||||
*lbufp++ = (TEXT) total;
|
|
||||||
*lbufp++ = (TEXT) (total >> 8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5795,50 +5770,44 @@ void JRD_shutdown_all(bool asyncMode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // SERVER_SHUTDOWN
|
|
||||||
|
|
||||||
// This conditional compilation, though sitting under not
|
void JRD_shutdown_attachment(Attachment** handle, Attachment** released)
|
||||||
// defined SERVER_SHUTDOWN, performs full or partial shutdown
|
|
||||||
// of database. SERVER_SHUTDOWN defined controls some other
|
|
||||||
// aspects of operation, therefore was left "as is".
|
|
||||||
// Who wants to invent better name for it, please do it.
|
|
||||||
|
|
||||||
void JRD_process_close()
|
|
||||||
{
|
{
|
||||||
shutdown_all();
|
/**************************************
|
||||||
}
|
*
|
||||||
|
* J R D _ s h u t d o w n _ a t t a c h m e n t
|
||||||
|
*
|
||||||
|
**************************************
|
||||||
|
*
|
||||||
|
* Functional description
|
||||||
|
* Release attachment.
|
||||||
|
*
|
||||||
|
**************************************/
|
||||||
|
ISC_STATUS_ARRAY temp_status;
|
||||||
|
ThreadContextHolder tdbb(temp_status);
|
||||||
|
|
||||||
void JRD_database_close(Attachment** handle, Attachment** released)
|
try
|
||||||
{
|
{
|
||||||
ThreadContextHolder tdbb;
|
Attachment* attachment = *handle;
|
||||||
|
validateHandle(tdbb, attachment);
|
||||||
|
DatabaseContextHolder dbbHolder(tdbb);
|
||||||
|
|
||||||
try {
|
purge_attachment(tdbb, temp_status, attachment, true);
|
||||||
Firebird::MutexLockGuard guard(databases_mutex);
|
|
||||||
|
|
||||||
Database* dbb = databases;
|
if (released)
|
||||||
for (; dbb; dbb = dbb->dbb_next)
|
|
||||||
{
|
{
|
||||||
for (Attachment* attach = dbb->dbb_attachments; attach; attach = attach->att_next)
|
*released++ = attachment;
|
||||||
{
|
|
||||||
if (attach == *handle)
|
|
||||||
{
|
|
||||||
// got dbb to be closed
|
|
||||||
shutdown_dbb(tdbb, dbb, released);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const Firebird::Exception&)
|
catch (const Firebird::Exception&)
|
||||||
|
{} // no-op
|
||||||
|
|
||||||
|
if (released)
|
||||||
{
|
{
|
||||||
// This function is called from yValve as a last attempt to help
|
*released = NULL;
|
||||||
// when terminate signal is sent to firebird server.
|
|
||||||
// Ignore possible mutex problems.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SERVER_SHUTDOWN
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned int purge_transactions(thread_db* tdbb,
|
static unsigned int purge_transactions(thread_db* tdbb,
|
||||||
Attachment* attachment,
|
Attachment* attachment,
|
||||||
|
@ -147,17 +147,13 @@ ISC_STATUS jrd8_unwind_request(ISC_STATUS *, Jrd::jrd_req**, SSHORT);
|
|||||||
|
|
||||||
void jrd_vtof(const char*, char*, SSHORT);
|
void jrd_vtof(const char*, char*, SSHORT);
|
||||||
|
|
||||||
#ifdef SERVER_SHUTDOWN
|
// Defines for paramater 3 of JRD_num_attachments
|
||||||
/* Defines for paramater 3 of JRD_num_attachments */
|
|
||||||
const USHORT JRD_info_drivemask = 1;
|
const USHORT JRD_info_drivemask = 1;
|
||||||
const USHORT JRD_info_dbnames = 2;
|
const USHORT JRD_info_dbnames = 2;
|
||||||
|
|
||||||
TEXT* JRD_num_attachments(TEXT* const, USHORT, USHORT, ULONG*, ULONG*);
|
TEXT* JRD_num_attachments(TEXT* const, USHORT, USHORT, ULONG*, ULONG*);
|
||||||
void JRD_shutdown_all(bool);
|
void JRD_shutdown_all(bool);
|
||||||
#else /* SERVER_SHUTDOWN */
|
void JRD_shutdown_attachment(Jrd::Attachment**, Jrd::Attachment**);
|
||||||
void JRD_process_close();
|
|
||||||
void JRD_database_close(Jrd::Attachment**, Jrd::Attachment**);
|
|
||||||
#endif /* SERVER_SHUTDOWN */
|
|
||||||
|
|
||||||
bool JRD_reschedule(Jrd::thread_db*, SLONG, bool);
|
bool JRD_reschedule(Jrd::thread_db*, SLONG, bool);
|
||||||
|
|
||||||
|
@ -94,13 +94,13 @@
|
|||||||
#include "../jrd/blr.h"
|
#include "../jrd/blr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined (SUPERCLIENT) && !defined(SERVER_SHUTDOWN)
|
#if !defined(SUPERCLIENT)
|
||||||
#define CANCEL_disable 1
|
#define CANCEL_disable 1
|
||||||
#define CANCEL_enable 2
|
#define CANCEL_enable 2
|
||||||
#define CANCEL_raise 3
|
#define CANCEL_raise 3
|
||||||
//extern "C" ISC_STATUS jrd8_cancel_operation(ISC_STATUS *, Jrd::Attachment**, USHORT);
|
//extern "C" ISC_STATUS jrd8_cancel_operation(ISC_STATUS *, Jrd::Attachment**, USHORT);
|
||||||
void JRD_process_close();
|
void JRD_shutdown_all(bool);
|
||||||
void JRD_database_close(Jrd::Attachment**, Jrd::Attachment**);
|
void JRD_shutdown_attachment(Jrd::Attachment**, Jrd::Attachment**);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace YValve;
|
using namespace YValve;
|
||||||
@ -553,7 +553,7 @@ namespace
|
|||||||
if (killed)
|
if (killed)
|
||||||
{
|
{
|
||||||
#if !defined (SUPERCLIENT)
|
#if !defined (SUPERCLIENT)
|
||||||
JRD_process_close();
|
JRD_shutdown_all(false);
|
||||||
#endif
|
#endif
|
||||||
propagateKill();
|
propagateKill();
|
||||||
}
|
}
|
||||||
@ -570,7 +570,7 @@ namespace
|
|||||||
releasedBuffer.getBuffer(attachments().getCount() + 1);
|
releasedBuffer.getBuffer(attachments().getCount() + 1);
|
||||||
*released = 0;
|
*released = 0;
|
||||||
#if !defined (SUPERCLIENT)
|
#if !defined (SUPERCLIENT)
|
||||||
JRD_database_close(&attach, released);
|
JRD_shutdown_attachment(&attach, released);
|
||||||
#endif
|
#endif
|
||||||
markShutdown(released);
|
markShutdown(released);
|
||||||
}
|
}
|
||||||
@ -668,7 +668,7 @@ namespace
|
|||||||
// but as long as we have not entered engine,
|
// but as long as we have not entered engine,
|
||||||
// any call to it should be safe
|
// any call to it should be safe
|
||||||
#if !defined (SUPERCLIENT)
|
#if !defined (SUPERCLIENT)
|
||||||
JRD_process_close();
|
JRD_shutdown_all(false);
|
||||||
#endif
|
#endif
|
||||||
propagateKill();
|
propagateKill();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user