8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 21:23:03 +01:00
This commit is contained in:
asfernandes 2011-05-12 00:42:40 +00:00
parent 2fd18f68c9
commit 3800177568
2 changed files with 46 additions and 79 deletions

View File

@ -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;
} }

View File

@ -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