mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 06:43: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;
|
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
|
class CheckoutLockGuard
|
||||||
{
|
{
|
||||||
public:
|
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.
|
// Since all SUPERSERVER_V2 database and shadow I/O is synchronous, this is a no-op.
|
||||||
#ifndef SUPERSERVER_V2
|
#ifndef SUPERSERVER_V2
|
||||||
|
PioCheckout dcoHolder(dbb);
|
||||||
MutexLockGuard guard(main_file->fil_mutex);
|
MutexLockGuard guard(main_file->fil_mutex);
|
||||||
|
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
|
||||||
for (jrd_file* file = main_file; file; file = file->fil_next)
|
for (jrd_file* file = main_file; file; file = file->fil_next)
|
||||||
{
|
{
|
||||||
if (file->fil_desc != -1)
|
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 char* const zero_buff = zeros().getBuffer();
|
||||||
const size_t zero_buff_size = zeros().getSize();
|
const size_t zero_buff_size = zeros().getSize();
|
||||||
|
|
||||||
|
PioCheckout dcoHolder(dbb);
|
||||||
|
|
||||||
// Fake buffer, used in seek_file. Page space ID have no matter there
|
// Fake buffer, used in seek_file. Page space ID have no matter there
|
||||||
// as we already know file to work with
|
// as we already know file to work with
|
||||||
BufferDesc bdb;
|
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);
|
bdb.bdb_page = PageNumber(0, startPage);
|
||||||
|
|
||||||
FB_UINT64 offset;
|
FB_UINT64 offset;
|
||||||
|
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
|
||||||
|
|
||||||
jrd_file* file = seek_file(main_file, &bdb, &offset, status_vector);
|
jrd_file* file = seek_file(main_file, &bdb, &offset, status_vector);
|
||||||
|
|
||||||
if (!file)
|
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* dbb = bdb->bdb_dbb;
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
PioCheckout dcoHolder(dbb);
|
||||||
|
|
||||||
const FB_UINT64 size = dbb->dbb_page_size;
|
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);
|
return unix_error("write", file, isc_io_write_err, status_vector);
|
||||||
|
|
||||||
Database* dbb = bdb->bdb_dbb;
|
Database* dbb = bdb->bdb_dbb;
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
PioCheckout dcoHolder(dbb);
|
||||||
|
|
||||||
const SLONG size = dbb->dbb_page_size;
|
const SLONG size = dbb->dbb_page_size;
|
||||||
|
|
||||||
|
@ -105,6 +105,29 @@ private:
|
|||||||
using namespace Jrd;
|
using namespace Jrd;
|
||||||
using namespace Firebird;
|
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
|
#ifdef TEXT
|
||||||
#undef TEXT
|
#undef TEXT
|
||||||
#endif
|
#endif
|
||||||
@ -300,7 +323,7 @@ void PIO_extend(Database* dbb, jrd_file* main_file, const ULONG extPages, const
|
|||||||
if (!main_file->fil_ext_lock)
|
if (!main_file->fil_ext_lock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
PioCheckout dcoHolder(dbb);
|
||||||
FileExtendLockGuard extLock(main_file->fil_ext_lock, true);
|
FileExtendLockGuard extLock(main_file->fil_ext_lock, true);
|
||||||
|
|
||||||
ULONG leftPages = extPages;
|
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.
|
* 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)
|
for (jrd_file* file = main_file; file; file = file->fil_next)
|
||||||
{
|
{
|
||||||
FlushFileBuffers(file->fil_desc);
|
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 char* const zero_buff = zeros().getBuffer();
|
||||||
const size_t zero_buff_size = zeros().getSize();
|
const size_t zero_buff_size = zeros().getSize();
|
||||||
|
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
PioCheckout dcoHolder(dbb);
|
||||||
FileExtendLockGuard extLock(main_file->fil_ext_lock, false);
|
FileExtendLockGuard extLock(main_file->fil_ext_lock, false);
|
||||||
|
|
||||||
// Fake buffer, used in seek_file. Page space ID doesn't matter there
|
// 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;
|
Database* const dbb = bdb->bdb_dbb;
|
||||||
const DWORD size = dbb->dbb_page_size;
|
const DWORD size = dbb->dbb_page_size;
|
||||||
|
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
PioCheckout dcoHolder(dbb);
|
||||||
FileExtendLockGuard extLock(file->fil_ext_lock, false);
|
FileExtendLockGuard extLock(file->fil_ext_lock, false);
|
||||||
|
|
||||||
OVERLAPPED overlapped, *overlapped_ptr;
|
OVERLAPPED overlapped, *overlapped_ptr;
|
||||||
@ -695,7 +718,7 @@ bool PIO_read_ahead(Database* dbb,
|
|||||||
**************************************/
|
**************************************/
|
||||||
OVERLAPPED overlapped, *overlapped_ptr;
|
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.
|
// 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.
|
* Check the status of an asynchronous I/O.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
PioCheckout dcoHolder(dbb);
|
||||||
|
|
||||||
if (!(piob->piob_flags & PIOB_success))
|
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;
|
Database* const dbb = bdb->bdb_dbb;
|
||||||
const DWORD size = dbb->dbb_page_size;
|
const DWORD size = dbb->dbb_page_size;
|
||||||
|
|
||||||
Database::CheckoutIfNotInAst dcoHolder(dbb);
|
PioCheckout dcoHolder(dbb);
|
||||||
FileExtendLockGuard extLock(file->fil_ext_lock, false);
|
FileExtendLockGuard extLock(file->fil_ext_lock, false);
|
||||||
|
|
||||||
file = seek_file(file, bdb, status_vector, &overlapped, &overlapped_ptr);
|
file = seek_file(file, bdb, status_vector, &overlapped, &overlapped_ptr);
|
||||||
|
Loading…
Reference in New Issue
Block a user