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

Fixed #7985: Hang in case of error when sweep thread is attaching to database - classic server case: i.e. backported fix for #7917

This commit is contained in:
AlexPeshkoff 2024-01-30 09:43:33 +03:00
parent 10e4f46592
commit 4c21cae778
2 changed files with 20 additions and 12 deletions

View File

@ -112,7 +112,7 @@ inline ThreadId getThreadId()
#define USE_FINI_SEM
#endif
template <typename TA>
template <typename TA, void (*cleanup) (TA) = nullptr>
class ThreadFinishSync
{
public:
@ -203,6 +203,9 @@ private:
threadArg->exceptionHandler(ex, threadRoutine);
}
#endif
if (cleanup)
cleanup(threadArg);
closing = true;
}
};

View File

@ -2708,11 +2708,6 @@ namespace {
: dbb(d)
{ }
void waitForStartup()
{
sem.enter();
}
static void runSweep(SweepParameter* par)
{
FbLocalStatus status;
@ -2735,7 +2730,6 @@ namespace {
prov->setDbCryptCallback(&status, cryptCallback);
status.check();
}
par->sem.release();
AutoDispose<IXpbBuilder> dpb(UtilInterfacePtr()->getXpbBuilder(&status, IXpbBuilder::DPB, nullptr, 0));
status.check();
@ -2759,14 +2753,26 @@ namespace {
ex.stuffException(&st);
if (st->getErrors()[1] != isc_att_shutdown)
iscLogException("Automatic sweep error", ex);
if (dbb)
{
dbb->clearSweepStarting();
SPTHR_DEBUG(fprintf(stderr, "called clearSweepStarting() dbb=%p par=%p\n", dbb, this));
dbb = nullptr;
}
}
static void cleanup(SweepParameter* par)
{
SPTHR_DEBUG(fprintf(stderr, "Cleanup dbb=%p par=%p\n", par->dbb, par));
delete par;
}
private:
Semaphore sem;
Database* dbb;
};
typedef ThreadFinishSync<SweepParameter*> SweepSync;
typedef ThreadFinishSync<SweepParameter*, SweepParameter::cleanup> SweepSync;
InitInstance<HalfStaticArray<SweepSync*, 16> > sweepThreads;
GlobalPtr<Mutex> swThrMutex;
bool sweepDown = false;
@ -2838,10 +2844,9 @@ static void start_sweeper(thread_db* tdbb)
}
AutoPtr<SweepSync> sweepSync(FB_NEW SweepSync(*getDefaultMemoryPool(), SweepParameter::runSweep));
SweepParameter swPar(dbb);
sweepSync->run(&swPar);
SweepParameter* swPar = FB_NEW SweepParameter(dbb);
sweepSync->run(swPar);
started = true;
swPar.waitForStartup();
sweepThreads().add(sweepSync.release());
}
catch (const Exception&)