lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / external / firebird / 0002-Backported-fix-for-CORE-5452-Segfault-when-engine-s-.patch.1
blobc55df4d0ae7139e48bae31335e282838253cf539
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
6  writer)
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(-)
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
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"
58 diff --git a/src/burp/burp.h b/src/burp/burp.h
59 index 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;
66 -//#include "../jrd/svc.h"
68  #include "../burp/std_desc.h"
70  #ifdef WIN_NT
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
75 @@ -31,6 +31,7 @@
76  #define JRD_THREADSTART_H
78  #include "../common/ThreadData.h"
79 +#include "../common/classes/semaphore.h"
81  #ifdef WIN_NT
82  #include <windows.h>
83 @@ -89,4 +90,89 @@ inline ThreadId getThreadId()
84         return Thread::getId();
85  }
88 +#ifndef USE_POSIX_THREADS
89 +#define USE_FINI_SEM
90 +#endif
92 +template <typename TA>
93 +class ThreadFinishSync
95 +public:
96 +       typedef void ThreadRoutine(TA);
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 +       { }
109 +       void run(TA arg)
110 +       {
111 +               threadArg = arg;
113 +               Thread::start(internalRun, this, threadPriority
114 +#ifndef USE_FINI_SEM
115 +                                       , &threadHandle
116 +#endif
117 +                       );
118 +       }
120 +       void waitForCompletion()
121 +       {
122 +#ifdef USE_FINI_SEM
123 +               fini.enter();
124 +#else
125 +               Thread::waitForCompletion(threadHandle);
126 +               threadHandle = 0;
127 +#endif
128 +       }
130 +private:
131 +#ifdef USE_FINI_SEM
132 +       Firebird::Semaphore fini;
133 +#else
134 +       Thread::Handle threadHandle;
135 +#endif
137 +       TA threadArg;
138 +       ThreadRoutine* threadRoutine;
139 +       int threadPriority;
140 +       bool starting;
142 +       static THREAD_ENTRY_DECLARE internalRun(THREAD_ENTRY_PARAM arg)
143 +       {
144 +               ((ThreadFinishSync*)arg)->internalRun();
145 +               return 0;
146 +       }
148 +       void internalRun()
149 +       {
150 +               try
151 +               {
152 +                       threadRoutine(threadArg);
153 +               }
154 +               catch (const Firebird::Exception& ex)
155 +               {
156 +                       threadArg->exceptionHandler(ex, threadRoutine);
157 +               }
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 +       }
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
177 @@ -33,10 +33,7 @@
178  #define CLASSES_SYNCHRONIZE_H
180  #include "../common/classes/SyncObject.h"
182 -#ifndef WIN_NT
183 -#include "fb_pthread.h"
184 -#endif
185 +#include "../common/ThreadStart.h"
188  namespace Firebird {
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
193 @@ -28,7 +28,6 @@
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>
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
205 @@ -26,9 +26,7 @@
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"
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
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"
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
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"
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
243 @@ -43,7 +43,6 @@
245  #include "fb_types.h"
246  #include "firebird/Interface.h"
247 -#include "../common/ThreadStart.h"
249  namespace Firebird
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
255 @@ -68,7 +68,6 @@
257  #ifdef __cplusplus
258  #include "../common/common.h"
259 -//#include "fb_exception.h"
260  #endif
262  #ifndef NULL
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
267 @@ -24,7 +24,6 @@
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
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"
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
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
303 -//#ifdef HAVE_IO_H
304 -//#include <io.h> // mktemp
305 -//#endif
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
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"
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:
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);
347 +       static void garbage_collector(Database* dbb);
348 +       void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<Database*>::ThreadRoutine* routine);
350  private:
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
359  public:
360         explicit MappingIpc(MemoryPool&)
361 -               : processId(getpid())
362 +               : processId(getpid()),
363 +                 cleanupSync(*getDefaultMemoryPool(), clearDelivery, THREAD_high)
364         { }
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();
374                 // Ignore errors in cleanup
375                 sharedMemory->eventFini(&sMem->process[process].notifyEvent);
376 @@ -755,7 +756,7 @@ public:
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         }
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 +       }
395  private:
396         void clearDeliveryThread()
397         {
398 @@ -801,13 +808,10 @@ private:
399                         }
400                         if (startup)
401                                 startupSemaphore.release();
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         }
413 @@ -862,11 +866,9 @@ private:
414                 MappingIpc* const data;
415         };
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         }
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  };
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*);
443  #ifdef CACHE_READER
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 *);
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)
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         }
472         SyncLockGuard bcbSync(&bcb->bcb_syncObject, SYNC_EXCLUSIVE, "CCH_shutdown");
473 @@ -2692,7 +2689,7 @@ static void flushAll(thread_db* tdbb, USHORT flush_flag)
476  #ifdef CACHE_READER
477 -static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
478 +void BufferControl::cache_reader(BufferControl* bcb)
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);
490         FbLocalStatus status_vector;
491 @@ -2846,7 +2843,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
492  #endif
495 -static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
496 +void BufferControl::cache_writer(BufferControl* bcb)
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;
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         }
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         }
534 -       return 0;
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
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;
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
586  #endif
588 +       void exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* routine);
590         bcb_repeat*     bcb_rpt;
591  };
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>
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)
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()
616         release_shmem();
618 -       Thread::start(watcher_thread, this, THREAD_medium);
619 +       m_cleanupSync.run(this);
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         }
636 +void EventManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine*)
638 +       iscLogException("Error closing event watcher thread\n", ex);
641  } // namespace
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);
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;
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         }
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;
675         bool m_exiting;
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
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
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
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"
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);
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         }
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,
734 -static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
735 +void Database::garbage_collector(Database* dbb)
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;
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         }
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         }
772 -       return 0;
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),
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);
796                         // Wait for the AST thread to finish cleanup or for 5 seconds
797 -                       m_cleanupSemaphore.tryEnter(5);
798 +                       m_cleanupSync.waitForCompletion();
799                 }
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         }
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 -       }
818 +void LockManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<LockManager*>::ThreadRoutine* /*routine*/)
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);
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                 {
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);
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;
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         }
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;
877  public:
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
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"
890 diff --git a/src/qli/dtr.h b/src/qli/dtr.h
891 index ba5cd64..e246ef4 100644
892 --- a/src/qli/dtr.h
893 +++ b/src/qli/dtr.h
894 @@ -480,7 +480,6 @@ struct qli_fun
895  };
897  // Program wide globals
898 -//#include <setjmp.h>
900  #ifdef QLI_MAIN
901  #define EXTERN
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;
907  #include <unistd.h>
908  #endif
910 -//#ifdef HAVE_CTYPES_H
911 -//#include <ctypes.h>
912 -//#endif
914  #ifdef HAVE_IO_H
915  #include <io.h> // isatty
916  #endif
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
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"
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
933 @@ -24,7 +24,6 @@
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
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"
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
957 @@ -27,7 +27,6 @@
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
969 @@ -27,7 +27,6 @@
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
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"
987  #ifdef HAVE_UNISTD_H
988  #include <unistd.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
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"
1009  static int process_id;
1011 -- 
1012 2.9.3