8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 00:03:03 +01:00

Reworked patch for bug CORE-4615 : Classic Server could hung with (near) 100% CPU load

This commit is contained in:
hvlad 2015-07-01 09:28:18 +00:00
parent 5da1523237
commit 1f5527be1f
3 changed files with 35 additions and 40 deletions

View File

@ -279,32 +279,6 @@ public:
Sync& sync;
};
class CheckoutIfNotInAst
{
public:
explicit CheckoutIfNotInAst(Database* dbb)
: sync(*dbb->dbb_sync)
{
inAst = sync.inAst();
if (!inAst)
sync.unlock();
}
~CheckoutIfNotInAst()
{
if (!inAst)
sync.lock();
}
private:
// copying is prohibited
CheckoutIfNotInAst(const CheckoutIfNotInAst&);
CheckoutIfNotInAst& operator=(const CheckoutIfNotInAst&);
Sync& sync;
bool inAst;
};
class CheckoutLockGuard
{
public:

View File

@ -366,9 +366,8 @@ void PIO_flush(Database* dbb, jrd_file* main_file)
// Since all SUPERSERVER_V2 database and shadow I/O is synchronous, this is a no-op.
#ifndef SUPERSERVER_V2
PioCheckout dcoHolder(dbb);
MutexLockGuard guard(main_file->fil_mutex);
Database::CheckoutIfNotInAst dcoHolder(dbb);
for (jrd_file* file = main_file; file; file = file->fil_next)
{
if (file->fil_desc != -1)
@ -590,6 +589,8 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
const char* const zero_buff = zeros().getBuffer();
const size_t zero_buff_size = zeros().getSize();
PioCheckout dcoHolder(dbb);
// Fake buffer, used in seek_file. Page space ID have no matter there
// as we already know file to work with
BufferDesc bdb;
@ -597,9 +598,6 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
bdb.bdb_page = PageNumber(0, startPage);
FB_UINT64 offset;
Database::CheckoutIfNotInAst dcoHolder(dbb);
jrd_file* file = seek_file(main_file, &bdb, &offset, status_vector);
if (!file)
@ -721,7 +719,7 @@ bool PIO_read(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* statu
}
Database* dbb = bdb->bdb_dbb;
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
const FB_UINT64 size = dbb->dbb_page_size;
@ -802,7 +800,7 @@ bool PIO_write(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* stat
return unix_error("write", file, isc_io_write_err, status_vector);
Database* dbb = bdb->bdb_dbb;
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
const SLONG size = dbb->dbb_page_size;

View File

@ -105,6 +105,29 @@ private:
using namespace Jrd;
using namespace Firebird;
namespace {
#ifdef SUPERSERVER
typedef Database::Checkout PioCheckout;
#else
class PioCheckout
{
public:
PioCheckout(Database*) {}
~PioCheckout() {}
private:
PioCheckout(const PioCheckout&);
PioCheckout& operator=(const PioCheckout&);
};
#endif
};
#ifdef TEXT
#undef TEXT
#endif
@ -300,7 +323,7 @@ void PIO_extend(Database* dbb, jrd_file* main_file, const ULONG extPages, const
if (!main_file->fil_ext_lock)
return;
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
FileExtendLockGuard extLock(main_file->fil_ext_lock, true);
ULONG leftPages = extPages;
@ -344,7 +367,7 @@ void PIO_flush(Database* dbb, jrd_file* main_file)
* Flush the operating system cache back to good, solid oxide.
*
**************************************/
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
for (jrd_file* file = main_file; file; file = file->fil_next)
{
FlushFileBuffers(file->fil_desc);
@ -495,7 +518,7 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
const char* const zero_buff = zeros().getBuffer();
const size_t zero_buff_size = zeros().getSize();
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
FileExtendLockGuard extLock(main_file->fil_ext_lock, false);
// Fake buffer, used in seek_file. Page space ID doesn't matter there
@ -624,7 +647,7 @@ bool PIO_read(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* statu
Database* const dbb = bdb->bdb_dbb;
const DWORD size = dbb->dbb_page_size;
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
FileExtendLockGuard extLock(file->fil_ext_lock, false);
OVERLAPPED overlapped, *overlapped_ptr;
@ -695,7 +718,7 @@ bool PIO_read_ahead(Database* dbb,
**************************************/
OVERLAPPED overlapped, *overlapped_ptr;
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
// If an I/O status block was passed the caller wants to queue an asynchronous I/O.
@ -783,7 +806,7 @@ bool PIO_status(Database* dbb, phys_io_blk* piob, ISC_STATUS* status_vector)
* Check the status of an asynchronous I/O.
*
**************************************/
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
if (!(piob->piob_flags & PIOB_success))
{
@ -826,7 +849,7 @@ bool PIO_write(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* stat
Database* const dbb = bdb->bdb_dbb;
const DWORD size = dbb->dbb_page_size;
Database::CheckoutIfNotInAst dcoHolder(dbb);
PioCheckout dcoHolder(dbb);
FileExtendLockGuard extLock(file->fil_ext_lock, false);
file = seek_file(file, bdb, status_vector, &overlapped, &overlapped_ptr);