Merge difference file to main files (if needed) and unlink() difference file then. If merge is already in progress method silently returns and does nothing (so it can be used for recovery on database startup).
| 432 | // file then. If merge is already in progress method silently returns and |
| 433 | // does nothing (so it can be used for recovery on database startup). |
| 434 | void BackupManager::endBackup(thread_db* tdbb, bool recover) |
| 435 | { |
| 436 | NBAK_TRACE(("end_backup, recover=%i", recover)); |
| 437 | |
| 438 | // Check for recover |
| 439 | |
| 440 | GlobalRWLock endLock(tdbb, *database->dbb_permanent, LCK_backup_end, false); |
| 441 | |
| 442 | if (!endLock.lockWrite(tdbb, LCK_NO_WAIT)) |
| 443 | { |
| 444 | // Someboby holds write lock on LCK_backup_end. We need not to do end_backup |
| 445 | return; |
| 446 | } |
| 447 | |
| 448 | MasterGuard masterGuard(*this); |
| 449 | |
| 450 | // STEP 1. Change state in header to "merge" |
| 451 | WIN window(HEADER_PAGE_NUMBER); |
| 452 | Ods::header_page* header; |
| 453 | |
| 454 | #ifdef NBAK_DEBUG |
| 455 | ULONG adjusted_scn; // We use this value to prevent race conditions. |
| 456 | // They are possible because we release state lock |
| 457 | // for some instants and anything is possible at |
| 458 | // that times. |
| 459 | #endif |
| 460 | |
| 461 | try |
| 462 | { |
| 463 | // Check state under PR lock of backup state for speed |
| 464 | { // scope |
| 465 | StateReadGuard stateGuard(tdbb); |
| 466 | // Nobody is doing end_backup but database isn't in merge state. |
| 467 | if ( (recover || backup_state != Ods::hdr_nbak_stalled) && (backup_state != Ods::hdr_nbak_merge ) ) |
| 468 | { |
| 469 | NBAK_TRACE(("invalid state %d", backup_state)); |
| 470 | endLock.unlockWrite(tdbb); |
| 471 | return; |
| 472 | } |
| 473 | |
| 474 | if (backup_state == Ods::hdr_nbak_stalled && !extendDatabase(tdbb)) |
| 475 | status_exception::raise(tdbb->tdbb_status_vector); |
| 476 | } |
| 477 | |
| 478 | // Here backup state can be changed. Need to check it again after lock |
| 479 | StateWriteGuard stateGuard(tdbb, &window); |
| 480 | |
| 481 | if ( (recover || backup_state != Ods::hdr_nbak_stalled) && (backup_state != Ods::hdr_nbak_merge ) ) |
| 482 | { |
| 483 | stateGuard.setSuccess(); |
| 484 | NBAK_TRACE(("invalid state %d", backup_state)); |
| 485 | endLock.unlockWrite(tdbb); |
| 486 | return; |
| 487 | } |
| 488 | |
| 489 | if (!extendDatabase(tdbb)) |
| 490 | { |
| 491 | stateGuard.setSuccess(); |
no test coverage detected