8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 00:03: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:
dimitr 2008-02-19 16:23:53 +00:00
parent 8291af3c5c
commit 7ae3eb5977
4 changed files with 99 additions and 121 deletions

View File

@ -254,6 +254,21 @@ public:
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:
size_t count, capacity;
T* data;
@ -289,8 +304,6 @@ public:
explicit SortedArray(size_t s) : Array<Value, Storage>(s) {}
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 {
size_t highBound = this->count, lowBound = 0;
while (highBound > lowBound) {

View File

@ -4895,10 +4895,8 @@ static Database* init(thread_db* tdbb,
// provide context pool for the rest stuff
Jrd::ContextPoolHolder context(tdbb, perm);
#ifdef SUPERSERVER
dbb->dbb_next = databases;
databases = dbb;
#endif
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);
@ -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&)
{
if (released)
{
*released = NULL;
}
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;
}
@ -5511,7 +5494,8 @@ static bool shutdown_all()
**************************************/
ThreadContextHolder tdbb;
try {
try
{
Firebird::MutexLockGuard guard(databases_mutex);
Database* dbb_next;
@ -5519,7 +5503,7 @@ static bool shutdown_all()
{
dbb_next = dbb->dbb_next;
if (!shutdown_dbb(tdbb, dbb, NULL))
if (!shutdown_dbb(tdbb, dbb))
{
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,
ULONG* atts, ULONG* dbs)
{
@ -5573,86 +5556,82 @@ TEXT* JRD_num_attachments(TEXT* const buf, USHORT buf_len, USHORT flag,
}
#endif
ULONG num_dbs = 0;
ULONG num_att = 0;
ULONG drive_mask = 0L;
USHORT total = 0;
Firebird::HalfStaticArray<Firebird::PathName, 8> dbFiles;
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)
try
{
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
// Get drive letters for db files
// Get drive letters for db files
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)
if (flag == JRD_info_drivemask)
{
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
// Get drive letters for temp directories
// Get drive letters for temp directories
if (flag == JRD_info_drivemask) {
const Firebird::TempDirectoryList dirList;
for (size_t i = 0; i < dirList.getCount(); i++) {
const Firebird::PathName& path = dirList[i];
ExtractDriveLetter(path.c_str(), &drive_mask);
if (flag == JRD_info_drivemask) {
const Firebird::TempDirectoryList dirList;
for (size_t i = 0; i < dirList.getCount(); i++) {
const Firebird::PathName& path = dirList[i];
ExtractDriveLetter(path.c_str(), &drive_mask);
}
}
}
#endif
}
}
}
}
databases_mutex->leave();
}
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
// we really have no way to notify world about mutex problem.
// AP. 2008.
}
const ULONG num_dbs = dbFiles.getCount();
*atts = num_att;
*dbs = num_dbs;
if (dbFiles.getCount() > 0)
if (num_dbs > 0)
{
if (flag == JRD_info_dbnames)
{
if (buf_len < (sizeof(USHORT) + total))
{
lbuf = (TEXT *) gds__alloc((SLONG) (sizeof(USHORT) + total));
lbuf = (TEXT *) gds__alloc(sizeof(USHORT) + total);
}
TEXT* lbufp = lbuf;
if (lbufp)
@ -5669,19 +5648,15 @@ TEXT* JRD_num_attachments(TEXT* const buf, USHORT buf_len, USHORT flag,
last db name
*/
lbufp += sizeof(USHORT);
total = 0;
for (size_t n = 0; n < dbFiles.getCount(); ++n) {
*lbufp++ = (TEXT) num_dbs;
*lbufp++ = (TEXT) (num_dbs >> 8);
for (size_t n = 0; n < num_dbs; ++n) {
*lbufp++ = (TEXT) dbFiles[n].length();
*lbufp++ = (TEXT) (dbFiles[n].length() >> 8);
memcpy(lbufp, dbFiles[n].c_str(), 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
// 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()
void JRD_shutdown_attachment(Attachment** handle, Attachment** released)
{
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)
{
ThreadContextHolder tdbb;
try
{
Attachment* attachment = *handle;
validateHandle(tdbb, attachment);
DatabaseContextHolder dbbHolder(tdbb);
try {
Firebird::MutexLockGuard guard(databases_mutex);
purge_attachment(tdbb, temp_status, attachment, true);
Database* dbb = databases;
for (; dbb; dbb = dbb->dbb_next)
if (released)
{
for (Attachment* attach = dbb->dbb_attachments; attach; attach = attach->att_next)
{
if (attach == *handle)
{
// got dbb to be closed
shutdown_dbb(tdbb, dbb, released);
return;
}
}
*released++ = attachment;
}
}
catch (const Firebird::Exception&)
{} // no-op
if (released)
{
// This function is called from yValve as a last attempt to help
// when terminate signal is sent to firebird server.
// Ignore possible mutex problems.
*released = NULL;
}
}
#endif // SERVER_SHUTDOWN
static unsigned int purge_transactions(thread_db* tdbb,
Attachment* attachment,

View File

@ -147,17 +147,13 @@ ISC_STATUS jrd8_unwind_request(ISC_STATUS *, Jrd::jrd_req**, 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_dbnames = 2;
TEXT* JRD_num_attachments(TEXT* const, USHORT, USHORT, ULONG*, ULONG*);
void JRD_shutdown_all(bool);
#else /* SERVER_SHUTDOWN */
void JRD_process_close();
void JRD_database_close(Jrd::Attachment**, Jrd::Attachment**);
#endif /* SERVER_SHUTDOWN */
void JRD_shutdown_attachment(Jrd::Attachment**, Jrd::Attachment**);
bool JRD_reschedule(Jrd::thread_db*, SLONG, bool);

View File

@ -94,13 +94,13 @@
#include "../jrd/blr.h"
#endif
#if !defined (SUPERCLIENT) && !defined(SERVER_SHUTDOWN)
#if !defined(SUPERCLIENT)
#define CANCEL_disable 1
#define CANCEL_enable 2
#define CANCEL_raise 3
//extern "C" ISC_STATUS jrd8_cancel_operation(ISC_STATUS *, Jrd::Attachment**, USHORT);
void JRD_process_close();
void JRD_database_close(Jrd::Attachment**, Jrd::Attachment**);
void JRD_shutdown_all(bool);
void JRD_shutdown_attachment(Jrd::Attachment**, Jrd::Attachment**);
#endif
using namespace YValve;
@ -553,7 +553,7 @@ namespace
if (killed)
{
#if !defined (SUPERCLIENT)
JRD_process_close();
JRD_shutdown_all(false);
#endif
propagateKill();
}
@ -570,7 +570,7 @@ namespace
releasedBuffer.getBuffer(attachments().getCount() + 1);
*released = 0;
#if !defined (SUPERCLIENT)
JRD_database_close(&attach, released);
JRD_shutdown_attachment(&attach, released);
#endif
markShutdown(released);
}
@ -668,7 +668,7 @@ namespace
// but as long as we have not entered engine,
// any call to it should be safe
#if !defined (SUPERCLIENT)
JRD_process_close();
JRD_shutdown_all(false);
#endif
propagateKill();
}