mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 00:03:03 +01:00
Misc.
This commit is contained in:
parent
2fd18f68c9
commit
3800177568
@ -330,15 +330,13 @@ bool CCH_exclusive(thread_db* tdbb, USHORT level, SSHORT wait_flag)
|
|||||||
|
|
||||||
if (dbb->dbb_config->getSharedCache() && !dbb->dbb_config->getSharedDatabase())
|
if (dbb->dbb_config->getSharedCache() && !dbb->dbb_config->getSharedDatabase())
|
||||||
{
|
{
|
||||||
if (!CCH_exclusive_attachment(tdbb, level, wait_flag)) {
|
if (!CCH_exclusive_attachment(tdbb, level, wait_flag))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Lock* lock = dbb->dbb_lock;
|
Lock* lock = dbb->dbb_lock;
|
||||||
if (!lock) {
|
if (!lock)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
dbb->dbb_flags |= DBB_exclusive;
|
dbb->dbb_flags |= DBB_exclusive;
|
||||||
|
|
||||||
@ -346,16 +344,12 @@ bool CCH_exclusive(thread_db* tdbb, USHORT level, SSHORT wait_flag)
|
|||||||
{
|
{
|
||||||
case LCK_PW:
|
case LCK_PW:
|
||||||
if (lock->lck_physical >= LCK_PW || LCK_convert(tdbb, lock, LCK_PW, wait_flag))
|
if (lock->lck_physical >= LCK_PW || LCK_convert(tdbb, lock, LCK_PW, wait_flag))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LCK_EX:
|
case LCK_EX:
|
||||||
if (lock->lck_physical == LCK_EX || LCK_convert(tdbb, lock, LCK_EX, wait_flag))
|
if (lock->lck_physical == LCK_EX || LCK_convert(tdbb, lock, LCK_EX, wait_flag))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -369,9 +363,8 @@ bool CCH_exclusive(thread_db* tdbb, USHORT level, SSHORT wait_flag)
|
|||||||
// If we are supposed to wait (presumably patiently),
|
// If we are supposed to wait (presumably patiently),
|
||||||
// but can't get the lock, generate an error
|
// but can't get the lock, generate an error
|
||||||
|
|
||||||
if (wait_flag == LCK_WAIT) {
|
if (wait_flag == LCK_WAIT)
|
||||||
ERR_post(Arg::Gds(isc_deadlock));
|
ERR_post(Arg::Gds(isc_deadlock));
|
||||||
}
|
|
||||||
|
|
||||||
dbb->dbb_flags &= ~DBB_exclusive;
|
dbb->dbb_flags &= ~DBB_exclusive;
|
||||||
|
|
||||||
@ -399,14 +392,12 @@ bool CCH_exclusive_attachment(thread_db* tdbb, USHORT level, SSHORT wait_flag)
|
|||||||
Database* dbb = tdbb->getDatabase();
|
Database* dbb = tdbb->getDatabase();
|
||||||
Sync dsGuard(&dbb->dbb_sync, "CCH_exclusive_attachment");
|
Sync dsGuard(&dbb->dbb_sync, "CCH_exclusive_attachment");
|
||||||
const bool exLock = dbb->dbb_sync.ourExclusiveLock();
|
const bool exLock = dbb->dbb_sync.ourExclusiveLock();
|
||||||
if (!exLock) {
|
if (!exLock)
|
||||||
dsGuard.lock(SYNC_SHARED);
|
dsGuard.lock(SYNC_SHARED);
|
||||||
}
|
|
||||||
|
|
||||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||||
if (attachment->att_flags & ATT_exclusive) {
|
if (attachment->att_flags & ATT_exclusive)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
attachment->att_flags |= (level == LCK_none) ? ATT_attach_pending : ATT_exclusive_pending;
|
attachment->att_flags |= (level == LCK_none) ? ATT_attach_pending : ATT_exclusive_pending;
|
||||||
|
|
||||||
@ -686,39 +677,32 @@ pag* CCH_fetch(thread_db* tdbb, WIN* window, int lock_type, SCHAR page_type, int
|
|||||||
if (window->win_flags & WIN_large_scan)
|
if (window->win_flags & WIN_large_scan)
|
||||||
{
|
{
|
||||||
if (lockState == lsLocked || bdb->bdb_flags & BDB_prefetch || bdb->bdb_scan_count < 0)
|
if (lockState == lsLocked || bdb->bdb_flags & BDB_prefetch || bdb->bdb_scan_count < 0)
|
||||||
{
|
|
||||||
bdb->bdb_scan_count = window->win_scans;
|
bdb->bdb_scan_count = window->win_scans;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (window->win_flags & WIN_garbage_collector)
|
else if (window->win_flags & WIN_garbage_collector)
|
||||||
{
|
{
|
||||||
if (lockState == lsLocked) {
|
if (lockState == lsLocked)
|
||||||
bdb->bdb_scan_count = -1;
|
bdb->bdb_scan_count = -1;
|
||||||
}
|
|
||||||
if (bdb->bdb_flags & BDB_garbage_collect) {
|
if (bdb->bdb_flags & BDB_garbage_collect)
|
||||||
window->win_flags |= WIN_garbage_collect;
|
window->win_flags |= WIN_garbage_collect;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (window->win_flags & WIN_secondary)
|
else if (window->win_flags & WIN_secondary)
|
||||||
{
|
{
|
||||||
if (lockState == lsLocked) {
|
if (lockState == lsLocked)
|
||||||
bdb->bdb_scan_count = -1;
|
bdb->bdb_scan_count = -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bdb->bdb_scan_count = 0;
|
bdb->bdb_scan_count = 0;
|
||||||
if (bdb->bdb_flags & BDB_garbage_collect) {
|
if (bdb->bdb_flags & BDB_garbage_collect)
|
||||||
bdb->bdb_flags &= ~BDB_garbage_collect;
|
bdb->bdb_flags &= ~BDB_garbage_collect;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the fetched page matches the expected type
|
// Validate the fetched page matches the expected type
|
||||||
|
|
||||||
if (bdb->bdb_buffer->pag_type != page_type && page_type != pag_undefined)
|
if (bdb->bdb_buffer->pag_type != page_type && page_type != pag_undefined)
|
||||||
{
|
|
||||||
page_validation_error(tdbb, window, page_type);
|
page_validation_error(tdbb, window, page_type);
|
||||||
}
|
|
||||||
|
|
||||||
return window->win_buffer;
|
return window->win_buffer;
|
||||||
}
|
}
|
||||||
@ -760,9 +744,8 @@ LockState CCH_fetch_lock(thread_db* tdbb, WIN* window, int lock_type, int wait,
|
|||||||
// if there has been a shadow added recently, go out and
|
// if there has been a shadow added recently, go out and
|
||||||
// find it before we grant any more write locks
|
// find it before we grant any more write locks
|
||||||
|
|
||||||
if (dbb->dbb_ast_flags & DBB_get_shadows) {
|
if (dbb->dbb_ast_flags & DBB_get_shadows)
|
||||||
SDW_get_shadows(tdbb);
|
SDW_get_shadows(tdbb);
|
||||||
}
|
|
||||||
|
|
||||||
// Look for the page in the cache.
|
// Look for the page in the cache.
|
||||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||||
@ -770,7 +753,8 @@ LockState CCH_fetch_lock(thread_db* tdbb, WIN* window, int lock_type, int wait,
|
|||||||
if (!attachment->backupStateReadLock(tdbb, wait))
|
if (!attachment->backupStateReadLock(tdbb, wait))
|
||||||
return lsLockTimeout;
|
return lsLockTimeout;
|
||||||
|
|
||||||
BufferDesc* bdb = get_buffer(tdbb, window->win_page, ((lock_type >= LCK_write) ? SYNC_EXCLUSIVE : SYNC_SHARED), wait);
|
BufferDesc* bdb = get_buffer(tdbb, window->win_page,
|
||||||
|
((lock_type >= LCK_write) ? SYNC_EXCLUSIVE : SYNC_SHARED), wait);
|
||||||
|
|
||||||
if (wait != 1 && bdb == 0)
|
if (wait != 1 && bdb == 0)
|
||||||
{
|
{
|
||||||
@ -778,9 +762,8 @@ LockState CCH_fetch_lock(thread_db* tdbb, WIN* window, int lock_type, int wait,
|
|||||||
return lsLatchTimeout; // latch timeout
|
return lsLatchTimeout; // latch timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock_type >= LCK_write) {
|
if (lock_type >= LCK_write)
|
||||||
bdb->bdb_flags |= BDB_writer;
|
bdb->bdb_flags |= BDB_writer;
|
||||||
}
|
|
||||||
|
|
||||||
window->win_bdb = bdb;
|
window->win_bdb = bdb;
|
||||||
window->win_buffer = bdb->bdb_buffer;
|
window->win_buffer = bdb->bdb_buffer;
|
||||||
@ -788,9 +771,8 @@ LockState CCH_fetch_lock(thread_db* tdbb, WIN* window, int lock_type, int wait,
|
|||||||
// lock_buffer returns 0 or 1 or -1.
|
// lock_buffer returns 0 or 1 or -1.
|
||||||
const LockState lock_result = lock_buffer(tdbb, bdb, wait, page_type);
|
const LockState lock_result = lock_buffer(tdbb, bdb, wait, page_type);
|
||||||
|
|
||||||
if (lock_result == lsLockTimeout) {
|
if (lock_result == lsLockTimeout)
|
||||||
attachment->backupStateReadUnLock(tdbb);
|
attachment->backupStateReadUnLock(tdbb);
|
||||||
}
|
|
||||||
|
|
||||||
return lock_result;
|
return lock_result;
|
||||||
}
|
}
|
||||||
@ -965,18 +947,13 @@ void CCH_forget_page(thread_db* tdbb, WIN* window)
|
|||||||
BufferDesc* bdb = window->win_bdb;
|
BufferDesc* bdb = window->win_bdb;
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
if (window->win_page != bdb->bdb_page ||
|
if (window->win_page != bdb->bdb_page || bdb->bdb_buffer->pag_type != pag_undefined)
|
||||||
bdb->bdb_buffer->pag_type != pag_undefined)
|
return; // buffer was reassigned or page was reused
|
||||||
{
|
|
||||||
// buffer was reassigned or page was reused
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->win_bdb = NULL;
|
window->win_bdb = NULL;
|
||||||
|
|
||||||
if (bdb->bdb_flags & BDB_io_error) {
|
if (bdb->bdb_flags & BDB_io_error)
|
||||||
dbb->dbb_flags &= ~DBB_suspend_bgio;
|
dbb->dbb_flags &= ~DBB_suspend_bgio;
|
||||||
}
|
|
||||||
|
|
||||||
clear_dirty_flag(tdbb, bdb);
|
clear_dirty_flag(tdbb, bdb);
|
||||||
bdb->bdb_flags = 0;
|
bdb->bdb_flags = 0;
|
||||||
@ -988,9 +965,8 @@ void CCH_forget_page(thread_db* tdbb, WIN* window)
|
|||||||
QUE_DELETE(bdb->bdb_que);
|
QUE_DELETE(bdb->bdb_que);
|
||||||
QUE_INSERT(bcb->bcb_empty, bdb->bdb_que);
|
QUE_INSERT(bcb->bcb_empty, bdb->bdb_que);
|
||||||
|
|
||||||
if (tdbb->tdbb_flags & TDBB_no_cache_unwind) {
|
if (tdbb->tdbb_flags & TDBB_no_cache_unwind)
|
||||||
bdb->release(tdbb);
|
bdb->release(tdbb);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1099,26 +1075,20 @@ void CCH_fini(thread_db* tdbb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (bcb->bcb_memory.hasData())
|
while (bcb->bcb_memory.hasData())
|
||||||
{
|
|
||||||
bcb->bcb_bufferpool->deallocate(bcb->bcb_memory.pop());
|
bcb->bcb_bufferpool->deallocate(bcb->bcb_memory.pop());
|
||||||
}
|
|
||||||
|
|
||||||
} // try
|
} // try
|
||||||
catch (const Firebird::Exception& ex)
|
catch (const Firebird::Exception& ex)
|
||||||
{
|
{
|
||||||
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
||||||
if (!flush_error) {
|
if (!flush_error)
|
||||||
flush_error = true;
|
flush_error = true;
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
ERR_punt();
|
ERR_punt();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flush_error) {
|
if (!flush_error)
|
||||||
// wasn't set in the catch => no failure, just exit
|
break; // wasn't set in the catch => no failure, just exit
|
||||||
break;
|
|
||||||
}
|
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
BufferControl::destroy(bcb);
|
BufferControl::destroy(bcb);
|
||||||
@ -1168,13 +1138,10 @@ void CCH_flush(thread_db* tdbb, USHORT flush_flag, SLONG tra_number)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flushDirty(tdbb, transaction_mask, sys_only, status);
|
flushDirty(tdbb, transaction_mask, sys_only, status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
flushAll(tdbb, flush_flag);
|
flushAll(tdbb, flush_flag);
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if flush needed
|
// Check if flush needed
|
||||||
@ -1253,9 +1220,7 @@ void CCH_flush_ast(thread_db* tdbb)
|
|||||||
BufferControl* bcb = dbb->dbb_bcb;
|
BufferControl* bcb = dbb->dbb_bcb;
|
||||||
|
|
||||||
if (bcb->bcb_flags & BCB_exclusive)
|
if (bcb->bcb_flags & BCB_exclusive)
|
||||||
{
|
|
||||||
CCH_flush(tdbb, FLUSH_ALL, 0);
|
CCH_flush(tdbb, FLUSH_ALL, 0);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Do some fancy footwork to make sure that pages are
|
// Do some fancy footwork to make sure that pages are
|
||||||
@ -1271,9 +1236,8 @@ void CCH_flush_ast(thread_db* tdbb)
|
|||||||
down_grade(tdbb, bdb);
|
down_grade(tdbb, bdb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keep_pages) {
|
if (!keep_pages)
|
||||||
bcb->bcb_flags &= ~BCB_keep_pages;
|
bcb->bcb_flags &= ~BCB_keep_pages;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1302,12 +1266,13 @@ bool CCH_free_page(thread_db* tdbb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BufferDesc* bdb;
|
BufferDesc* bdb;
|
||||||
if (bcb->bcb_flags & BCB_free_pending && (bdb = get_buffer(tdbb, FREE_PAGE, SYNC_SHARED /*LATCH_none*/, 1)))
|
|
||||||
|
if ((bcb->bcb_flags & BCB_free_pending) &&
|
||||||
|
(bdb = get_buffer(tdbb, FREE_PAGE, SYNC_SHARED /*LATCH_none*/, 1)))
|
||||||
{
|
{
|
||||||
if (!write_buffer(tdbb, bdb, bdb->bdb_page, true, tdbb->tdbb_status_vector, true))
|
if (!write_buffer(tdbb, bdb, bdb->bdb_page, true, tdbb->tdbb_status_vector, true))
|
||||||
{
|
|
||||||
CCH_unwind(tdbb, false);
|
CCH_unwind(tdbb, false);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,9 +82,9 @@ struct bcb_repeat
|
|||||||
|
|
||||||
class BufferControl : public pool_alloc<type_bcb>
|
class BufferControl : public pool_alloc<type_bcb>
|
||||||
{
|
{
|
||||||
explicit BufferControl(MemoryPool& p) :
|
explicit BufferControl(MemoryPool& p)
|
||||||
bcb_bufferpool(&p),
|
: bcb_bufferpool(&p),
|
||||||
bcb_memory(p)
|
bcb_memory(p)
|
||||||
{
|
{
|
||||||
bcb_database = NULL;
|
bcb_database = NULL;
|
||||||
QUE_INIT(bcb_in_use);
|
QUE_INIT(bcb_in_use);
|
||||||
@ -115,7 +115,7 @@ public:
|
|||||||
Firebird::MemoryStats bcb_memory_stats;
|
Firebird::MemoryStats bcb_memory_stats;
|
||||||
|
|
||||||
// To be deleted when PAG will be not coupled with Database.
|
// To be deleted when PAG will be not coupled with Database.
|
||||||
// Used only in CS mode when each BufferControl have one Database .
|
// Used only in CS mode when each BufferControl have one Database.
|
||||||
Database* bcb_database;
|
Database* bcb_database;
|
||||||
|
|
||||||
UCharStack bcb_memory; // Large block partitioned into buffers
|
UCharStack bcb_memory; // Large block partitioned into buffers
|
||||||
@ -147,14 +147,14 @@ public:
|
|||||||
Firebird::SyncObject bcb_syncLRU;
|
Firebird::SyncObject bcb_syncLRU;
|
||||||
//Firebird::SyncObject bcb_syncPageWrite;
|
//Firebird::SyncObject bcb_syncPageWrite;
|
||||||
|
|
||||||
Firebird::Semaphore bcb_writer_sem; // Wake up cache writer
|
Firebird::Semaphore bcb_writer_sem; // Wake up cache writer
|
||||||
Firebird::Semaphore bcb_writer_init;// Cache writer initialization
|
Firebird::Semaphore bcb_writer_init; // Cache writer initialization
|
||||||
Firebird::Semaphore bcb_writer_fini;// Cache writer finalization
|
Firebird::Semaphore bcb_writer_fini; // Cache writer finalization
|
||||||
#ifdef SUPERSERVER_V2
|
#ifdef SUPERSERVER_V2
|
||||||
// the code in cch.cpp is not tested for semaphore instead event !!!
|
// the code in cch.cpp is not tested for semaphore instead event !!!
|
||||||
Firebird::Semaphore bcb_reader_sem; // Wake up cache reader
|
Firebird::Semaphore bcb_reader_sem; // Wake up cache reader
|
||||||
Firebird::Semaphore bcb_reader_init;// Cache reader initialization
|
Firebird::Semaphore bcb_reader_init; // Cache reader initialization
|
||||||
Firebird::Semaphore bcb_reader_fini;// Cache reader finalization
|
Firebird::Semaphore bcb_reader_fini; // Cache reader finalization
|
||||||
|
|
||||||
PageBitmap* bcb_prefetch; // Bitmap of pages to prefetch
|
PageBitmap* bcb_prefetch; // Bitmap of pages to prefetch
|
||||||
#endif
|
#endif
|
||||||
@ -179,10 +179,10 @@ const int BCB_exclusive = 128; // there is only BCB in whole system
|
|||||||
class BufferDesc : public pool_alloc<type_bdb>
|
class BufferDesc : public pool_alloc<type_bdb>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BufferDesc(BufferControl* bcb) :
|
BufferDesc(BufferControl* bcb)
|
||||||
bdb_bcb(bcb),
|
: bdb_bcb(bcb),
|
||||||
bdb_page(0, 0),
|
bdb_page(0, 0),
|
||||||
bdb_pending_page(0, 0)
|
bdb_pending_page(0, 0)
|
||||||
{
|
{
|
||||||
bdb_lock = NULL;
|
bdb_lock = NULL;
|
||||||
QUE_INIT(bdb_que);
|
QUE_INIT(bdb_que);
|
||||||
@ -241,9 +241,11 @@ public:
|
|||||||
que bdb_lower; // lower precedence que
|
que bdb_lower; // lower precedence que
|
||||||
que bdb_higher; // higher precedence que
|
que bdb_higher; // higher precedence que
|
||||||
thread_db* bdb_exclusive; // thread holding exclusive latch
|
thread_db* bdb_exclusive; // thread holding exclusive latch
|
||||||
|
|
||||||
private:
|
private:
|
||||||
thread_db* bdb_io; // thread holding io latch
|
thread_db* bdb_io; // thread holding io latch
|
||||||
Firebird::SyncObject bdb_syncIO;
|
Firebird::SyncObject bdb_syncIO;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Firebird::AtomicCounter bdb_ast_flags; // flags manipulated at AST level
|
Firebird::AtomicCounter bdb_ast_flags; // flags manipulated at AST level
|
||||||
Firebird::AtomicCounter bdb_flags;
|
Firebird::AtomicCounter bdb_flags;
|
||||||
@ -265,7 +267,7 @@ const int BDB_writer = 0x0004; // someone is updating the page
|
|||||||
const int BDB_marked = 0x0008; // page has been updated
|
const int BDB_marked = 0x0008; // page has been updated
|
||||||
const int BDB_must_write = 0x0010; // forces a write as soon as the page is released
|
const int BDB_must_write = 0x0010; // forces a write as soon as the page is released
|
||||||
const int BDB_faked = 0x0020; // page was just allocated
|
const int BDB_faked = 0x0020; // page was just allocated
|
||||||
//const int BDB_merge = 0x0040;
|
//const int BDB_merge = 0x0040;
|
||||||
const int BDB_system_dirty = 0x0080; // system transaction has marked dirty
|
const int BDB_system_dirty = 0x0080; // system transaction has marked dirty
|
||||||
const int BDB_io_error = 0x0100; // page i/o error
|
const int BDB_io_error = 0x0100; // page i/o error
|
||||||
const int BDB_read_pending = 0x0200; // read is pending
|
const int BDB_read_pending = 0x0200; // read is pending
|
||||||
|
Loading…
Reference in New Issue
Block a user