1 From 40f782ae3e918c4f3842571ff8064be1c4f54961 Mon Sep 17 00:00:00 2001
2 From: AlexPeshkoff <peshkoff@mail.ru>
3 Date: Fri, 13 Jan 2017 14:29:54 +0300
4 Subject: [PATCH] Backported fix for CORE-5452: Segfault when engine's dynamic
5 library is unloaded right after closing worker threads (GC and/or cache
9 src/alice/alice_meta.epp | 1 -
11 src/common/ThreadStart.h | 86 ++++++++++++++++++++++++++++
12 src/common/classes/Synchronize.h | 5 +-
13 src/common/classes/misc/class_perf.cpp | 1 -
14 src/common/xdr.cpp | 2 -
15 src/gpre/boot/gpre_meta_boot.cpp | 1 -
16 src/gpre/std/gpre_meta.epp | 1 -
17 src/include/fb_exception.h | 1 -
18 src/include/firebird.h | 1 -
19 src/isql/OptionsBase.cpp | 1 -
20 src/isql/extract.epp | 1 -
21 src/isql/isql.epp | 5 --
22 src/jrd/Attachment.h | 1 +
23 src/jrd/Database.h | 6 +-
24 src/jrd/Mapping.cpp | 26 +++++----
25 src/jrd/cch.cpp | 31 +++++-----
26 src/jrd/cch.h | 14 ++++-
27 src/jrd/event.cpp | 13 +++--
28 src/jrd/event_proto.h | 7 +--
29 src/jrd/intl.cpp | 1 -
30 src/jrd/trace/TraceConfigStorage.h | 1 +
31 src/jrd/vio.cpp | 23 ++++----
32 src/lock/lock.cpp | 29 ++++++----
33 src/lock/lock_proto.h | 8 +--
34 src/qli/command.cpp | 1 -
36 src/qli/lex.cpp | 4 --
37 src/qli/meta.epp | 1 -
38 src/utilities/gsec/gsecswi.h | 1 -
39 src/utilities/gstat/dba.epp | 1 +
40 src/utilities/nbackup/nbkswi.h | 1 -
41 src/utilities/ntrace/os/win32/FileObject.cpp | 1 -
42 src/yvalve/gds.cpp | 1 +
43 src/yvalve/preparse.cpp | 1 -
44 35 files changed, 182 insertions(+), 99 deletions(-)
46 diff --git a/src/alice/alice_meta.epp b/src/alice/alice_meta.epp
47 index d0f59bc..65dc37e 100644
48 --- a/src/alice/alice_meta.epp
49 +++ b/src/alice/alice_meta.epp
53 #include "../jrd/ibase.h"
54 -//#include "../jrd/license.h"
55 #include "../alice/alice.h"
56 #include "../alice/alice_meta.h"
57 #include "../yvalve/gds_proto.h"
58 diff --git a/src/burp/burp.h b/src/burp/burp.h
59 index 293a91f..fe26335 100644
62 @@ -769,8 +769,6 @@ struct burp_meta_obj
63 // I need to review if we tolerate different lengths for different OS's here.
64 const unsigned int MAX_FILE_NAME_SIZE = 256;
66 -//#include "../jrd/svc.h"
68 #include "../burp/std_desc.h"
71 diff --git a/src/common/ThreadStart.h b/src/common/ThreadStart.h
72 index 85e6a38..823c5c1 100644
73 --- a/src/common/ThreadStart.h
74 +++ b/src/common/ThreadStart.h
76 #define JRD_THREADSTART_H
78 #include "../common/ThreadData.h"
79 +#include "../common/classes/semaphore.h"
83 @@ -89,4 +90,89 @@ inline ThreadId getThreadId()
84 return Thread::getId();
88 +#ifndef USE_POSIX_THREADS
92 +template <typename TA>
93 +class ThreadFinishSync
96 + typedef void ThreadRoutine(TA);
98 + ThreadFinishSync(Firebird::MemoryPool& pool, ThreadRoutine* routine, int priority_arg)
105 + threadRoutine(routine),
106 + threadPriority(priority_arg)
113 + Thread::start(internalRun, this, threadPriority
114 +#ifndef USE_FINI_SEM
120 + void waitForCompletion()
125 + Thread::waitForCompletion(threadHandle);
132 + Firebird::Semaphore fini;
134 + Thread::Handle threadHandle;
138 + ThreadRoutine* threadRoutine;
139 + int threadPriority;
142 + static THREAD_ENTRY_DECLARE internalRun(THREAD_ENTRY_PARAM arg)
144 + ((ThreadFinishSync*)arg)->internalRun();
152 + threadRoutine(threadArg);
154 + catch (const Firebird::Exception& ex)
156 + threadArg->exceptionHandler(ex, threadRoutine);
164 + catch (const Firebird::Exception& ex)
166 + threadArg->exceptionHandler(ex, threadRoutine);
172 #endif // JRD_THREADSTART_H
173 diff --git a/src/common/classes/Synchronize.h b/src/common/classes/Synchronize.h
174 index 198de44..3788541 100644
175 --- a/src/common/classes/Synchronize.h
176 +++ b/src/common/classes/Synchronize.h
178 #define CLASSES_SYNCHRONIZE_H
180 #include "../common/classes/SyncObject.h"
183 -#include "fb_pthread.h"
185 +#include "../common/ThreadStart.h"
189 diff --git a/src/common/classes/misc/class_perf.cpp b/src/common/classes/misc/class_perf.cpp
190 index 97b7bb3..142bfde 100644
191 --- a/src/common/classes/misc/class_perf.cpp
192 +++ b/src/common/classes/misc/class_perf.cpp
197 -//#include "../memory/memory_pool.h"
201 diff --git a/src/common/xdr.cpp b/src/common/xdr.cpp
202 index b9f9f4d..1dfff76 100644
203 --- a/src/common/xdr.cpp
204 +++ b/src/common/xdr.cpp
207 #include "firebird.h"
209 -//#include "../remote/remote.h"
210 #include "../common/xdr.h"
211 -//#include "../remote/proto_proto.h"
212 #include "../common/xdr_proto.h"
213 #include "../yvalve/gds_proto.h"
214 #include "../common/gdsassert.h"
215 diff --git a/src/gpre/boot/gpre_meta_boot.cpp b/src/gpre/boot/gpre_meta_boot.cpp
216 index 0fde018..1f302c6 100644
217 --- a/src/gpre/boot/gpre_meta_boot.cpp
218 +++ b/src/gpre/boot/gpre_meta_boot.cpp
221 #include "../jrd/ibase.h"
222 #include "../gpre/gpre.h"
223 -//#include "../jrd/license.h"
224 #include "../jrd/intl.h"
225 #include "../gpre/gpre_proto.h"
226 #include "../gpre/hsh_proto.h"
227 diff --git a/src/gpre/std/gpre_meta.epp b/src/gpre/std/gpre_meta.epp
228 index 34ff932..0780dd4 100644
229 --- a/src/gpre/std/gpre_meta.epp
230 +++ b/src/gpre/std/gpre_meta.epp
233 #include "../jrd/ibase.h"
234 #include "../gpre/gpre.h"
235 -//#include "../jrd/license.h"
236 #include "../jrd/intl.h"
237 #include "../gpre/gpre_proto.h"
238 #include "../gpre/hsh_proto.h"
239 diff --git a/src/include/fb_exception.h b/src/include/fb_exception.h
240 index 030cf94..c4c1df4 100644
241 --- a/src/include/fb_exception.h
242 +++ b/src/include/fb_exception.h
245 #include "fb_types.h"
246 #include "firebird/Interface.h"
247 -#include "../common/ThreadStart.h"
251 diff --git a/src/include/firebird.h b/src/include/firebird.h
252 index 3d74354..87f0a11 100644
253 --- a/src/include/firebird.h
254 +++ b/src/include/firebird.h
258 #include "../common/common.h"
259 -//#include "fb_exception.h"
263 diff --git a/src/isql/OptionsBase.cpp b/src/isql/OptionsBase.cpp
264 index 5a78540..0974fa3 100644
265 --- a/src/isql/OptionsBase.cpp
266 +++ b/src/isql/OptionsBase.cpp
269 #include "firebird.h"
270 #include "OptionsBase.h"
271 -//#include "../common/utils_proto.h" // strnicmp
272 #include "../common/gdsassert.h"
275 diff --git a/src/isql/extract.epp b/src/isql/extract.epp
276 index ec2ddb1..99e821c 100644
277 --- a/src/isql/extract.epp
278 +++ b/src/isql/extract.epp
280 #include "../jrd/ods.h"
281 #include "../common/utils_proto.h"
282 #include "../jrd/constants.h"
283 -//#include "../common/classes/ImplementHelper.h"
285 using MsgFormat::SafeArg;
287 diff --git a/src/isql/isql.epp b/src/isql/isql.epp
288 index ccadce2..98b37bb 100644
289 --- a/src/isql/isql.epp
290 +++ b/src/isql/isql.epp
292 #include "firebird.h"
294 #include "../yvalve/keywords.h"
295 -//#include "../yvalve/gds_proto.h"
296 #include "../jrd/intl.h"
304 -//#include <io.h> // mktemp
307 #ifdef HAVE_EDITLINE_H
308 // This is a local file included in our distribution - but not always
309 // compiled into the system
310 diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h
311 index 2807db3..e71610e 100644
312 --- a/src/jrd/Attachment.h
313 +++ b/src/jrd/Attachment.h
315 #include "../common/classes/array.h"
316 #include "../common/classes/stack.h"
317 #include "../common/classes/timestamp.h"
318 +#include "../common/ThreadStart.h"
320 #include "../jrd/EngineInterface.h"
322 diff --git a/src/jrd/Database.h b/src/jrd/Database.h
323 index 0eab40d..f0f44d3 100644
324 --- a/src/jrd/Database.h
325 +++ b/src/jrd/Database.h
326 @@ -440,7 +440,7 @@ public:
327 GarbageCollector* dbb_garbage_collector; // GarbageCollector class
328 Firebird::Semaphore dbb_gc_sem; // Event to wake up garbage collector
329 Firebird::Semaphore dbb_gc_init; // Event for initialization garbage collector
330 - Firebird::Semaphore dbb_gc_fini; // Event for finalization garbage collector
331 + ThreadFinishSync<Database*> dbb_gc_fini; // Sync for finalization garbage collector
333 Firebird::MemoryStats dbb_memory_stats;
334 RuntimeStatistics dbb_stats;
335 @@ -511,6 +511,7 @@ private:
338 dbb_sort_buffers(*p),
339 + dbb_gc_fini(*p, garbage_collector, THREAD_medium),
341 dbb_lock_owner_id(getLockOwnerId()),
343 @@ -560,6 +561,9 @@ public:
344 // reset sweep flags and release sweep lock
345 void clearSweepFlags(thread_db* tdbb);
347 + static void garbage_collector(Database* dbb);
348 + void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<Database*>::ThreadRoutine* routine);
351 //static int blockingAstSharedCounter(void*);
352 static int blocking_ast_sweep(void* ast_object);
353 diff --git a/src/jrd/Mapping.cpp b/src/jrd/Mapping.cpp
354 index c1bcf0e..8df7e2f 100644
355 --- a/src/jrd/Mapping.cpp
356 +++ b/src/jrd/Mapping.cpp
357 @@ -581,7 +581,8 @@ class MappingIpc FB_FINAL : public Firebird::IpcObject
360 explicit MappingIpc(MemoryPool&)
361 - : processId(getpid())
362 + : processId(getpid()),
363 + cleanupSync(*getDefaultMemoryPool(), clearDelivery, THREAD_high)
367 @@ -602,7 +603,7 @@ public:
368 sMem->process[process].flags &= ~MappingHeader::FLAG_ACTIVE;
369 (void) // Ignore errors in cleanup
370 sharedMemory->eventPost(&sMem->process[process].notifyEvent);
371 - cleanupSemaphore.tryEnter(5);
372 + cleanupSync.waitForCompletion();
374 // Ignore errors in cleanup
375 sharedMemory->eventFini(&sMem->process[process].notifyEvent);
376 @@ -755,7 +756,7 @@ public:
380 - Thread::start(clearDelivery, this, THREAD_high);
381 + cleanupSync.run(this);
383 catch (const Exception&)
385 @@ -764,6 +765,12 @@ public:
389 + void exceptionHandler(const Exception& ex, ThreadFinishSync<MappingIpc*>::ThreadRoutine*)
391 + iscLogException("Fatal error in clearDeliveryThread", ex);
392 + fb_utils::logAndDie("Fatal error in clearDeliveryThread");
396 void clearDeliveryThread()
398 @@ -801,13 +808,10 @@ private:
401 startupSemaphore.release();
403 - cleanupSemaphore.release();
405 catch (const Exception& ex)
407 - iscLogException("Fatal error in clearDeliveryThread", ex);
408 - fb_utils::logAndDie("Fatal error in clearDeliveryThread");
409 + exceptionHandler(ex, NULL);
413 @@ -862,11 +866,9 @@ private:
414 MappingIpc* const data;
417 - static THREAD_ENTRY_DECLARE clearDelivery(THREAD_ENTRY_PARAM par)
418 + static void clearDelivery(MappingIpc* mapping)
420 - MappingIpc* m = (MappingIpc*)par;
421 - m->clearDeliveryThread();
423 + mapping->clearDeliveryThread();
426 AutoPtr<SharedMemory<MappingHeader> > sharedMemory;
427 @@ -874,7 +876,7 @@ private:
428 const SLONG processId;
430 Semaphore startupSemaphore;
431 - Semaphore cleanupSemaphore;
432 + ThreadFinishSync<MappingIpc*> cleanupSync;
435 GlobalPtr<MappingIpc, InstanceControl::PRIORITY_DELETE_FIRST> mappingIpc;
436 diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp
437 index e1d403b..1bf714f 100644
438 --- a/src/jrd/cch.cpp
439 +++ b/src/jrd/cch.cpp
440 @@ -120,14 +120,11 @@ static BufferDesc* alloc_bdb(thread_db*, BufferControl*, UCHAR **);
441 static Lock* alloc_page_lock(Jrd::thread_db*, BufferDesc*);
442 static int blocking_ast_bdb(void*);
444 -static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM);
446 static void prefetch_epilogue(Prefetch*, FbStatusVector *);
447 static void prefetch_init(Prefetch*, thread_db*);
448 static void prefetch_io(Prefetch*, FbStatusVector *);
449 static void prefetch_prologue(Prefetch*, SLONG *);
451 -static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM);
452 static void check_precedence(thread_db*, WIN*, PageNumber);
453 static void clear_precedence(thread_db*, BufferDesc*);
454 static BufferDesc* dealloc_bdb(BufferDesc*);
455 @@ -1438,7 +1435,7 @@ void CCH_init2(thread_db* tdbb)
459 - Thread::start(cache_writer, dbb, THREAD_medium);
460 + bcb->bcb_writer_fini.run(bcb);
462 catch (const Exception&)
464 @@ -2017,7 +2014,7 @@ void CCH_shutdown(thread_db* tdbb)
466 bcb->bcb_flags &= ~BCB_cache_writer;
467 bcb->bcb_writer_sem.release(); // Wake up running thread
468 - bcb->bcb_writer_fini.enter();
469 + bcb->bcb_writer_fini.waitForCompletion();
472 SyncLockGuard bcbSync(&bcb->bcb_syncObject, SYNC_EXCLUSIVE, "CCH_shutdown");
473 @@ -2692,7 +2689,7 @@ static void flushAll(thread_db* tdbb, USHORT flush_flag)
477 -static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
478 +void BufferControl::cache_reader(BufferControl* bcb)
480 /**************************************
482 @@ -2706,7 +2703,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
485 **************************************/
486 - Database* dbb = (Database*) arg;
487 + Database* dbb = bcb->bcb_database;
488 Database::SyncGuard dsGuard(dbb);
490 FbLocalStatus status_vector;
491 @@ -2846,7 +2843,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
495 -static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
496 +void BufferControl::cache_writer(BufferControl* bcb)
498 /**************************************
500 @@ -2859,8 +2856,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
502 **************************************/
503 FbLocalStatus status_vector;
504 - Database* const dbb = (Database*) arg;
505 - BufferControl* const bcb = dbb->dbb_bcb;
506 + Database* const dbb = bcb->bcb_database;
510 @@ -2964,8 +2960,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
512 catch (const Firebird::Exception& ex)
514 - ex.stuffException(&status_vector);
515 - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
516 + bcb->exceptionHandler(ex, cache_writer);
519 bcb->bcb_flags &= ~BCB_cache_writer;
520 @@ -2977,15 +2972,19 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
521 bcb->bcb_flags &= ~BCB_writer_start;
522 bcb->bcb_writer_init.release();
524 - bcb->bcb_writer_fini.release();
526 catch (const Firebird::Exception& ex)
528 - ex.stuffException(&status_vector);
529 - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
530 + bcb->exceptionHandler(ex, cache_writer);
536 +void BufferControl::exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* /*routine*/)
538 + FbLocalStatus status_vector;
539 + ex.stuffException(&status_vector);
540 + iscDbLogStatus(bcb_database->dbb_filename.c_str(), &status_vector);
544 diff --git a/src/jrd/cch.h b/src/jrd/cch.h
545 index b920566..b7f8486 100644
549 #include "../common/classes/RefCounted.h"
550 #include "../common/classes/semaphore.h"
551 #include "../common/classes/SyncObject.h"
552 +#include "../common/ThreadStart.h"
553 #ifdef SUPERSERVER_V2
554 #include "../jrd/sbm.h"
555 #include "../jrd/pag.h"
556 @@ -85,7 +86,8 @@ class BufferControl : public pool_alloc<type_bcb>
557 BufferControl(MemoryPool& p, Firebird::MemoryStats& parentStats)
558 : bcb_bufferpool(&p),
559 bcb_memory_stats(&parentStats),
562 + bcb_writer_fini(p, cache_writer, THREAD_medium)
565 QUE_INIT(bcb_in_use);
566 @@ -144,18 +146,24 @@ public:
567 Firebird::SyncObject bcb_syncLRU;
568 //Firebird::SyncObject bcb_syncPageWrite;
570 + typedef ThreadFinishSync<BufferControl*> BcbSync;
572 + static void cache_writer(BufferControl* bcb);
573 Firebird::Semaphore bcb_writer_sem; // Wake up cache writer
574 Firebird::Semaphore bcb_writer_init; // Cache writer initialization
575 - Firebird::Semaphore bcb_writer_fini; // Cache writer finalization
576 + BcbSync bcb_writer_fini; // Cache writer finalization
577 #ifdef SUPERSERVER_V2
578 + static void cache_reader(BufferControl* bcb);
579 // the code in cch.cpp is not tested for semaphore instead event !!!
580 Firebird::Semaphore bcb_reader_sem; // Wake up cache reader
581 Firebird::Semaphore bcb_reader_init; // Cache reader initialization
582 - Firebird::Semaphore bcb_reader_fini; // Cache reader finalization
583 + BcbSync bcb_reader_fini; // Cache reader finalization
585 PageBitmap* bcb_prefetch; // Bitmap of pages to prefetch
588 + void exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* routine);
593 diff --git a/src/jrd/event.cpp b/src/jrd/event.cpp
594 index 3a6bf28..cb6dc33 100644
595 --- a/src/jrd/event.cpp
596 +++ b/src/jrd/event.cpp
597 @@ -126,6 +126,7 @@ EventManager::EventManager(const Firebird::string& id, Firebird::RefPtr<Config>
599 m_dbId(getPool(), id),
601 + m_cleanupSync(getPool(), watcher_thread, THREAD_medium),
602 m_sharedFileCreated(false),
605 @@ -146,7 +147,7 @@ EventManager::~EventManager()
606 // Terminate the event watcher thread
607 m_startupSemaphore.tryEnter(5);
608 (void) m_sharedMemory->eventPost(&m_process->prb_event);
609 - m_cleanupSemaphore.tryEnter(5);
610 + m_cleanupSync.waitForCompletion();
612 #ifdef HAVE_OBJECT_MAP
613 m_sharedMemory->unmapObject(&localStatus, &m_process);
614 @@ -697,7 +698,7 @@ void EventManager::create_process()
618 - Thread::start(watcher_thread, this, THREAD_medium);
619 + m_cleanupSync.run(this);
623 @@ -1414,12 +1415,16 @@ void EventManager::watcher_thread()
625 m_startupSemaphore.release();
627 - m_cleanupSemaphore.release();
629 catch (const Firebird::Exception& ex)
631 - iscLogException("Error closing event watcher thread\n", ex);
632 + exceptionHandler(ex, NULL);
636 +void EventManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine*)
638 + iscLogException("Error closing event watcher thread\n", ex);
642 diff --git a/src/jrd/event_proto.h b/src/jrd/event_proto.h
643 index 3301203..9bfd20e 100644
644 --- a/src/jrd/event_proto.h
645 +++ b/src/jrd/event_proto.h
646 @@ -63,6 +63,7 @@ public:
648 bool initialize(Firebird::SharedMemoryBase*, bool);
649 void mutexBug(int osErrorCode, const char* text);
650 + void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine* routine);
653 void acquire_shmem();
654 @@ -91,11 +92,9 @@ private:
655 void detach_shared_file();
656 void get_shared_file_name(Firebird::PathName&) const;
658 - static THREAD_ENTRY_DECLARE watcher_thread(THREAD_ENTRY_PARAM arg)
659 + static void watcher_thread(EventManager* eventMgr)
661 - EventManager* const eventMgr = static_cast<EventManager*>(arg);
662 eventMgr->watcher_thread();
666 static void mutex_bugcheck(const TEXT*, int);
667 @@ -109,7 +108,7 @@ private:
668 Firebird::AutoPtr<Firebird::SharedMemory<evh> > m_sharedMemory;
670 Firebird::Semaphore m_startupSemaphore;
671 - Firebird::Semaphore m_cleanupSemaphore;
672 + ThreadFinishSync<EventManager*> m_cleanupSync;
674 bool m_sharedFileCreated;
676 diff --git a/src/jrd/intl.cpp b/src/jrd/intl.cpp
677 index 6666c5f..b0e662b 100644
678 --- a/src/jrd/intl.cpp
679 +++ b/src/jrd/intl.cpp
681 #include "../intl/charsets.h"
682 #include "../intl/country_codes.h"
683 #include "../common/gdsassert.h"
684 -//#include "../jrd/license.h"
686 #include "../intl/ld_proto.h"
688 diff --git a/src/jrd/trace/TraceConfigStorage.h b/src/jrd/trace/TraceConfigStorage.h
689 index ca973c0..3d08143 100644
690 --- a/src/jrd/trace/TraceConfigStorage.h
691 +++ b/src/jrd/trace/TraceConfigStorage.h
693 #include "../../common/classes/fb_string.h"
694 #include "../../common/classes/init.h"
695 #include "../../common/isc_s_proto.h"
696 +#include "../../common/ThreadStart.h"
697 #include "../../jrd/trace/TraceSession.h"
698 #include "../../common/classes/RefCounted.h"
700 diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp
701 index 02c5809..8ca9f66 100644
702 --- a/src/jrd/vio.cpp
703 +++ b/src/jrd/vio.cpp
704 @@ -107,7 +107,6 @@ static bool dfw_should_know(record_param* org_rpb, record_param* new_rpb,
705 USHORT irrelevant_field, bool void_update_is_relevant = false);
706 static void garbage_collect(thread_db*, record_param*, ULONG, RecordStack&);
707 static void garbage_collect_idx(thread_db*, record_param*, Record*, Record*);
708 -static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM);
712 @@ -1958,7 +1957,7 @@ void VIO_fini(thread_db* tdbb)
714 dbb->dbb_flags &= ~DBB_garbage_collector;
715 dbb->dbb_gc_sem.release(); // Wake up running thread
716 - dbb->dbb_gc_fini.enter();
717 + dbb->dbb_gc_fini.waitForCompletion();
721 @@ -2420,7 +2419,7 @@ void VIO_init(thread_db* tdbb)
725 - Thread::start(garbage_collector, dbb, THREAD_medium);
726 + dbb->dbb_gc_fini.run(dbb);
728 catch (const Exception&)
730 @@ -4741,7 +4740,7 @@ static void garbage_collect_idx(thread_db* tdbb,
734 -static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
735 +void Database::garbage_collector(Database* dbb)
737 /**************************************
739 @@ -4758,7 +4757,6 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
741 **************************************/
742 FbLocalStatus status_vector;
743 - Database* const dbb = (Database*) arg;
747 @@ -4989,8 +4987,7 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
749 catch (const Firebird::Exception& ex)
751 - ex.stuffException(&status_vector);
752 - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
753 + dbb->exceptionHandler(ex, NULL);
756 dbb->dbb_flags &= ~(DBB_garbage_collector | DBB_gc_active | DBB_gc_pending);
757 @@ -5003,15 +5000,19 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
758 dbb->dbb_flags &= ~DBB_gc_starting;
759 dbb->dbb_gc_init.release();
761 - dbb->dbb_gc_fini.release();
763 catch (const Firebird::Exception& ex)
765 - ex.stuffException(&status_vector);
766 - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
767 + dbb->exceptionHandler(ex, NULL);
773 +void Database::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<Database*>::ThreadRoutine* /*routine*/)
775 + FbLocalStatus status_vector;
776 + ex.stuffException(&status_vector);
777 + iscDbLogStatus(dbb_filename.c_str(), &status_vector);
781 diff --git a/src/lock/lock.cpp b/src/lock/lock.cpp
782 index 89eb4c5..2ab3358 100644
783 --- a/src/lock/lock.cpp
784 +++ b/src/lock/lock.cpp
785 @@ -214,6 +214,7 @@ LockManager::LockManager(const Firebird::string& id, RefPtr<Config> conf)
786 m_sharedFileCreated(false),
789 + m_cleanupSync(getPool(), blocking_action_thread, THREAD_high),
790 m_sharedMemory(NULL),
792 m_dbId(getPool(), id),
793 @@ -259,7 +260,7 @@ LockManager::~LockManager()
794 m_sharedMemory->eventPost(&m_process->prc_blocking);
796 // Wait for the AST thread to finish cleanup or for 5 seconds
797 - m_cleanupSemaphore.tryEnter(5);
798 + m_cleanupSync.waitForCompletion();
801 #ifdef HAVE_OBJECT_MAP
802 @@ -1548,16 +1549,22 @@ void LockManager::blocking_action_thread()
804 iscLogException("Error in blocking action thread\n", x);
810 - // Wakeup the main thread waiting for our exit
811 - m_cleanupSemaphore.release();
813 - catch (const Firebird::Exception& x)
815 - iscLogException("Error closing blocking action thread\n", x);
818 +void LockManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<LockManager*>::ThreadRoutine* /*routine*/)
820 +/**************************************
822 + * e x c e p t i o n H a n d l e r
824 + **************************************
826 + * Functional description
827 + * Handler for blocking thread close bugs.
829 + **************************************/
830 + iscLogException("Error closing blocking action thread\n", ex);
834 @@ -1815,7 +1822,7 @@ bool LockManager::create_process(CheckStatusWrapper* statusVector)
838 - Thread::start(blocking_action_thread, this, THREAD_high);
839 + m_cleanupSync.run(this);
841 catch (const Exception& ex)
843 diff --git a/src/lock/lock_proto.h b/src/lock/lock_proto.h
844 index d991c1e..2faec49 100644
845 --- a/src/lock/lock_proto.h
846 +++ b/src/lock/lock_proto.h
847 @@ -418,6 +418,8 @@ public:
848 SINT64 readData2(USHORT, const UCHAR*, USHORT, SRQ_PTR);
849 SINT64 writeData(SRQ_PTR, SINT64);
851 + void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<LockManager*>::ThreadRoutine* routine);
854 explicit LockManager(const Firebird::string&, Firebird::RefPtr<Config>);
856 @@ -471,11 +473,9 @@ private:
857 void detach_shared_file(Firebird::CheckStatusWrapper*);
858 void get_shared_file_name(Firebird::PathName&, ULONG extend = 0) const;
860 - static THREAD_ENTRY_DECLARE blocking_action_thread(THREAD_ENTRY_PARAM arg)
861 + static void blocking_action_thread(LockManager* lockMgr)
863 - LockManager* const lockMgr = static_cast<LockManager*>(arg);
864 lockMgr->blocking_action_thread();
868 bool initialize(Firebird::SharedMemoryBase* sm, bool init);
869 @@ -490,7 +490,7 @@ private:
870 Firebird::RWLock m_remapSync;
871 Firebird::AtomicCounter m_waitingOwners;
873 - Firebird::Semaphore m_cleanupSemaphore;
874 + ThreadFinishSync<LockManager*> m_cleanupSync;
875 Firebird::Semaphore m_startupSemaphore;
878 diff --git a/src/qli/command.cpp b/src/qli/command.cpp
879 index 5f949f3..fbbf4fb 100644
880 --- a/src/qli/command.cpp
881 +++ b/src/qli/command.cpp
883 #include "../qli/parse.h"
884 #include "../qli/compile.h"
885 #include "../qli/exe.h"
886 -//#include "../jrd/license.h"
887 #include "../qli/all_proto.h"
888 #include "../qli/err_proto.h"
889 #include "../qli/exe_proto.h"
890 diff --git a/src/qli/dtr.h b/src/qli/dtr.h
891 index ba5cd64..e246ef4 100644
894 @@ -480,7 +480,6 @@ struct qli_fun
897 // Program wide globals
898 -//#include <setjmp.h>
902 diff --git a/src/qli/lex.cpp b/src/qli/lex.cpp
903 index c20d1f9..9e26046 100644
904 --- a/src/qli/lex.cpp
905 +++ b/src/qli/lex.cpp
906 @@ -50,10 +50,6 @@ using MsgFormat::SafeArg;
910 -//#ifdef HAVE_CTYPES_H
911 -//#include <ctypes.h>
915 #include <io.h> // isatty
917 diff --git a/src/qli/meta.epp b/src/qli/meta.epp
918 index a7f222c..2d55716 100644
919 --- a/src/qli/meta.epp
920 +++ b/src/qli/meta.epp
922 #include "../qli/dtr.h"
923 #include "../qli/compile.h"
924 #include "../qli/exe.h"
925 -//#include "../jrd/license.h"
926 #include "../jrd/flags.h"
927 #include "../jrd/ibase.h"
928 #include "../qli/reqs.h"
929 diff --git a/src/utilities/gsec/gsecswi.h b/src/utilities/gsec/gsecswi.h
930 index b8519f5..9b560e3 100644
931 --- a/src/utilities/gsec/gsecswi.h
932 +++ b/src/utilities/gsec/gsecswi.h
934 #ifndef GSEC_GSECSWI_H
935 #define GSEC_GSECSWI_H
937 -//#include "../common/common.h"
938 #include "../jrd/constants.h"
940 /* Switch handling constants. Note that the first IN_SW_DATA_ITEMS
941 diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp
942 index 379b418..19b99d1 100644
943 --- a/src/utilities/gstat/dba.epp
944 +++ b/src/utilities/gstat/dba.epp
946 #include "../common/classes/UserBlob.h"
947 #include "../common/os/os_utils.h"
948 #include "../common/StatusHolder.h"
949 +#include "../common/ThreadStart.h"
951 using MsgFormat::SafeArg;
953 diff --git a/src/utilities/nbackup/nbkswi.h b/src/utilities/nbackup/nbkswi.h
954 index 4326c3d..b8d43da 100644
955 --- a/src/utilities/nbackup/nbkswi.h
956 +++ b/src/utilities/nbackup/nbkswi.h
958 #ifndef NBACKUP_NBKSWI_H
959 #define NBACKUP_NBKSWI_H
961 -//#include "../common/common.h"
962 #include "../jrd/constants.h"
964 // Switch handling constants
965 diff --git a/src/utilities/ntrace/os/win32/FileObject.cpp b/src/utilities/ntrace/os/win32/FileObject.cpp
966 index 73ed38f..53fbfc0 100644
967 --- a/src/utilities/ntrace/os/win32/FileObject.cpp
968 +++ b/src/utilities/ntrace/os/win32/FileObject.cpp
971 #include "firebird.h"
972 #include "../FileObject.h"
973 -//#include "../common/classes/locks.h"
975 using namespace Firebird;
976 Firebird::Mutex open_mutex;
977 diff --git a/src/yvalve/gds.cpp b/src/yvalve/gds.cpp
978 index c851f7c..998bbde 100644
979 --- a/src/yvalve/gds.cpp
980 +++ b/src/yvalve/gds.cpp
982 #include "../common/classes/init.h"
983 #include "../common/classes/TempFile.h"
984 #include "../common/utils_proto.h"
985 +#include "../common/ThreadStart.h"
989 diff --git a/src/yvalve/preparse.cpp b/src/yvalve/preparse.cpp
990 index b2335a5..e742784 100644
991 --- a/src/yvalve/preparse.cpp
992 +++ b/src/yvalve/preparse.cpp
994 #include "firebird.h"
997 -//#include "../dsql/chars.h"
998 #include "../yvalve/prepa_proto.h"
999 #include "../yvalve/gds_proto.h"
1000 #include "../yvalve/YObjects.h"
1001 --- a/src/common/isc_sync.cpp
1002 +++ b/src/common/isc_sync.cpp
1004 #include "../common/classes/RefMutex.h"
1005 #include "../common/classes/array.h"
1006 #include "../common/StatusHolder.h"
1007 +#include "../common/ThreadStart.h"
1009 static int process_id;