8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 15:23:02 +01:00

Fixed possibly trashed memory plus small cleanup.

This commit is contained in:
dimitr 2007-02-08 14:32:07 +00:00
parent 2c90a5124d
commit 5c9c0e58c4
2 changed files with 24 additions and 27 deletions

View File

@ -399,7 +399,7 @@ int BackupManager::backup_state_ast(void *ast_object) throw()
tdbb->tdbb_transaction = NULL;
NBAK_TRACE_AST("NBAK, backup_state_ast");
if (new_dbb->dbb_backup_manager->flags & NBAK_state_in_use)
new_dbb->dbb_backup_manager->ast_flags |= NBAK_state_blocking;
else {
@ -503,7 +503,7 @@ int BackupManager::backup_database_ast(void *ast_object) throw()
tdbb->tdbb_status_vector = ast_status;
NBAK_TRACE_AST("NBAK, backup_database_ast");
if (new_dbb->dbb_backup_manager->database_use_count) {
new_dbb->dbb_backup_manager->ast_flags |= NBAK_database_blocking;
ast_status[1] = 0;
@ -618,7 +618,7 @@ void BackupManager::begin_backup(thread_db* tdbb)
header_locked = false;
CCH_RELEASE(tdbb, &window);
tdbb->tdbb_flags &= ~TDBB_set_backup_state;
backup_state = newState;
current_scn = adjusted_scn;
// This is essential for SuperServer to prevent multi-threading issues
@ -723,10 +723,9 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover)
CCH_RELEASE(tdbb, &window);
throw;
}
// Here comes the dirty work. We need to reapply all changes from difference file to database
// Release write state lock and get read lock.
// Merge process should not inhibit normal operations.
tdbb->tdbb_flags &= ~TDBB_set_backup_state;
@ -746,9 +745,9 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover)
ERR_punt();
NBAK_TRACE(("Allocation table %p is current.", alloc_table));
AllocItemTree::Accessor all(alloc_table);
tdbb->tdbb_flags |= TDBB_set_backup_state | TDBB_backup_merge;
if (all.getFirst()) {
do {
WIN window2(DB_PAGE_SPACE, all.current().db_page); //vlad ??
@ -763,14 +762,14 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover)
tdbb->tdbb_flags &= ~(TDBB_set_backup_state | TDBB_backup_merge);
unlock_state(tdbb);
}
catch (const Firebird::Exception&) {
tdbb->tdbb_flags &= ~(TDBB_set_backup_state | TDBB_backup_merge);
unlock_state(tdbb);
throw;
}
// We finished. We need to reflect it in our database header page
window.win_page = HEADER_PAGE_NUMBER;
window.win_flags = 0;
@ -800,12 +799,12 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover)
header_locked = false;
CCH_RELEASE(tdbb, &window);
tdbb->tdbb_flags &= ~TDBB_set_backup_state;
// Page allocation table cache is no longer valid
delete alloc_table;
alloc_table = NULL;
last_allocated_page = 0;
if (diff_file) {
#ifndef SUPERSERVER
diff_generation++;
@ -814,7 +813,7 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover)
diff_file = NULL;
}
unlink(diff_name.c_str());
unlock_state_write(tdbb);
NBAK_TRACE(("backup ended"));
}
@ -829,7 +828,7 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover)
}
return;
}
bool BackupManager::actualize_alloc(thread_db* tdbb) throw()
{
if (alloc_table
@ -850,12 +849,12 @@ bool BackupManager::actualize_alloc(thread_db* tdbb) throw()
// Difference file pointer pages have one ULONG as number of pages allocated on the page and
// then go physical numbers of pages from main database file. Offsets of numbers correspond
// to difference file pages.
// Get offset of pointer page. We can do so because page sizes are powers of 2
temp_bdb.bdb_page = last_allocated_page & ~(database->dbb_page_size / sizeof(ULONG) - 1);
temp_bdb.bdb_dbb = database;
temp_bdb.bdb_buffer = reinterpret_cast<Ods::pag*>(alloc_buffer);
if (!PIO_read(diff_file, &temp_bdb, temp_bdb.bdb_buffer, status_vector))
return false;
for (ULONG i = last_allocated_page - temp_bdb.bdb_page.getPageNum();
@ -924,7 +923,7 @@ ULONG BackupManager::allocate_difference_page(thread_db* tdbb, ULONG db_page) th
temp_bdb.bdb_buffer = reinterpret_cast<Ods::pag*>(empty_buffer);
if (!PIO_write(diff_file, &temp_bdb, (Ods::pag*)empty_buffer, status_vector))
return 0;
const bool alloc_page_full = alloc_buffer[0] == database->dbb_page_size / sizeof(ULONG) - 2;
if (alloc_page_full) {
// Pointer page is full. Its time to create new one.
@ -961,7 +960,7 @@ ULONG BackupManager::allocate_difference_page(thread_db* tdbb, ULONG db_page) th
memset(alloc_buffer, 0, database->dbb_page_size);
return last_allocated_page - 1;
}
return last_allocated_page;
}
@ -975,7 +974,7 @@ bool BackupManager::write_difference(ISC_STATUS* status, ULONG diff_page, Ods::p
return false;
return true;
}
bool BackupManager::read_difference(thread_db* tdbb, ULONG diff_page, Ods::pag* page) throw()
{
BufferDesc temp_bdb;
@ -986,7 +985,7 @@ bool BackupManager::read_difference(thread_db* tdbb, ULONG diff_page, Ods::pag*
return false;
return true;
}
BackupManager::BackupManager(thread_db* tdbb, Database* _database, int ini_state) :
database(_database), diff_file(NULL), alloc_table(NULL),
backup_state(ini_state), last_allocated_page(0),
@ -998,12 +997,11 @@ BackupManager::BackupManager(thread_db* tdbb, Database* _database, int ini_state
BYTE *temp_buffers = reinterpret_cast<BYTE*>(
FB_ALIGN(reinterpret_cast<U_IPTR>(temp_buffers_space), MIN_PAGE_SIZE));
memset(temp_buffers, 0, database->dbb_page_size * 3);
empty_buffer = reinterpret_cast<ULONG*>(temp_buffers);
spare_buffer = reinterpret_cast<ULONG*>(temp_buffers + database->dbb_page_size);
alloc_buffer = reinterpret_cast<ULONG*>(temp_buffers + database->dbb_page_size + 2);
alloc_buffer = reinterpret_cast<ULONG*>(temp_buffers + database->dbb_page_size * 2);
#ifdef SUPERSERVER
alloc_lock = FB_NEW(*_database->dbb_permanent) Firebird::RWLock();
state_lock = FB_NEW(*_database->dbb_permanent) Firebird::RWLock();
@ -1015,7 +1013,7 @@ BackupManager::BackupManager(thread_db* tdbb, Database* _database, int ini_state
database_use_count = 0;
diff_use_count = 0;
diff_generation = 0;
state_lock = FB_NEW_RPT(*database->dbb_permanent, 0) Lock();
state_lock->lck_type = LCK_backup_state;
state_lock->lck_owner_handle = LCK_get_owner_handle(tdbb, state_lock->lck_type);
@ -1096,9 +1094,9 @@ bool BackupManager::actualize_state(thread_db* tdbb) throw()
// State is unknown. We need to read it from the disk.
// We cannot use CCH for this because of likely recursion.
NBAK_TRACE(("actualize_state"));
ISC_STATUS *status = tdbb->tdbb_status_vector;
// Read original page from database file or shadows.
SSHORT retryCount = 0;
Ods::header_page* header = reinterpret_cast<Ods::header_page*>(spare_buffer);

View File

@ -63,7 +63,6 @@ class AllocItem {
public:
ULONG db_page; // Page number in the main database file
ULONG diff_page; // Page number in the difference file
Record* rec_data;
static const ULONG& generate(const void *sender, const AllocItem& item) {
return item.db_page;
}