1From 40f782ae3e918c4f3842571ff8064be1c4f54961 Mon Sep 17 00:00:00 2001 2From: AlexPeshkoff <peshkoff@mail.ru> 3Date: Fri, 13 Jan 2017 14:29:54 +0300 4Subject: [PATCH] Backported fix for CORE-5452: Segfault when engine's dynamic 5 library is unloaded right after closing worker threads (GC and/or cache 6 writer) 7 8--- 9 src/alice/alice_meta.epp | 1 - 10 src/burp/burp.h | 2 - 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 - 35 src/qli/dtr.h | 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(-) 45 46diff --git a/src/alice/alice_meta.epp b/src/alice/alice_meta.epp 47index d0f59bc..65dc37e 100644 48--- a/src/alice/alice_meta.epp 49+++ b/src/alice/alice_meta.epp 50@@ -30,7 +30,6 @@ 51 #include "firebird.h" 52 #include <stdio.h> 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" 58diff --git a/src/burp/burp.h b/src/burp/burp.h 59index 293a91f..fe26335 100644 60--- a/src/burp/burp.h 61+++ b/src/burp/burp.h 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; 65 66-//#include "../jrd/svc.h" 67- 68 #include "../burp/std_desc.h" 69 70 #ifdef WIN_NT 71diff --git a/src/common/ThreadStart.h b/src/common/ThreadStart.h 72index 85e6a38..823c5c1 100644 73--- a/src/common/ThreadStart.h 74+++ b/src/common/ThreadStart.h 75@@ -31,6 +31,7 @@ 76 #define JRD_THREADSTART_H 77 78 #include "../common/ThreadData.h" 79+#include "../common/classes/semaphore.h" 80 81 #ifdef WIN_NT 82 #include <windows.h> 83@@ -89,4 +90,89 @@ inline ThreadId getThreadId() 84 return Thread::getId(); 85 } 86 87+ 88+#ifndef USE_POSIX_THREADS 89+#define USE_FINI_SEM 90+#endif 91+ 92+template <typename TA> 93+class ThreadFinishSync 94+{ 95+public: 96+ typedef void ThreadRoutine(TA); 97+ 98+ ThreadFinishSync(Firebird::MemoryPool& pool, ThreadRoutine* routine, int priority_arg) 99+ : 100+#ifdef USE_FINI_SEM 101+ fini(pool), 102+#else 103+ threadHandle(0), 104+#endif 105+ threadRoutine(routine), 106+ threadPriority(priority_arg) 107+ { } 108+ 109+ void run(TA arg) 110+ { 111+ threadArg = arg; 112+ 113+ Thread::start(internalRun, this, threadPriority 114+#ifndef USE_FINI_SEM 115+ , &threadHandle 116+#endif 117+ ); 118+ } 119+ 120+ void waitForCompletion() 121+ { 122+#ifdef USE_FINI_SEM 123+ fini.enter(); 124+#else 125+ Thread::waitForCompletion(threadHandle); 126+ threadHandle = 0; 127+#endif 128+ } 129+ 130+private: 131+#ifdef USE_FINI_SEM 132+ Firebird::Semaphore fini; 133+#else 134+ Thread::Handle threadHandle; 135+#endif 136+ 137+ TA threadArg; 138+ ThreadRoutine* threadRoutine; 139+ int threadPriority; 140+ bool starting; 141+ 142+ static THREAD_ENTRY_DECLARE internalRun(THREAD_ENTRY_PARAM arg) 143+ { 144+ ((ThreadFinishSync*)arg)->internalRun(); 145+ return 0; 146+ } 147+ 148+ void internalRun() 149+ { 150+ try 151+ { 152+ threadRoutine(threadArg); 153+ } 154+ catch (const Firebird::Exception& ex) 155+ { 156+ threadArg->exceptionHandler(ex, threadRoutine); 157+ } 158+ 159+#ifdef USE_FINI_SEM 160+ try 161+ { 162+ fini.release(); 163+ } 164+ catch (const Firebird::Exception& ex) 165+ { 166+ threadArg->exceptionHandler(ex, threadRoutine); 167+ } 168+#endif 169+ } 170+}; 171+ 172 #endif // JRD_THREADSTART_H 173diff --git a/src/common/classes/Synchronize.h b/src/common/classes/Synchronize.h 174index 198de44..3788541 100644 175--- a/src/common/classes/Synchronize.h 176+++ b/src/common/classes/Synchronize.h 177@@ -33,10 +33,7 @@ 178 #define CLASSES_SYNCHRONIZE_H 179 180 #include "../common/classes/SyncObject.h" 181- 182-#ifndef WIN_NT 183-#include "fb_pthread.h" 184-#endif 185+#include "../common/ThreadStart.h" 186 187 188 namespace Firebird { 189diff --git a/src/common/classes/misc/class_perf.cpp b/src/common/classes/misc/class_perf.cpp 190index 97b7bb3..142bfde 100644 191--- a/src/common/classes/misc/class_perf.cpp 192+++ b/src/common/classes/misc/class_perf.cpp 193@@ -28,7 +28,6 @@ 194 195 #include "tree.h" 196 #include "alloc.h" 197-//#include "../memory/memory_pool.h" 198 #include <stdio.h> 199 #include <time.h> 200 #include <set> 201diff --git a/src/common/xdr.cpp b/src/common/xdr.cpp 202index b9f9f4d..1dfff76 100644 203--- a/src/common/xdr.cpp 204+++ b/src/common/xdr.cpp 205@@ -26,9 +26,7 @@ 206 207 #include "firebird.h" 208 #include <string.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" 215diff --git a/src/gpre/boot/gpre_meta_boot.cpp b/src/gpre/boot/gpre_meta_boot.cpp 216index 0fde018..1f302c6 100644 217--- a/src/gpre/boot/gpre_meta_boot.cpp 218+++ b/src/gpre/boot/gpre_meta_boot.cpp 219@@ -32,7 +32,6 @@ 220 #include <string.h> 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" 227diff --git a/src/gpre/std/gpre_meta.epp b/src/gpre/std/gpre_meta.epp 228index 34ff932..0780dd4 100644 229--- a/src/gpre/std/gpre_meta.epp 230+++ b/src/gpre/std/gpre_meta.epp 231@@ -32,7 +32,6 @@ 232 #include <string.h> 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" 239diff --git a/src/include/fb_exception.h b/src/include/fb_exception.h 240index 030cf94..c4c1df4 100644 241--- a/src/include/fb_exception.h 242+++ b/src/include/fb_exception.h 243@@ -43,7 +43,6 @@ 244 245 #include "fb_types.h" 246 #include "firebird/Interface.h" 247-#include "../common/ThreadStart.h" 248 249 namespace Firebird 250 { 251diff --git a/src/include/firebird.h b/src/include/firebird.h 252index 3d74354..87f0a11 100644 253--- a/src/include/firebird.h 254+++ b/src/include/firebird.h 255@@ -68,7 +68,6 @@ 256 257 #ifdef __cplusplus 258 #include "../common/common.h" 259-//#include "fb_exception.h" 260 #endif 261 262 #ifndef NULL 263diff --git a/src/isql/OptionsBase.cpp b/src/isql/OptionsBase.cpp 264index 5a78540..0974fa3 100644 265--- a/src/isql/OptionsBase.cpp 266+++ b/src/isql/OptionsBase.cpp 267@@ -24,7 +24,6 @@ 268 269 #include "firebird.h" 270 #include "OptionsBase.h" 271-//#include "../common/utils_proto.h" // strnicmp 272 #include "../common/gdsassert.h" 273 274 275diff --git a/src/isql/extract.epp b/src/isql/extract.epp 276index ec2ddb1..99e821c 100644 277--- a/src/isql/extract.epp 278+++ b/src/isql/extract.epp 279@@ -59,7 +59,6 @@ 280 #include "../jrd/ods.h" 281 #include "../common/utils_proto.h" 282 #include "../jrd/constants.h" 283-//#include "../common/classes/ImplementHelper.h" 284 285 using MsgFormat::SafeArg; 286 287diff --git a/src/isql/isql.epp b/src/isql/isql.epp 288index ccadce2..98b37bb 100644 289--- a/src/isql/isql.epp 290+++ b/src/isql/isql.epp 291@@ -46,7 +46,6 @@ 292 #include "firebird.h" 293 #include <stdio.h> 294 #include "../yvalve/keywords.h" 295-//#include "../yvalve/gds_proto.h" 296 #include "../jrd/intl.h" 297 #include <stdlib.h> 298 #include <stdarg.h> 299@@ -79,10 +78,6 @@ 300 #include <locale.h> 301 #endif 302 303-//#ifdef HAVE_IO_H 304-//#include <io.h> // mktemp 305-//#endif 306- 307 #ifdef HAVE_EDITLINE_H 308 // This is a local file included in our distribution - but not always 309 // compiled into the system 310diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h 311index 2807db3..e71610e 100644 312--- a/src/jrd/Attachment.h 313+++ b/src/jrd/Attachment.h 314@@ -39,6 +39,7 @@ 315 #include "../common/classes/array.h" 316 #include "../common/classes/stack.h" 317 #include "../common/classes/timestamp.h" 318+#include "../common/ThreadStart.h" 319 320 #include "../jrd/EngineInterface.h" 321 322diff --git a/src/jrd/Database.h b/src/jrd/Database.h 323index 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 332 333 Firebird::MemoryStats dbb_memory_stats; 334 RuntimeStatistics dbb_stats; 335@@ -511,6 +511,7 @@ private: 336 dbb_owner(*p), 337 dbb_pools(*p, 4), 338 dbb_sort_buffers(*p), 339+ dbb_gc_fini(*p, garbage_collector, THREAD_medium), 340 dbb_stats(*p), 341 dbb_lock_owner_id(getLockOwnerId()), 342 dbb_tip_cache(NULL), 343@@ -560,6 +561,9 @@ public: 344 // reset sweep flags and release sweep lock 345 void clearSweepFlags(thread_db* tdbb); 346 347+ static void garbage_collector(Database* dbb); 348+ void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<Database*>::ThreadRoutine* routine); 349+ 350 private: 351 //static int blockingAstSharedCounter(void*); 352 static int blocking_ast_sweep(void* ast_object); 353diff --git a/src/jrd/Mapping.cpp b/src/jrd/Mapping.cpp 354index 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 358 359 public: 360 explicit MappingIpc(MemoryPool&) 361- : processId(getpid()) 362+ : processId(getpid()), 363+ cleanupSync(*getDefaultMemoryPool(), clearDelivery, THREAD_high) 364 { } 365 366 ~MappingIpc() 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(); 373 374 // Ignore errors in cleanup 375 sharedMemory->eventFini(&sMem->process[process].notifyEvent); 376@@ -755,7 +756,7 @@ public: 377 378 try 379 { 380- Thread::start(clearDelivery, this, THREAD_high); 381+ cleanupSync.run(this); 382 } 383 catch (const Exception&) 384 { 385@@ -764,6 +765,12 @@ public: 386 } 387 } 388 389+ void exceptionHandler(const Exception& ex, ThreadFinishSync<MappingIpc*>::ThreadRoutine*) 390+ { 391+ iscLogException("Fatal error in clearDeliveryThread", ex); 392+ fb_utils::logAndDie("Fatal error in clearDeliveryThread"); 393+ } 394+ 395 private: 396 void clearDeliveryThread() 397 { 398@@ -801,13 +808,10 @@ private: 399 } 400 if (startup) 401 startupSemaphore.release(); 402- 403- cleanupSemaphore.release(); 404 } 405 catch (const Exception& ex) 406 { 407- iscLogException("Fatal error in clearDeliveryThread", ex); 408- fb_utils::logAndDie("Fatal error in clearDeliveryThread"); 409+ exceptionHandler(ex, NULL); 410 } 411 } 412 413@@ -862,11 +866,9 @@ private: 414 MappingIpc* const data; 415 }; 416 417- static THREAD_ENTRY_DECLARE clearDelivery(THREAD_ENTRY_PARAM par) 418+ static void clearDelivery(MappingIpc* mapping) 419 { 420- MappingIpc* m = (MappingIpc*)par; 421- m->clearDeliveryThread(); 422- return 0; 423+ mapping->clearDeliveryThread(); 424 } 425 426 AutoPtr<SharedMemory<MappingHeader> > sharedMemory; 427@@ -874,7 +876,7 @@ private: 428 const SLONG processId; 429 unsigned process; 430 Semaphore startupSemaphore; 431- Semaphore cleanupSemaphore; 432+ ThreadFinishSync<MappingIpc*> cleanupSync; 433 }; 434 435 GlobalPtr<MappingIpc, InstanceControl::PRIORITY_DELETE_FIRST> mappingIpc; 436diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp 437index 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*); 443 #ifdef CACHE_READER 444-static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM); 445- 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 *); 450 #endif 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) 456 457 try 458 { 459- Thread::start(cache_writer, dbb, THREAD_medium); 460+ bcb->bcb_writer_fini.run(bcb); 461 } 462 catch (const Exception&) 463 { 464@@ -2017,7 +2014,7 @@ void CCH_shutdown(thread_db* tdbb) 465 { 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(); 470 } 471 472 SyncLockGuard bcbSync(&bcb->bcb_syncObject, SYNC_EXCLUSIVE, "CCH_shutdown"); 473@@ -2692,7 +2689,7 @@ static void flushAll(thread_db* tdbb, USHORT flush_flag) 474 475 476 #ifdef CACHE_READER 477-static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg) 478+void BufferControl::cache_reader(BufferControl* bcb) 479 { 480 /************************************** 481 * 482@@ -2706,7 +2703,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg) 483 * busy at a time. 484 * 485 **************************************/ 486- Database* dbb = (Database*) arg; 487+ Database* dbb = bcb->bcb_database; 488 Database::SyncGuard dsGuard(dbb); 489 490 FbLocalStatus status_vector; 491@@ -2846,7 +2843,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg) 492 #endif 493 494 495-static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg) 496+void BufferControl::cache_writer(BufferControl* bcb) 497 { 498 /************************************** 499 * 500@@ -2859,8 +2856,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg) 501 * 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; 507 508 try 509 { 510@@ -2964,8 +2960,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg) 511 } // try 512 catch (const Firebird::Exception& ex) 513 { 514- ex.stuffException(&status_vector); 515- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); 516+ bcb->exceptionHandler(ex, cache_writer); 517 } 518 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(); 523 } 524- bcb->bcb_writer_fini.release(); 525 } 526 catch (const Firebird::Exception& ex) 527 { 528- ex.stuffException(&status_vector); 529- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); 530+ bcb->exceptionHandler(ex, cache_writer); 531 } 532+} 533 534- return 0; 535+ 536+void BufferControl::exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* /*routine*/) 537+{ 538+ FbLocalStatus status_vector; 539+ ex.stuffException(&status_vector); 540+ iscDbLogStatus(bcb_database->dbb_filename.c_str(), &status_vector); 541 } 542 543 544diff --git a/src/jrd/cch.h b/src/jrd/cch.h 545index b920566..b7f8486 100644 546--- a/src/jrd/cch.h 547+++ b/src/jrd/cch.h 548@@ -29,6 +29,7 @@ 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), 560- bcb_memory(p) 561+ bcb_memory(p), 562+ bcb_writer_fini(p, cache_writer, THREAD_medium) 563 { 564 bcb_database = NULL; 565 QUE_INIT(bcb_in_use); 566@@ -144,18 +146,24 @@ public: 567 Firebird::SyncObject bcb_syncLRU; 568 //Firebird::SyncObject bcb_syncPageWrite; 569 570+ typedef ThreadFinishSync<BufferControl*> BcbSync; 571+ 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 584 585 PageBitmap* bcb_prefetch; // Bitmap of pages to prefetch 586 #endif 587 588+ void exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* routine); 589+ 590 bcb_repeat* bcb_rpt; 591 }; 592 593diff --git a/src/jrd/event.cpp b/src/jrd/event.cpp 594index 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> 598 m_processOffset(0), 599 m_dbId(getPool(), id), 600 m_config(conf), 601+ m_cleanupSync(getPool(), watcher_thread, THREAD_medium), 602 m_sharedFileCreated(false), 603 m_exiting(false) 604 { 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(); 611 612 #ifdef HAVE_OBJECT_MAP 613 m_sharedMemory->unmapObject(&localStatus, &m_process); 614@@ -697,7 +698,7 @@ void EventManager::create_process() 615 616 release_shmem(); 617 618- Thread::start(watcher_thread, this, THREAD_medium); 619+ m_cleanupSync.run(this); 620 } 621 622 623@@ -1414,12 +1415,16 @@ void EventManager::watcher_thread() 624 { 625 m_startupSemaphore.release(); 626 } 627- m_cleanupSemaphore.release(); 628 } 629 catch (const Firebird::Exception& ex) 630 { 631- iscLogException("Error closing event watcher thread\n", ex); 632+ exceptionHandler(ex, NULL); 633 } 634 } 635 636+void EventManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine*) 637+{ 638+ iscLogException("Error closing event watcher thread\n", ex); 639+} 640+ 641 } // namespace 642diff --git a/src/jrd/event_proto.h b/src/jrd/event_proto.h 643index 3301203..9bfd20e 100644 644--- a/src/jrd/event_proto.h 645+++ b/src/jrd/event_proto.h 646@@ -63,6 +63,7 @@ public: 647 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); 651 652 private: 653 void acquire_shmem(); 654@@ -91,11 +92,9 @@ private: 655 void detach_shared_file(); 656 void get_shared_file_name(Firebird::PathName&) const; 657 658- static THREAD_ENTRY_DECLARE watcher_thread(THREAD_ENTRY_PARAM arg) 659+ static void watcher_thread(EventManager* eventMgr) 660 { 661- EventManager* const eventMgr = static_cast<EventManager*>(arg); 662 eventMgr->watcher_thread(); 663- return 0; 664 } 665 666 static void mutex_bugcheck(const TEXT*, int); 667@@ -109,7 +108,7 @@ private: 668 Firebird::AutoPtr<Firebird::SharedMemory<evh> > m_sharedMemory; 669 670 Firebird::Semaphore m_startupSemaphore; 671- Firebird::Semaphore m_cleanupSemaphore; 672+ ThreadFinishSync<EventManager*> m_cleanupSync; 673 674 bool m_sharedFileCreated; 675 bool m_exiting; 676diff --git a/src/jrd/intl.cpp b/src/jrd/intl.cpp 677index 6666c5f..b0e662b 100644 678--- a/src/jrd/intl.cpp 679+++ b/src/jrd/intl.cpp 680@@ -104,7 +104,6 @@ 681 #include "../intl/charsets.h" 682 #include "../intl/country_codes.h" 683 #include "../common/gdsassert.h" 684-//#include "../jrd/license.h" 685 #ifdef INTL_BUILTIN 686 #include "../intl/ld_proto.h" 687 #endif 688diff --git a/src/jrd/trace/TraceConfigStorage.h b/src/jrd/trace/TraceConfigStorage.h 689index ca973c0..3d08143 100644 690--- a/src/jrd/trace/TraceConfigStorage.h 691+++ b/src/jrd/trace/TraceConfigStorage.h 692@@ -32,6 +32,7 @@ 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" 699 700diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp 701index 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); 709 710 711 #ifdef VIO_DEBUG 712@@ -1958,7 +1957,7 @@ void VIO_fini(thread_db* tdbb) 713 { 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(); 718 } 719 } 720 721@@ -2420,7 +2419,7 @@ void VIO_init(thread_db* tdbb) 722 { 723 try 724 { 725- Thread::start(garbage_collector, dbb, THREAD_medium); 726+ dbb->dbb_gc_fini.run(dbb); 727 } 728 catch (const Exception&) 729 { 730@@ -4741,7 +4740,7 @@ static void garbage_collect_idx(thread_db* tdbb, 731 } 732 733 734-static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg) 735+void Database::garbage_collector(Database* dbb) 736 { 737 /************************************** 738 * 739@@ -4758,7 +4757,6 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg) 740 * 741 **************************************/ 742 FbLocalStatus status_vector; 743- Database* const dbb = (Database*) arg; 744 745 try 746 { 747@@ -4989,8 +4987,7 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg) 748 } // try 749 catch (const Firebird::Exception& ex) 750 { 751- ex.stuffException(&status_vector); 752- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); 753+ dbb->exceptionHandler(ex, NULL); 754 } 755 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(); 760 } 761- dbb->dbb_gc_fini.release(); 762 } 763 catch (const Firebird::Exception& ex) 764 { 765- ex.stuffException(&status_vector); 766- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); 767+ dbb->exceptionHandler(ex, NULL); 768 } 769+} 770+ 771 772- return 0; 773+void Database::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<Database*>::ThreadRoutine* /*routine*/) 774+{ 775+ FbLocalStatus status_vector; 776+ ex.stuffException(&status_vector); 777+ iscDbLogStatus(dbb_filename.c_str(), &status_vector); 778 } 779 780 781diff --git a/src/lock/lock.cpp b/src/lock/lock.cpp 782index 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), 787 m_process(NULL), 788 m_processOffset(0), 789+ m_cleanupSync(getPool(), blocking_action_thread, THREAD_high), 790 m_sharedMemory(NULL), 791 m_blockage(false), 792 m_dbId(getPool(), id), 793@@ -259,7 +260,7 @@ LockManager::~LockManager() 794 m_sharedMemory->eventPost(&m_process->prc_blocking); 795 796 // Wait for the AST thread to finish cleanup or for 5 seconds 797- m_cleanupSemaphore.tryEnter(5); 798+ m_cleanupSync.waitForCompletion(); 799 } 800 801 #ifdef HAVE_OBJECT_MAP 802@@ -1548,16 +1549,22 @@ void LockManager::blocking_action_thread() 803 { 804 iscLogException("Error in blocking action thread\n", x); 805 } 806+} 807 808- try 809- { 810- // Wakeup the main thread waiting for our exit 811- m_cleanupSemaphore.release(); 812- } 813- catch (const Firebird::Exception& x) 814- { 815- iscLogException("Error closing blocking action thread\n", x); 816- } 817+ 818+void LockManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<LockManager*>::ThreadRoutine* /*routine*/) 819+{ 820+/************************************** 821+ * 822+ * e x c e p t i o n H a n d l e r 823+ * 824+ ************************************** 825+ * 826+ * Functional description 827+ * Handler for blocking thread close bugs. 828+ * 829+ **************************************/ 830+ iscLogException("Error closing blocking action thread\n", ex); 831 } 832 833 834@@ -1815,7 +1822,7 @@ bool LockManager::create_process(CheckStatusWrapper* statusVector) 835 { 836 try 837 { 838- Thread::start(blocking_action_thread, this, THREAD_high); 839+ m_cleanupSync.run(this); 840 } 841 catch (const Exception& ex) 842 { 843diff --git a/src/lock/lock_proto.h b/src/lock/lock_proto.h 844index 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); 850 851+ void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<LockManager*>::ThreadRoutine* routine); 852+ 853 private: 854 explicit LockManager(const Firebird::string&, Firebird::RefPtr<Config>); 855 ~LockManager(); 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; 859 860- static THREAD_ENTRY_DECLARE blocking_action_thread(THREAD_ENTRY_PARAM arg) 861+ static void blocking_action_thread(LockManager* lockMgr) 862 { 863- LockManager* const lockMgr = static_cast<LockManager*>(arg); 864 lockMgr->blocking_action_thread(); 865- return 0; 866 } 867 868 bool initialize(Firebird::SharedMemoryBase* sm, bool init); 869@@ -490,7 +490,7 @@ private: 870 Firebird::RWLock m_remapSync; 871 Firebird::AtomicCounter m_waitingOwners; 872 873- Firebird::Semaphore m_cleanupSemaphore; 874+ ThreadFinishSync<LockManager*> m_cleanupSync; 875 Firebird::Semaphore m_startupSemaphore; 876 877 public: 878diff --git a/src/qli/command.cpp b/src/qli/command.cpp 879index 5f949f3..fbbf4fb 100644 880--- a/src/qli/command.cpp 881+++ b/src/qli/command.cpp 882@@ -30,7 +30,6 @@ 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" 890diff --git a/src/qli/dtr.h b/src/qli/dtr.h 891index ba5cd64..e246ef4 100644 892--- a/src/qli/dtr.h 893+++ b/src/qli/dtr.h 894@@ -480,7 +480,6 @@ struct qli_fun 895 }; 896 897 // Program wide globals 898-//#include <setjmp.h> 899 900 #ifdef QLI_MAIN 901 #define EXTERN 902diff --git a/src/qli/lex.cpp b/src/qli/lex.cpp 903index c20d1f9..9e26046 100644 904--- a/src/qli/lex.cpp 905+++ b/src/qli/lex.cpp 906@@ -50,10 +50,6 @@ using MsgFormat::SafeArg; 907 #include <unistd.h> 908 #endif 909 910-//#ifdef HAVE_CTYPES_H 911-//#include <ctypes.h> 912-//#endif 913- 914 #ifdef HAVE_IO_H 915 #include <io.h> // isatty 916 #endif 917diff --git a/src/qli/meta.epp b/src/qli/meta.epp 918index a7f222c..2d55716 100644 919--- a/src/qli/meta.epp 920+++ b/src/qli/meta.epp 921@@ -28,7 +28,6 @@ 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" 929diff --git a/src/utilities/gsec/gsecswi.h b/src/utilities/gsec/gsecswi.h 930index b8519f5..9b560e3 100644 931--- a/src/utilities/gsec/gsecswi.h 932+++ b/src/utilities/gsec/gsecswi.h 933@@ -24,7 +24,6 @@ 934 #ifndef GSEC_GSECSWI_H 935 #define GSEC_GSECSWI_H 936 937-//#include "../common/common.h" 938 #include "../jrd/constants.h" 939 940 /* Switch handling constants. Note that the first IN_SW_DATA_ITEMS 941diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp 942index 379b418..19b99d1 100644 943--- a/src/utilities/gstat/dba.epp 944+++ b/src/utilities/gstat/dba.epp 945@@ -56,6 +56,7 @@ 946 #include "../common/classes/UserBlob.h" 947 #include "../common/os/os_utils.h" 948 #include "../common/StatusHolder.h" 949+#include "../common/ThreadStart.h" 950 951 using MsgFormat::SafeArg; 952 953diff --git a/src/utilities/nbackup/nbkswi.h b/src/utilities/nbackup/nbkswi.h 954index 4326c3d..b8d43da 100644 955--- a/src/utilities/nbackup/nbkswi.h 956+++ b/src/utilities/nbackup/nbkswi.h 957@@ -27,7 +27,6 @@ 958 #ifndef NBACKUP_NBKSWI_H 959 #define NBACKUP_NBKSWI_H 960 961-//#include "../common/common.h" 962 #include "../jrd/constants.h" 963 964 // Switch handling constants 965diff --git a/src/utilities/ntrace/os/win32/FileObject.cpp b/src/utilities/ntrace/os/win32/FileObject.cpp 966index 73ed38f..53fbfc0 100644 967--- a/src/utilities/ntrace/os/win32/FileObject.cpp 968+++ b/src/utilities/ntrace/os/win32/FileObject.cpp 969@@ -27,7 +27,6 @@ 970 971 #include "firebird.h" 972 #include "../FileObject.h" 973-//#include "../common/classes/locks.h" 974 975 using namespace Firebird; 976 Firebird::Mutex open_mutex; 977diff --git a/src/yvalve/gds.cpp b/src/yvalve/gds.cpp 978index c851f7c..998bbde 100644 979--- a/src/yvalve/gds.cpp 980+++ b/src/yvalve/gds.cpp 981@@ -57,6 +57,7 @@ 982 #include "../common/classes/init.h" 983 #include "../common/classes/TempFile.h" 984 #include "../common/utils_proto.h" 985+#include "../common/ThreadStart.h" 986 987 #ifdef HAVE_UNISTD_H 988 #include <unistd.h> 989diff --git a/src/yvalve/preparse.cpp b/src/yvalve/preparse.cpp 990index b2335a5..e742784 100644 991--- a/src/yvalve/preparse.cpp 992+++ b/src/yvalve/preparse.cpp 993@@ -25,7 +25,6 @@ 994 #include "firebird.h" 995 #include <stdlib.h> 996 #include <string.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 1003@@ -67,6 +67,7 @@ 1004 #include "../common/classes/RefMutex.h" 1005 #include "../common/classes/array.h" 1006 #include "../common/StatusHolder.h" 1007+#include "../common/ThreadStart.h" 1008 1009 static int process_id; 1010 1011-- 10122.9.3 1013 1014