Skip to content

Commit dc32c34

Browse files
committed
Fixed #8449: Races when server is closed during forced database shutdown
(cherry picked from commit df1e8aa)
1 parent f184848 commit dc32c34

File tree

7 files changed

+60
-4
lines changed

7 files changed

+60
-4
lines changed

builds/posix/prefix.linux_amd64

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DAMD64 -pipe -MMD -fPIC -fmessage-length=0 -fno-delete-null-pointer-checks
2222
CXXFLAGS=-std=gnu++03
2323
OPTIMIZE_FLAGS=-O3 -fno-omit-frame-pointer
24-
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-invalid-offsetof -Wno-narrowing -Wno-unused-local-typedefs -Wno-class-memaccess
24+
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-invalid-offsetof -Wno-narrowing -Wno-unused-local-typedefs -Wno-class-memaccess -Wno-template-id-cdtor
2525

2626
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
2727
#DEV_FLAGS=-DUSE_VALGRIND $(COMMON_FLAGS) $(WARN_FLAGS) -fmax-errors=8

src/common/classes/init.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ class GlobalPtr : private InstanceControl
158158
{
159159
return instance;
160160
}
161+
162+
operator bool() throw()
163+
{
164+
return instance;
165+
}
161166
};
162167

163168
// InitMutex - executes static void C::init() once and only once

src/yvalve/MasterImplementation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@ Mutex& pauseTimer()
404404
return timerPause;
405405
}
406406

407+
bool timerThreadStopped()
408+
{
409+
return stopTimerThread.value() != 0;
410+
}
411+
407412
} // namespace Why
408413

409414

src/yvalve/MasterImplementation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ namespace Why
7272
void shutdownTimers();
7373

7474
Firebird::Mutex& pauseTimer();
75+
76+
bool timerThreadStopped();
7577
} // namespace Why
7678

7779
#endif // YVALVE_MASTER_IMPLEMENTATION_H

src/yvalve/PluginManager.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "../common/classes/fb_string.h"
3838
#include "../common/classes/init.h"
3939
#include "../common/classes/semaphore.h"
40+
#include "../common/classes/RefMutex.h"
4041
#include "../common/config/config.h"
4142
#include "../common/config/config_file.h"
4243
#include "../common/utils_proto.h"
@@ -476,7 +477,7 @@ namespace
476477
const PathName& pplugName)
477478
: module(pmodule), regPlugin(preg), pluginLoaderConfig(pconfig),
478479
confName(getPool(), pconfName), plugName(getPool(), pplugName),
479-
delay(DEFAULT_DELAY)
480+
processingDelayedDelete(false), delay(DEFAULT_DELAY)
480481
{
481482
if (pluginLoaderConfig.hasData())
482483
{
@@ -493,7 +494,7 @@ namespace
493494
#ifdef DEBUG_PLUGINS
494495
RegisteredPlugin& r(module->getPlugin(regPlugin));
495496
fprintf(stderr, " ConfiguredPlugin %s module %s registered as %s type %d order %d\n",
496-
plugName.c_str(), module->getName(), r.name, r.type, regPlugin);
497+
plugName.c_str(), module->getName(), r.name.c_str(), r.type, regPlugin);
497498
#endif
498499
}
499500

@@ -537,6 +538,7 @@ namespace
537538
{ }
538539

539540
int release();
541+
static void processDelayedDelete();
540542

541543
private:
542544
~ConfiguredPlugin() {}
@@ -547,6 +549,7 @@ namespace
547549
RefPtr<ConfigFile> pluginLoaderConfig;
548550
PathName confName;
549551
PathName plugName;
552+
bool processingDelayedDelete;
550553

551554
static const FB_UINT64 DEFAULT_DELAY = 1000000 * 60; // 1 min
552555
FB_UINT64 delay;
@@ -620,7 +623,7 @@ namespace
620623
~FactoryParameter()
621624
{
622625
#ifdef DEBUG_PLUGINS
623-
fprintf(stderr, "~FactoryParameter places configuredPlugin %s in unload query for %d seconds\n",
626+
fprintf(stderr, "~FactoryParameter places configuredPlugin %s in unload query for %lld seconds\n",
624627
configuredPlugin->getPlugName(), configuredPlugin->getReleaseDelay() / 1000000);
625628
#endif
626629
LocalStatus ls;
@@ -746,6 +749,9 @@ namespace
746749
*prev = this;
747750
}
748751

752+
typedef HalfStaticArray<ConfiguredPlugin*, 16> DelayedDelete;
753+
static GlobalPtr<DelayedDelete> delayedDelete;
754+
749755
int ConfiguredPlugin::release()
750756
{
751757
int x = --refCounter;
@@ -761,6 +767,15 @@ namespace
761767
if (refCounter != 0)
762768
return 1;
763769

770+
if (Why::timerThreadStopped() && !processingDelayedDelete && delayedDelete)
771+
{
772+
// delay delete
773+
addRef();
774+
delayedDelete->push(this);
775+
776+
return 1;
777+
}
778+
764779
destroy();
765780
}
766781

@@ -773,6 +788,26 @@ namespace
773788
return 1;
774789
}
775790

791+
void ConfiguredPlugin::processDelayedDelete()
792+
{
793+
DelayedDelete& dd(delayedDelete);
794+
MutexEnsureUnlock g(plugins->mutex, FB_FUNCTION);
795+
g.enter();
796+
for (unsigned n = 0; n < dd.getCount(); ++n)
797+
{
798+
ConfiguredPlugin* ptr = dd[n];
799+
if (ptr)
800+
{
801+
g.leave();
802+
ptr->processingDelayedDelete = true;
803+
ptr->release();
804+
g.enter();
805+
}
806+
dd[n] = NULL;
807+
}
808+
delayedDelete->clear();
809+
}
810+
776811
struct PluginLoadInfo
777812
{
778813
PathName curModule, regName, plugConfigFile;
@@ -1252,6 +1287,10 @@ void PluginManager::threadDetach()
12521287
modules->threadDetach();
12531288
}
12541289

1290+
void PluginManager::deleteDelayed()
1291+
{
1292+
ConfiguredPlugin::processDelayedDelete();
1293+
}
12551294

12561295
} // namespace Firebird
12571296

src/yvalve/PluginManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class PluginManager : public AutoIface<IPluginManagerImpl<PluginManager, CheckSt
5555
static void shutdown();
5656
static void waitForType(unsigned int typeThatMustGoAway);
5757
static void threadDetach();
58+
static void deleteDelayed();
5859
};
5960

6061
} // namespace Firebird

src/yvalve/why.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6031,7 +6031,10 @@ void Dispatcher::shutdown(CheckStatusWrapper* userStatus, unsigned int timeout,
60316031
}
60326032

60336033
if (hasThreads)
6034+
{
6035+
PluginManager::deleteDelayed();
60346036
continue;
6037+
}
60356038

60366039
Stack<YAttachment*, 64> attStack;
60376040
{
@@ -6061,6 +6064,7 @@ void Dispatcher::shutdown(CheckStatusWrapper* userStatus, unsigned int timeout,
60616064
attachment->release();
60626065
}
60636066

6067+
PluginManager::deleteDelayed();
60646068
}
60656069

60666070
// ... and wait for all providers to go away

0 commit comments

Comments
 (0)