mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 02:03:04 +01:00
Fixed CORE-5824: Segmentation fault during install on Linux
This commit is contained in:
parent
672a130e1a
commit
332334ab3d
@ -136,6 +136,61 @@ namespace {
|
|||||||
GlobalPtr<AllServices> allServices; // protected by globalServicesMutex
|
GlobalPtr<AllServices> allServices; // protected by globalServicesMutex
|
||||||
volatile bool svcShutdown = false;
|
volatile bool svcShutdown = false;
|
||||||
|
|
||||||
|
class ThreadCollect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThreadCollect(MemoryPool& p)
|
||||||
|
: threads(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void join()
|
||||||
|
{
|
||||||
|
// join threads to be sure they are gone when shutdown is complete
|
||||||
|
// no need locking something cause this is expected to run when services are closing
|
||||||
|
waitFor(threads);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(Thread::Handle& h)
|
||||||
|
{
|
||||||
|
// put thread into completion wait queue when it finished running
|
||||||
|
MutexLockGuard g(threadsMutex, FB_FUNCTION);
|
||||||
|
threads.add(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void houseKeeping()
|
||||||
|
{
|
||||||
|
if (!threads.hasData())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// join finished threads
|
||||||
|
AllThreads t;
|
||||||
|
{ // mutex scope
|
||||||
|
MutexLockGuard g(threadsMutex, FB_FUNCTION);
|
||||||
|
t.assign(threads);
|
||||||
|
threads.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
waitFor(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef Array<Thread::Handle> AllThreads;
|
||||||
|
|
||||||
|
static void waitFor(AllThreads& thr)
|
||||||
|
{
|
||||||
|
while (thr.hasData())
|
||||||
|
{
|
||||||
|
Thread::Handle h(thr.pop());
|
||||||
|
Thread::waitForCompletion(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AllThreads threads;
|
||||||
|
Mutex threadsMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
GlobalPtr<ThreadCollect> threadCollect;
|
||||||
|
|
||||||
void spbVersionError()
|
void spbVersionError()
|
||||||
{
|
{
|
||||||
ERR_post(Arg::Gds(isc_bad_spb_form) <<
|
ERR_post(Arg::Gds(isc_bad_spb_form) <<
|
||||||
@ -655,7 +710,7 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
|||||||
svc_remote_pid(0), svc_trace_manager(NULL), svc_crypt_callback(crypt_callback),
|
svc_remote_pid(0), svc_trace_manager(NULL), svc_crypt_callback(crypt_callback),
|
||||||
svc_existence(FB_NEW_POOL(*getDefaultMemoryPool()) SvcMutex(this)),
|
svc_existence(FB_NEW_POOL(*getDefaultMemoryPool()) SvcMutex(this)),
|
||||||
svc_stdin_size_requested(0), svc_stdin_buffer(NULL), svc_stdin_size_preload(0),
|
svc_stdin_size_requested(0), svc_stdin_buffer(NULL), svc_stdin_size_preload(0),
|
||||||
svc_stdin_preload_requested(0), svc_stdin_user_size(0)
|
svc_stdin_preload_requested(0), svc_stdin_user_size(0), svc_thread(0)
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
, svc_debug(false)
|
, svc_debug(false)
|
||||||
#endif
|
#endif
|
||||||
@ -995,6 +1050,8 @@ void Service::shutdownServices()
|
|||||||
|
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
threadCollect->join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1919,6 +1976,7 @@ THREAD_ENTRY_DECLARE Service::run(THREAD_ENTRY_PARAM arg)
|
|||||||
RefPtr<SvcMutex> ref(svc->svc_existence);
|
RefPtr<SvcMutex> ref(svc->svc_existence);
|
||||||
exit_code = svc->svc_service_run->serv_thd(svc);
|
exit_code = svc->svc_service_run->serv_thd(svc);
|
||||||
|
|
||||||
|
threadCollect->add(svc->svc_thread);
|
||||||
svc->started();
|
svc->started();
|
||||||
svc->svc_sem_full.release();
|
svc->svc_sem_full.release();
|
||||||
svc->finish(SVC_finished);
|
svc->finish(SVC_finished);
|
||||||
@ -2081,7 +2139,10 @@ void Service::start(USHORT spb_length, const UCHAR* spb_data)
|
|||||||
|
|
||||||
svc_stdout_head = svc_stdout_tail = 0;
|
svc_stdout_head = svc_stdout_tail = 0;
|
||||||
|
|
||||||
Thread::start(run, this, THREAD_medium);
|
Thread::start(run, this, THREAD_medium, &svc_thread);
|
||||||
|
|
||||||
|
// good time for housekeeping while new thread starts
|
||||||
|
threadCollect->houseKeeping();
|
||||||
|
|
||||||
// Check for the service being detached. This will prevent the thread
|
// Check for the service being detached. This will prevent the thread
|
||||||
// from waiting infinitely if the client goes away.
|
// from waiting infinitely if the client goes away.
|
||||||
|
@ -391,6 +391,8 @@ private:
|
|||||||
// Size of data, placed into svc_stdin_buffer (set in put)
|
// Size of data, placed into svc_stdin_buffer (set in put)
|
||||||
ULONG svc_stdin_user_size;
|
ULONG svc_stdin_user_size;
|
||||||
static const ULONG PRELOAD_BUFFER_SIZE = SVC_IO_BUFFER_SIZE;
|
static const ULONG PRELOAD_BUFFER_SIZE = SVC_IO_BUFFER_SIZE;
|
||||||
|
// Handle of a thread to wait for when closing
|
||||||
|
Thread::Handle svc_thread;
|
||||||
|
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
bool svc_debug;
|
bool svc_debug;
|
||||||
|
Loading…
Reference in New Issue
Block a user