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:
parent
5da1523237
commit
1f5527be1f
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user