From 40f782ae3e918c4f3842571ff8064be1c4f54961 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 13 Jan 2017 14:29:54 +0300 Subject: [PATCH] Backported fix for CORE-5452: Segfault when engine's dynamic library is unloaded right after closing worker threads (GC and/or cache writer) --- src/alice/alice_meta.epp | 1 - src/burp/burp.h | 2 - src/common/ThreadStart.h | 86 ++++++++++++++++++++++++++++ src/common/classes/Synchronize.h | 5 +- src/common/classes/misc/class_perf.cpp | 1 - src/common/xdr.cpp | 2 - src/gpre/boot/gpre_meta_boot.cpp | 1 - src/gpre/std/gpre_meta.epp | 1 - src/include/fb_exception.h | 1 - src/include/firebird.h | 1 - src/isql/OptionsBase.cpp | 1 - src/isql/extract.epp | 1 - src/isql/isql.epp | 5 -- src/jrd/Attachment.h | 1 + src/jrd/Database.h | 6 +- src/jrd/Mapping.cpp | 26 +++++---- src/jrd/cch.cpp | 31 +++++----- src/jrd/cch.h | 14 ++++- src/jrd/event.cpp | 13 +++-- src/jrd/event_proto.h | 7 +-- src/jrd/intl.cpp | 1 - src/jrd/trace/TraceConfigStorage.h | 1 + src/jrd/vio.cpp | 23 ++++---- src/lock/lock.cpp | 29 ++++++---- src/lock/lock_proto.h | 8 +-- src/qli/command.cpp | 1 - src/qli/dtr.h | 1 - src/qli/lex.cpp | 4 -- src/qli/meta.epp | 1 - src/utilities/gsec/gsecswi.h | 1 - src/utilities/gstat/dba.epp | 1 + src/utilities/nbackup/nbkswi.h | 1 - src/utilities/ntrace/os/win32/FileObject.cpp | 1 - src/yvalve/gds.cpp | 1 + src/yvalve/preparse.cpp | 1 - 35 files changed, 182 insertions(+), 99 deletions(-) diff --git a/src/alice/alice_meta.epp b/src/alice/alice_meta.epp index d0f59bc..65dc37e 100644 --- a/src/alice/alice_meta.epp +++ b/src/alice/alice_meta.epp @@ -30,7 +30,6 @@ #include "firebird.h" #include #include "../jrd/ibase.h" -//#include "../jrd/license.h" #include "../alice/alice.h" #include "../alice/alice_meta.h" #include "../yvalve/gds_proto.h" diff --git a/src/burp/burp.h b/src/burp/burp.h index 293a91f..fe26335 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -769,8 +769,6 @@ struct burp_meta_obj // I need to review if we tolerate different lengths for different OS's here. const unsigned int MAX_FILE_NAME_SIZE = 256; -//#include "../jrd/svc.h" - #include "../burp/std_desc.h" #ifdef WIN_NT diff --git a/src/common/ThreadStart.h b/src/common/ThreadStart.h index 85e6a38..823c5c1 100644 --- a/src/common/ThreadStart.h +++ b/src/common/ThreadStart.h @@ -31,6 +31,7 @@ #define JRD_THREADSTART_H #include "../common/ThreadData.h" +#include "../common/classes/semaphore.h" #ifdef WIN_NT #include @@ -89,4 +90,89 @@ inline ThreadId getThreadId() return Thread::getId(); } + +#ifndef USE_POSIX_THREADS +#define USE_FINI_SEM +#endif + +template +class ThreadFinishSync +{ +public: + typedef void ThreadRoutine(TA); + + ThreadFinishSync(Firebird::MemoryPool& pool, ThreadRoutine* routine, int priority_arg) + : +#ifdef USE_FINI_SEM + fini(pool), +#else + threadHandle(0), +#endif + threadRoutine(routine), + threadPriority(priority_arg) + { } + + void run(TA arg) + { + threadArg = arg; + + Thread::start(internalRun, this, threadPriority +#ifndef USE_FINI_SEM + , &threadHandle +#endif + ); + } + + void waitForCompletion() + { +#ifdef USE_FINI_SEM + fini.enter(); +#else + Thread::waitForCompletion(threadHandle); + threadHandle = 0; +#endif + } + +private: +#ifdef USE_FINI_SEM + Firebird::Semaphore fini; +#else + Thread::Handle threadHandle; +#endif + + TA threadArg; + ThreadRoutine* threadRoutine; + int threadPriority; + bool starting; + + static THREAD_ENTRY_DECLARE internalRun(THREAD_ENTRY_PARAM arg) + { + ((ThreadFinishSync*)arg)->internalRun(); + return 0; + } + + void internalRun() + { + try + { + threadRoutine(threadArg); + } + catch (const Firebird::Exception& ex) + { + threadArg->exceptionHandler(ex, threadRoutine); + } + +#ifdef USE_FINI_SEM + try + { + fini.release(); + } + catch (const Firebird::Exception& ex) + { + threadArg->exceptionHandler(ex, threadRoutine); + } +#endif + } +}; + #endif // JRD_THREADSTART_H diff --git a/src/common/classes/Synchronize.h b/src/common/classes/Synchronize.h index 198de44..3788541 100644 --- a/src/common/classes/Synchronize.h +++ b/src/common/classes/Synchronize.h @@ -33,10 +33,7 @@ #define CLASSES_SYNCHRONIZE_H #include "../common/classes/SyncObject.h" - -#ifndef WIN_NT -#include "fb_pthread.h" -#endif +#include "../common/ThreadStart.h" namespace Firebird { diff --git a/src/common/classes/misc/class_perf.cpp b/src/common/classes/misc/class_perf.cpp index 97b7bb3..142bfde 100644 --- a/src/common/classes/misc/class_perf.cpp +++ b/src/common/classes/misc/class_perf.cpp @@ -28,7 +28,6 @@ #include "tree.h" #include "alloc.h" -//#include "../memory/memory_pool.h" #include #include #include diff --git a/src/common/xdr.cpp b/src/common/xdr.cpp index b9f9f4d..1dfff76 100644 --- a/src/common/xdr.cpp +++ b/src/common/xdr.cpp @@ -26,9 +26,7 @@ #include "firebird.h" #include -//#include "../remote/remote.h" #include "../common/xdr.h" -//#include "../remote/proto_proto.h" #include "../common/xdr_proto.h" #include "../yvalve/gds_proto.h" #include "../common/gdsassert.h" diff --git a/src/gpre/boot/gpre_meta_boot.cpp b/src/gpre/boot/gpre_meta_boot.cpp index 0fde018..1f302c6 100644 --- a/src/gpre/boot/gpre_meta_boot.cpp +++ b/src/gpre/boot/gpre_meta_boot.cpp @@ -32,7 +32,6 @@ #include #include "../jrd/ibase.h" #include "../gpre/gpre.h" -//#include "../jrd/license.h" #include "../jrd/intl.h" #include "../gpre/gpre_proto.h" #include "../gpre/hsh_proto.h" diff --git a/src/gpre/std/gpre_meta.epp b/src/gpre/std/gpre_meta.epp index 34ff932..0780dd4 100644 --- a/src/gpre/std/gpre_meta.epp +++ b/src/gpre/std/gpre_meta.epp @@ -32,7 +32,6 @@ #include #include "../jrd/ibase.h" #include "../gpre/gpre.h" -//#include "../jrd/license.h" #include "../jrd/intl.h" #include "../gpre/gpre_proto.h" #include "../gpre/hsh_proto.h" diff --git a/src/include/fb_exception.h b/src/include/fb_exception.h index 030cf94..c4c1df4 100644 --- a/src/include/fb_exception.h +++ b/src/include/fb_exception.h @@ -43,7 +43,6 @@ #include "fb_types.h" #include "firebird/Interface.h" -#include "../common/ThreadStart.h" namespace Firebird { diff --git a/src/include/firebird.h b/src/include/firebird.h index 3d74354..87f0a11 100644 --- a/src/include/firebird.h +++ b/src/include/firebird.h @@ -68,7 +68,6 @@ #ifdef __cplusplus #include "../common/common.h" -//#include "fb_exception.h" #endif #ifndef NULL diff --git a/src/isql/OptionsBase.cpp b/src/isql/OptionsBase.cpp index 5a78540..0974fa3 100644 --- a/src/isql/OptionsBase.cpp +++ b/src/isql/OptionsBase.cpp @@ -24,7 +24,6 @@ #include "firebird.h" #include "OptionsBase.h" -//#include "../common/utils_proto.h" // strnicmp #include "../common/gdsassert.h" diff --git a/src/isql/extract.epp b/src/isql/extract.epp index ec2ddb1..99e821c 100644 --- a/src/isql/extract.epp +++ b/src/isql/extract.epp @@ -59,7 +59,6 @@ #include "../jrd/ods.h" #include "../common/utils_proto.h" #include "../jrd/constants.h" -//#include "../common/classes/ImplementHelper.h" using MsgFormat::SafeArg; diff --git a/src/isql/isql.epp b/src/isql/isql.epp index ccadce2..98b37bb 100644 --- a/src/isql/isql.epp +++ b/src/isql/isql.epp @@ -46,7 +46,6 @@ #include "firebird.h" #include #include "../yvalve/keywords.h" -//#include "../yvalve/gds_proto.h" #include "../jrd/intl.h" #include #include @@ -79,10 +78,6 @@ #include #endif -//#ifdef HAVE_IO_H -//#include // mktemp -//#endif - #ifdef HAVE_EDITLINE_H // This is a local file included in our distribution - but not always // compiled into the system diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index 2807db3..e71610e 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -39,6 +39,7 @@ #include "../common/classes/array.h" #include "../common/classes/stack.h" #include "../common/classes/timestamp.h" +#include "../common/ThreadStart.h" #include "../jrd/EngineInterface.h" diff --git a/src/jrd/Database.h b/src/jrd/Database.h index 0eab40d..f0f44d3 100644 --- a/src/jrd/Database.h +++ b/src/jrd/Database.h @@ -440,7 +440,7 @@ public: GarbageCollector* dbb_garbage_collector; // GarbageCollector class Firebird::Semaphore dbb_gc_sem; // Event to wake up garbage collector Firebird::Semaphore dbb_gc_init; // Event for initialization garbage collector - Firebird::Semaphore dbb_gc_fini; // Event for finalization garbage collector + ThreadFinishSync dbb_gc_fini; // Sync for finalization garbage collector Firebird::MemoryStats dbb_memory_stats; RuntimeStatistics dbb_stats; @@ -511,6 +511,7 @@ private: dbb_owner(*p), dbb_pools(*p, 4), dbb_sort_buffers(*p), + dbb_gc_fini(*p, garbage_collector, THREAD_medium), dbb_stats(*p), dbb_lock_owner_id(getLockOwnerId()), dbb_tip_cache(NULL), @@ -560,6 +561,9 @@ public: // reset sweep flags and release sweep lock void clearSweepFlags(thread_db* tdbb); + static void garbage_collector(Database* dbb); + void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync::ThreadRoutine* routine); + private: //static int blockingAstSharedCounter(void*); static int blocking_ast_sweep(void* ast_object); diff --git a/src/jrd/Mapping.cpp b/src/jrd/Mapping.cpp index c1bcf0e..8df7e2f 100644 --- a/src/jrd/Mapping.cpp +++ b/src/jrd/Mapping.cpp @@ -581,7 +581,8 @@ class MappingIpc FB_FINAL : public Firebird::IpcObject public: explicit MappingIpc(MemoryPool&) - : processId(getpid()) + : processId(getpid()), + cleanupSync(*getDefaultMemoryPool(), clearDelivery, THREAD_high) { } ~MappingIpc() @@ -602,7 +603,7 @@ public: sMem->process[process].flags &= ~MappingHeader::FLAG_ACTIVE; (void) // Ignore errors in cleanup sharedMemory->eventPost(&sMem->process[process].notifyEvent); - cleanupSemaphore.tryEnter(5); + cleanupSync.waitForCompletion(); // Ignore errors in cleanup sharedMemory->eventFini(&sMem->process[process].notifyEvent); @@ -755,7 +756,7 @@ public: try { - Thread::start(clearDelivery, this, THREAD_high); + cleanupSync.run(this); } catch (const Exception&) { @@ -764,6 +765,12 @@ public: } } + void exceptionHandler(const Exception& ex, ThreadFinishSync::ThreadRoutine*) + { + iscLogException("Fatal error in clearDeliveryThread", ex); + fb_utils::logAndDie("Fatal error in clearDeliveryThread"); + } + private: void clearDeliveryThread() { @@ -801,13 +808,10 @@ private: } if (startup) startupSemaphore.release(); - - cleanupSemaphore.release(); } catch (const Exception& ex) { - iscLogException("Fatal error in clearDeliveryThread", ex); - fb_utils::logAndDie("Fatal error in clearDeliveryThread"); + exceptionHandler(ex, NULL); } } @@ -862,11 +866,9 @@ private: MappingIpc* const data; }; - static THREAD_ENTRY_DECLARE clearDelivery(THREAD_ENTRY_PARAM par) + static void clearDelivery(MappingIpc* mapping) { - MappingIpc* m = (MappingIpc*)par; - m->clearDeliveryThread(); - return 0; + mapping->clearDeliveryThread(); } AutoPtr > sharedMemory; @@ -874,7 +876,7 @@ private: const SLONG processId; unsigned process; Semaphore startupSemaphore; - Semaphore cleanupSemaphore; + ThreadFinishSync cleanupSync; }; GlobalPtr mappingIpc; diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp index e1d403b..1bf714f 100644 --- a/src/jrd/cch.cpp +++ b/src/jrd/cch.cpp @@ -120,14 +120,11 @@ static BufferDesc* alloc_bdb(thread_db*, BufferControl*, UCHAR **); static Lock* alloc_page_lock(Jrd::thread_db*, BufferDesc*); static int blocking_ast_bdb(void*); #ifdef CACHE_READER -static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM); - static void prefetch_epilogue(Prefetch*, FbStatusVector *); static void prefetch_init(Prefetch*, thread_db*); static void prefetch_io(Prefetch*, FbStatusVector *); static void prefetch_prologue(Prefetch*, SLONG *); #endif -static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM); static void check_precedence(thread_db*, WIN*, PageNumber); static void clear_precedence(thread_db*, BufferDesc*); static BufferDesc* dealloc_bdb(BufferDesc*); @@ -1438,7 +1435,7 @@ void CCH_init2(thread_db* tdbb) try { - Thread::start(cache_writer, dbb, THREAD_medium); + bcb->bcb_writer_fini.run(bcb); } catch (const Exception&) { @@ -2017,7 +2014,7 @@ void CCH_shutdown(thread_db* tdbb) { bcb->bcb_flags &= ~BCB_cache_writer; bcb->bcb_writer_sem.release(); // Wake up running thread - bcb->bcb_writer_fini.enter(); + bcb->bcb_writer_fini.waitForCompletion(); } SyncLockGuard bcbSync(&bcb->bcb_syncObject, SYNC_EXCLUSIVE, "CCH_shutdown"); @@ -2692,7 +2689,7 @@ static void flushAll(thread_db* tdbb, USHORT flush_flag) #ifdef CACHE_READER -static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg) +void BufferControl::cache_reader(BufferControl* bcb) { /************************************** * @@ -2706,7 +2703,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg) * busy at a time. * **************************************/ - Database* dbb = (Database*) arg; + Database* dbb = bcb->bcb_database; Database::SyncGuard dsGuard(dbb); FbLocalStatus status_vector; @@ -2846,7 +2843,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg) #endif -static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg) +void BufferControl::cache_writer(BufferControl* bcb) { /************************************** * @@ -2859,8 +2856,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg) * **************************************/ FbLocalStatus status_vector; - Database* const dbb = (Database*) arg; - BufferControl* const bcb = dbb->dbb_bcb; + Database* const dbb = bcb->bcb_database; try { @@ -2964,8 +2960,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg) } // try catch (const Firebird::Exception& ex) { - ex.stuffException(&status_vector); - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); + bcb->exceptionHandler(ex, cache_writer); } bcb->bcb_flags &= ~BCB_cache_writer; @@ -2977,15 +2972,19 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg) bcb->bcb_flags &= ~BCB_writer_start; bcb->bcb_writer_init.release(); } - bcb->bcb_writer_fini.release(); } catch (const Firebird::Exception& ex) { - ex.stuffException(&status_vector); - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); + bcb->exceptionHandler(ex, cache_writer); } +} - return 0; + +void BufferControl::exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* /*routine*/) +{ + FbLocalStatus status_vector; + ex.stuffException(&status_vector); + iscDbLogStatus(bcb_database->dbb_filename.c_str(), &status_vector); } diff --git a/src/jrd/cch.h b/src/jrd/cch.h index b920566..b7f8486 100644 --- a/src/jrd/cch.h +++ b/src/jrd/cch.h @@ -29,6 +29,7 @@ #include "../common/classes/RefCounted.h" #include "../common/classes/semaphore.h" #include "../common/classes/SyncObject.h" +#include "../common/ThreadStart.h" #ifdef SUPERSERVER_V2 #include "../jrd/sbm.h" #include "../jrd/pag.h" @@ -85,7 +86,8 @@ class BufferControl : public pool_alloc BufferControl(MemoryPool& p, Firebird::MemoryStats& parentStats) : bcb_bufferpool(&p), bcb_memory_stats(&parentStats), - bcb_memory(p) + bcb_memory(p), + bcb_writer_fini(p, cache_writer, THREAD_medium) { bcb_database = NULL; QUE_INIT(bcb_in_use); @@ -144,18 +146,24 @@ public: Firebird::SyncObject bcb_syncLRU; //Firebird::SyncObject bcb_syncPageWrite; + typedef ThreadFinishSync BcbSync; + + static void cache_writer(BufferControl* bcb); Firebird::Semaphore bcb_writer_sem; // Wake up cache writer Firebird::Semaphore bcb_writer_init; // Cache writer initialization - Firebird::Semaphore bcb_writer_fini; // Cache writer finalization + BcbSync bcb_writer_fini; // Cache writer finalization #ifdef SUPERSERVER_V2 + static void cache_reader(BufferControl* bcb); // the code in cch.cpp is not tested for semaphore instead event !!! Firebird::Semaphore bcb_reader_sem; // Wake up cache reader Firebird::Semaphore bcb_reader_init; // Cache reader initialization - Firebird::Semaphore bcb_reader_fini; // Cache reader finalization + BcbSync bcb_reader_fini; // Cache reader finalization PageBitmap* bcb_prefetch; // Bitmap of pages to prefetch #endif + void exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* routine); + bcb_repeat* bcb_rpt; }; diff --git a/src/jrd/event.cpp b/src/jrd/event.cpp index 3a6bf28..cb6dc33 100644 --- a/src/jrd/event.cpp +++ b/src/jrd/event.cpp @@ -126,6 +126,7 @@ EventManager::EventManager(const Firebird::string& id, Firebird::RefPtr m_processOffset(0), m_dbId(getPool(), id), m_config(conf), + m_cleanupSync(getPool(), watcher_thread, THREAD_medium), m_sharedFileCreated(false), m_exiting(false) { @@ -146,7 +147,7 @@ EventManager::~EventManager() // Terminate the event watcher thread m_startupSemaphore.tryEnter(5); (void) m_sharedMemory->eventPost(&m_process->prb_event); - m_cleanupSemaphore.tryEnter(5); + m_cleanupSync.waitForCompletion(); #ifdef HAVE_OBJECT_MAP m_sharedMemory->unmapObject(&localStatus, &m_process); @@ -697,7 +698,7 @@ void EventManager::create_process() release_shmem(); - Thread::start(watcher_thread, this, THREAD_medium); + m_cleanupSync.run(this); } @@ -1414,12 +1415,16 @@ void EventManager::watcher_thread() { m_startupSemaphore.release(); } - m_cleanupSemaphore.release(); } catch (const Firebird::Exception& ex) { - iscLogException("Error closing event watcher thread\n", ex); + exceptionHandler(ex, NULL); } } +void EventManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync::ThreadRoutine*) +{ + iscLogException("Error closing event watcher thread\n", ex); +} + } // namespace diff --git a/src/jrd/event_proto.h b/src/jrd/event_proto.h index 3301203..9bfd20e 100644 --- a/src/jrd/event_proto.h +++ b/src/jrd/event_proto.h @@ -63,6 +63,7 @@ public: bool initialize(Firebird::SharedMemoryBase*, bool); void mutexBug(int osErrorCode, const char* text); + void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync::ThreadRoutine* routine); private: void acquire_shmem(); @@ -91,11 +92,9 @@ private: void detach_shared_file(); void get_shared_file_name(Firebird::PathName&) const; - static THREAD_ENTRY_DECLARE watcher_thread(THREAD_ENTRY_PARAM arg) + static void watcher_thread(EventManager* eventMgr) { - EventManager* const eventMgr = static_cast(arg); eventMgr->watcher_thread(); - return 0; } static void mutex_bugcheck(const TEXT*, int); @@ -109,7 +108,7 @@ private: Firebird::AutoPtr > m_sharedMemory; Firebird::Semaphore m_startupSemaphore; - Firebird::Semaphore m_cleanupSemaphore; + ThreadFinishSync m_cleanupSync; bool m_sharedFileCreated; bool m_exiting; diff --git a/src/jrd/intl.cpp b/src/jrd/intl.cpp index 6666c5f..b0e662b 100644 --- a/src/jrd/intl.cpp +++ b/src/jrd/intl.cpp @@ -104,7 +104,6 @@ #include "../intl/charsets.h" #include "../intl/country_codes.h" #include "../common/gdsassert.h" -//#include "../jrd/license.h" #ifdef INTL_BUILTIN #include "../intl/ld_proto.h" #endif diff --git a/src/jrd/trace/TraceConfigStorage.h b/src/jrd/trace/TraceConfigStorage.h index ca973c0..3d08143 100644 --- a/src/jrd/trace/TraceConfigStorage.h +++ b/src/jrd/trace/TraceConfigStorage.h @@ -32,6 +32,7 @@ #include "../../common/classes/fb_string.h" #include "../../common/classes/init.h" #include "../../common/isc_s_proto.h" +#include "../../common/ThreadStart.h" #include "../../jrd/trace/TraceSession.h" #include "../../common/classes/RefCounted.h" diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 02c5809..8ca9f66 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -107,7 +107,6 @@ static bool dfw_should_know(record_param* org_rpb, record_param* new_rpb, USHORT irrelevant_field, bool void_update_is_relevant = false); static void garbage_collect(thread_db*, record_param*, ULONG, RecordStack&); static void garbage_collect_idx(thread_db*, record_param*, Record*, Record*); -static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM); #ifdef VIO_DEBUG @@ -1958,7 +1957,7 @@ void VIO_fini(thread_db* tdbb) { dbb->dbb_flags &= ~DBB_garbage_collector; dbb->dbb_gc_sem.release(); // Wake up running thread - dbb->dbb_gc_fini.enter(); + dbb->dbb_gc_fini.waitForCompletion(); } } @@ -2420,7 +2419,7 @@ void VIO_init(thread_db* tdbb) { try { - Thread::start(garbage_collector, dbb, THREAD_medium); + dbb->dbb_gc_fini.run(dbb); } catch (const Exception&) { @@ -4741,7 +4740,7 @@ static void garbage_collect_idx(thread_db* tdbb, } -static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg) +void Database::garbage_collector(Database* dbb) { /************************************** * @@ -4758,7 +4757,6 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg) * **************************************/ FbLocalStatus status_vector; - Database* const dbb = (Database*) arg; try { @@ -4989,8 +4987,7 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg) } // try catch (const Firebird::Exception& ex) { - ex.stuffException(&status_vector); - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); + dbb->exceptionHandler(ex, NULL); } dbb->dbb_flags &= ~(DBB_garbage_collector | DBB_gc_active | DBB_gc_pending); @@ -5003,15 +5000,19 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg) dbb->dbb_flags &= ~DBB_gc_starting; dbb->dbb_gc_init.release(); } - dbb->dbb_gc_fini.release(); } catch (const Firebird::Exception& ex) { - ex.stuffException(&status_vector); - iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector); + dbb->exceptionHandler(ex, NULL); } +} + - return 0; +void Database::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync::ThreadRoutine* /*routine*/) +{ + FbLocalStatus status_vector; + ex.stuffException(&status_vector); + iscDbLogStatus(dbb_filename.c_str(), &status_vector); } diff --git a/src/lock/lock.cpp b/src/lock/lock.cpp index 89eb4c5..2ab3358 100644 --- a/src/lock/lock.cpp +++ b/src/lock/lock.cpp @@ -214,6 +214,7 @@ LockManager::LockManager(const Firebird::string& id, RefPtr conf) m_sharedFileCreated(false), m_process(NULL), m_processOffset(0), + m_cleanupSync(getPool(), blocking_action_thread, THREAD_high), m_sharedMemory(NULL), m_blockage(false), m_dbId(getPool(), id), @@ -259,7 +260,7 @@ LockManager::~LockManager() m_sharedMemory->eventPost(&m_process->prc_blocking); // Wait for the AST thread to finish cleanup or for 5 seconds - m_cleanupSemaphore.tryEnter(5); + m_cleanupSync.waitForCompletion(); } #ifdef HAVE_OBJECT_MAP @@ -1548,16 +1549,22 @@ void LockManager::blocking_action_thread() { iscLogException("Error in blocking action thread\n", x); } +} - try - { - // Wakeup the main thread waiting for our exit - m_cleanupSemaphore.release(); - } - catch (const Firebird::Exception& x) - { - iscLogException("Error closing blocking action thread\n", x); - } + +void LockManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync::ThreadRoutine* /*routine*/) +{ +/************************************** + * + * e x c e p t i o n H a n d l e r + * + ************************************** + * + * Functional description + * Handler for blocking thread close bugs. + * + **************************************/ + iscLogException("Error closing blocking action thread\n", ex); } @@ -1815,7 +1822,7 @@ bool LockManager::create_process(CheckStatusWrapper* statusVector) { try { - Thread::start(blocking_action_thread, this, THREAD_high); + m_cleanupSync.run(this); } catch (const Exception& ex) { diff --git a/src/lock/lock_proto.h b/src/lock/lock_proto.h index d991c1e..2faec49 100644 --- a/src/lock/lock_proto.h +++ b/src/lock/lock_proto.h @@ -418,6 +418,8 @@ public: SINT64 readData2(USHORT, const UCHAR*, USHORT, SRQ_PTR); SINT64 writeData(SRQ_PTR, SINT64); + void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync::ThreadRoutine* routine); + private: explicit LockManager(const Firebird::string&, Firebird::RefPtr); ~LockManager(); @@ -471,11 +473,9 @@ private: void detach_shared_file(Firebird::CheckStatusWrapper*); void get_shared_file_name(Firebird::PathName&, ULONG extend = 0) const; - static THREAD_ENTRY_DECLARE blocking_action_thread(THREAD_ENTRY_PARAM arg) + static void blocking_action_thread(LockManager* lockMgr) { - LockManager* const lockMgr = static_cast(arg); lockMgr->blocking_action_thread(); - return 0; } bool initialize(Firebird::SharedMemoryBase* sm, bool init); @@ -490,7 +490,7 @@ private: Firebird::RWLock m_remapSync; Firebird::AtomicCounter m_waitingOwners; - Firebird::Semaphore m_cleanupSemaphore; + ThreadFinishSync m_cleanupSync; Firebird::Semaphore m_startupSemaphore; public: diff --git a/src/qli/command.cpp b/src/qli/command.cpp index 5f949f3..fbbf4fb 100644 --- a/src/qli/command.cpp +++ b/src/qli/command.cpp @@ -30,7 +30,6 @@ #include "../qli/parse.h" #include "../qli/compile.h" #include "../qli/exe.h" -//#include "../jrd/license.h" #include "../qli/all_proto.h" #include "../qli/err_proto.h" #include "../qli/exe_proto.h" diff --git a/src/qli/dtr.h b/src/qli/dtr.h index ba5cd64..e246ef4 100644 --- a/src/qli/dtr.h +++ b/src/qli/dtr.h @@ -480,7 +480,6 @@ struct qli_fun }; // Program wide globals -//#include #ifdef QLI_MAIN #define EXTERN diff --git a/src/qli/lex.cpp b/src/qli/lex.cpp index c20d1f9..9e26046 100644 --- a/src/qli/lex.cpp +++ b/src/qli/lex.cpp @@ -50,10 +50,6 @@ using MsgFormat::SafeArg; #include #endif -//#ifdef HAVE_CTYPES_H -//#include -//#endif - #ifdef HAVE_IO_H #include // isatty #endif diff --git a/src/qli/meta.epp b/src/qli/meta.epp index a7f222c..2d55716 100644 --- a/src/qli/meta.epp +++ b/src/qli/meta.epp @@ -28,7 +28,6 @@ #include "../qli/dtr.h" #include "../qli/compile.h" #include "../qli/exe.h" -//#include "../jrd/license.h" #include "../jrd/flags.h" #include "../jrd/ibase.h" #include "../qli/reqs.h" diff --git a/src/utilities/gsec/gsecswi.h b/src/utilities/gsec/gsecswi.h index b8519f5..9b560e3 100644 --- a/src/utilities/gsec/gsecswi.h +++ b/src/utilities/gsec/gsecswi.h @@ -24,7 +24,6 @@ #ifndef GSEC_GSECSWI_H #define GSEC_GSECSWI_H -//#include "../common/common.h" #include "../jrd/constants.h" /* Switch handling constants. Note that the first IN_SW_DATA_ITEMS diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp index 379b418..19b99d1 100644 --- a/src/utilities/gstat/dba.epp +++ b/src/utilities/gstat/dba.epp @@ -56,6 +56,7 @@ #include "../common/classes/UserBlob.h" #include "../common/os/os_utils.h" #include "../common/StatusHolder.h" +#include "../common/ThreadStart.h" using MsgFormat::SafeArg; diff --git a/src/utilities/nbackup/nbkswi.h b/src/utilities/nbackup/nbkswi.h index 4326c3d..b8d43da 100644 --- a/src/utilities/nbackup/nbkswi.h +++ b/src/utilities/nbackup/nbkswi.h @@ -27,7 +27,6 @@ #ifndef NBACKUP_NBKSWI_H #define NBACKUP_NBKSWI_H -//#include "../common/common.h" #include "../jrd/constants.h" // Switch handling constants diff --git a/src/utilities/ntrace/os/win32/FileObject.cpp b/src/utilities/ntrace/os/win32/FileObject.cpp index 73ed38f..53fbfc0 100644 --- a/src/utilities/ntrace/os/win32/FileObject.cpp +++ b/src/utilities/ntrace/os/win32/FileObject.cpp @@ -27,7 +27,6 @@ #include "firebird.h" #include "../FileObject.h" -//#include "../common/classes/locks.h" using namespace Firebird; Firebird::Mutex open_mutex; diff --git a/src/yvalve/gds.cpp b/src/yvalve/gds.cpp index c851f7c..998bbde 100644 --- a/src/yvalve/gds.cpp +++ b/src/yvalve/gds.cpp @@ -57,6 +57,7 @@ #include "../common/classes/init.h" #include "../common/classes/TempFile.h" #include "../common/utils_proto.h" +#include "../common/ThreadStart.h" #ifdef HAVE_UNISTD_H #include diff --git a/src/yvalve/preparse.cpp b/src/yvalve/preparse.cpp index b2335a5..e742784 100644 --- a/src/yvalve/preparse.cpp +++ b/src/yvalve/preparse.cpp @@ -25,7 +25,6 @@ #include "firebird.h" #include #include -//#include "../dsql/chars.h" #include "../yvalve/prepa_proto.h" #include "../yvalve/gds_proto.h" #include "../yvalve/YObjects.h" --- a/src/common/isc_sync.cpp +++ b/src/common/isc_sync.cpp @@ -67,6 +67,7 @@ #include "../common/classes/RefMutex.h" #include "../common/classes/array.h" #include "../common/StatusHolder.h" +#include "../common/ThreadStart.h" static int process_id; -- 2.9.3