@@ -75,8 +75,26 @@ namespace
75
75
const USHORT CTL_VERSION1 = 1 ;
76
76
const USHORT CTL_CURRENT_VERSION = CTL_VERSION1;
77
77
78
- volatile bool * shutdownPtr = NULL ;
78
+ volatile bool shutdownFlag = false ;
79
79
AtomicCounter activeThreads;
80
+ Semaphore shutdownSemaphore;
81
+
82
+ int shutdownHandler (const int , const int , void *)
83
+ {
84
+ if (activeThreads.value ())
85
+ {
86
+ gds__log (" Shutting down the replication server with %d replicated database(s)" ,
87
+ (int ) activeThreads.value ());
88
+
89
+ shutdownFlag = true ;
90
+ shutdownSemaphore.release (activeThreads.value () + 1 );
91
+
92
+ while (activeThreads.value ())
93
+ Thread::sleep (10 );
94
+ }
95
+
96
+ return 0 ;
97
+ }
80
98
81
99
struct ActiveTransaction
82
100
{
@@ -626,7 +644,7 @@ namespace
626
644
}
627
645
}
628
646
629
- enum ProcessStatus { PROCESS_SUSPEND, PROCESS_CONTINUE, PROCESS_ERROR };
647
+ enum ProcessStatus { PROCESS_SUSPEND, PROCESS_CONTINUE, PROCESS_ERROR, PROCESS_SHUTDOWN };
630
648
631
649
ProcessStatus process_archive (MemoryPool& pool, Target* target)
632
650
{
@@ -645,6 +663,9 @@ namespace
645
663
for (iter = PathUtils::newDirIterator (pool, config->sourceDirectory );
646
664
*iter; ++(*iter))
647
665
{
666
+ if (shutdownFlag)
667
+ return PROCESS_SHUTDOWN;
668
+
648
669
const auto filename = **iter;
649
670
650
671
#ifdef PRESERVE_LOG
@@ -755,6 +776,9 @@ namespace
755
776
756
777
for (Segment** iter = queue.begin (); iter != queue.end (); ++iter)
757
778
{
779
+ if (shutdownFlag)
780
+ return PROCESS_SHUTDOWN;
781
+
758
782
Segment* const segment = *iter;
759
783
const FB_UINT64 sequence = segment->header .hdr_sequence ;
760
784
const Guid& guid = segment->header .hdr_guid ;
@@ -845,6 +869,9 @@ namespace
845
869
ULONG totalLength = sizeof (SegmentHeader);
846
870
while (totalLength < segment->header .hdr_length )
847
871
{
872
+ if (shutdownFlag)
873
+ return PROCESS_SHUTDOWN;
874
+
848
875
Block header;
849
876
if (read (file, &header, sizeof (Block)) != sizeof (Block))
850
877
raiseError (" Journal file %s read failed (error %d)" , segment->filename .c_str (), ERRNO);
@@ -959,14 +986,12 @@ namespace
959
986
960
987
THREAD_ENTRY_DECLARE process_thread (THREAD_ENTRY_PARAM arg)
961
988
{
962
- fb_assert (shutdownPtr);
963
-
964
989
AutoPtr<Target> target (static_cast <Target*>(arg));
965
990
const auto config = target->getConfig ();
966
991
967
992
target->verbose (" Started replication thread" );
968
993
969
- while (!*shutdownPtr )
994
+ while (!shutdownFlag )
970
995
{
971
996
AutoMemoryPool workingPool (MemoryPool::createPool ());
972
997
ContextPoolHolder threadContext (workingPool);
@@ -978,42 +1003,47 @@ namespace
978
1003
979
1004
target->shutdown ();
980
1005
981
- if (!*shutdownPtr)
1006
+ if (ret == PROCESS_SHUTDOWN)
1007
+ break ;
1008
+
1009
+ if (!shutdownFlag)
982
1010
{
983
1011
const ULONG timeout =
984
1012
(ret == PROCESS_SUSPEND) ? config->applyIdleTimeout : config->applyErrorTimeout ;
985
1013
986
- Thread::sleep (timeout * 1000 );
1014
+ shutdownSemaphore. tryEnter (timeout);
987
1015
}
988
1016
}
989
1017
990
1018
target->verbose (" Finished replication thread" );
991
-
992
1019
--activeThreads;
993
1020
994
1021
return 0 ;
995
1022
}
996
1023
}
997
1024
998
- bool REPL_server (CheckStatusWrapper* status, bool wait, bool * aShutdownPtr)
1025
+
1026
+ bool REPL_server (CheckStatusWrapper* status, bool wait)
999
1027
{
1000
1028
try
1001
1029
{
1002
- shutdownPtr = aShutdownPtr ;
1030
+ fb_shutdown_callback ( 0 , shutdownHandler, fb_shut_finish, 0 ) ;
1003
1031
1004
1032
TargetList targets;
1005
1033
readConfig (targets);
1006
1034
1007
1035
for (auto target : targets)
1008
1036
{
1037
+ Thread::start (process_thread, target, THREAD_medium, NULL );
1009
1038
++activeThreads;
1010
- Thread::start ((ThreadEntryPoint*) process_thread, target, THREAD_medium, NULL );
1011
1039
}
1012
1040
1013
1041
if (wait)
1014
1042
{
1043
+ shutdownSemaphore.enter ();
1044
+
1015
1045
do {
1016
- Thread::sleep (100 );
1046
+ Thread::sleep (10 );
1017
1047
} while (activeThreads.value ());
1018
1048
}
1019
1049
}
0 commit comments