Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/include/firebird/impl/msg/jrd.h
Original file line number Diff line number Diff line change
Expand Up @@ -987,3 +987,7 @@ FB_IMPL_MSG(JRD, 984, incompatible_format_patterns, -901, "HY", "000", "@1 incom
FB_IMPL_MSG(JRD, 985, only_one_pattern_can_be_used, -901, "HY", "000", "Can use only one of these patterns @1")
FB_IMPL_MSG(JRD, 986, can_not_use_same_pattern_twice, -901, "HY", "000", "Cannot use the same pattern twice: @1")
FB_IMPL_MSG(JRD, 987, sysf_invalid_gen_uuid_version, -833, "42", "000", "Invalid GEN_UUID version (@1). Must be 4 or 7")
FB_IMPL_MSG(JRD, 988, sweep_unable_to_run, -901, "42", "000", "Unable to run sweep")
FB_IMPL_MSG(JRD, 989, sweep_concurrent_instance, -901, "42", "000", "Another instance of sweep is already running")
FB_IMPL_MSG(JRD, 990, sweep_read_only, -901, "42", "000", "Database in read only state")
FB_IMPL_MSG(JRD, 991, sweep_attach_no_cleanup, -901, "42", "000", "Attachment has no cleanup flag set")
4 changes: 4 additions & 0 deletions src/include/gen/Firebird.pas
Original file line number Diff line number Diff line change
Expand Up @@ -5740,6 +5740,10 @@ IProfilerStatsImpl = class(IProfilerStats)
isc_only_one_pattern_can_be_used = 335545305;
isc_can_not_use_same_pattern_twice = 335545306;
isc_sysf_invalid_gen_uuid_version = 335545307;
isc_sweep_unable_to_run = 335545308;
isc_sweep_concurrent_instance = 335545309;
isc_sweep_read_only = 335545310;
isc_sweep_attach_no_cleanup = 335545311;
isc_gfix_db_name = 335740929;
isc_gfix_invalid_sw = 335740930;
isc_gfix_incmp_sw = 335740932;
Expand Down
28 changes: 17 additions & 11 deletions src/jrd/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@

using namespace Firebird;

namespace
{
void unableToRunSweepException(const Arg::Gds& reason)
{
ERR_post(Arg::Gds(isc_sweep_unable_to_run) << reason);
}
}

namespace Jrd
{
bool Database::onRawDevice() const
Expand Down Expand Up @@ -299,35 +307,35 @@ namespace Jrd
}
}

bool Database::allowSweepRun(thread_db* tdbb)
void Database::initiateSweepRun(thread_db* tdbb)
{
SPTHR_DEBUG(fprintf(stderr, "allowSweepRun %p\n", this));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " %p\n", this));

if (readOnly())
return false;
unableToRunSweepException(Arg::Gds(isc_sweep_read_only));

Jrd::Attachment* const attachment = tdbb->getAttachment();
if (attachment->att_flags & ATT_no_cleanup)
return false;
unableToRunSweepException(Arg::Gds(isc_sweep_attach_no_cleanup));

while (true)
{
AtomicCounter::counter_type old = dbb_flags;
if (old & DBB_sweep_in_progress)
{
clearSweepStarting();
return false;
unableToRunSweepException(Arg::Gds(isc_sweep_concurrent_instance));
}

if (dbb_flags.compareExchange(old, old | DBB_sweep_in_progress))
break;
}

SPTHR_DEBUG(fprintf(stderr, "allowSweepRun - set DBB_sweep_in_progress\n"));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " - set DBB_sweep_in_progress\n"));

if (!(dbb_flags & DBB_sweep_starting))
{
SPTHR_DEBUG(fprintf(stderr, "allowSweepRun - createSweepLock\n"));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " - createSweepLock\n"));

createSweepLock(tdbb);
if (!LCK_lock(tdbb, dbb_sweep_lock, LCK_EX, -1))
Expand All @@ -336,17 +344,15 @@ namespace Jrd
fb_utils::init_status(tdbb->tdbb_status_vector);

dbb_flags &= ~DBB_sweep_in_progress;
return false;
unableToRunSweepException(Arg::Gds(isc_sweep_concurrent_instance));
}
}
else
{
SPTHR_DEBUG(fprintf(stderr, "allowSweepRun - clearSweepStarting\n"));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " - clearSweepStarting\n"));
attachment->att_flags |= ATT_from_thread;
clearSweepStarting();
}

return true;
}

void Database::clearSweepFlags(thread_db* tdbb)
Expand Down
4 changes: 2 additions & 2 deletions src/jrd/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,8 @@ class Database : public pool_alloc<type_dbb>

// returns true if sweeper thread could start
bool allowSweepThread(thread_db* tdbb);
// returns true if sweep could run
bool allowSweepRun(thread_db* tdbb);
// Throw an exception if sweep cannot be run
void initiateSweepRun(thread_db* tdbb);
// reset sweep flag and release sweep lock
void clearSweepFlags(thread_db* tdbb);
// reset sweep starting flag, release thread starting mutex
Expand Down
9 changes: 4 additions & 5 deletions src/jrd/tra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1846,11 +1846,7 @@ void TRA_sweep(thread_db* tdbb)
Database* const dbb = tdbb->getDatabase();
CHECK_DBB(dbb);

if (!dbb->allowSweepRun(tdbb))
{
dbb->clearSweepFlags(tdbb);
return;
}
dbb->initiateSweepRun(tdbb);

fb_assert(dbb->dbb_flags & DBB_sweep_in_progress);

Expand Down Expand Up @@ -2756,6 +2752,9 @@ namespace {
status.check();

AutoRelease<IAttachment> att(prov->attachDatabase(&status, dbName.c_str(), dpbLen, dpbBytes));
if (fb_utils::containsErrorCode(status->getErrors(), isc_sweep_unable_to_run))
return;

status.check();
}

Expand Down
Loading