From: Vlad K. <hv...@us...> - 2011-01-27 08:49:12
|
>> 3 clients, each with 99 threads and each client thread sending a query to >> server. > > So we could expect that there are no more than 300 simultaneous queries > running, and total number of server threads should be a tiny bit more. At least this is how it should work. > So far it looks like the server cannot reuse the inactive thread found > in the pool and thus keep creating new ones. Looking at Worker::wait() > it seems that if it won't be woken up during the timeout (1 min), then > the thread pool may get totally blocked, as both waiting and signaling > are protected by the same mutex. I hope Vlad would comment on it. Sorry, i failed to see how you made such conclusion. bool Worker::wait(int timeout) { // here we don't hold any global locks // wait 60 sec for request to work on it if (m_sem.tryEnter(timeout)) // here this thread will be reused return true; // wait timed out, remove thread from idle list and destroy it // acquire common mutex to modify common idle list Firebird::MutexLockGuard guard(m_mutex); // last quick check if we was awaken if (m_sem.tryEnter(0)) return true; // remove thread from idle list remove(); // destroy it return false; } bool Worker::wakeUp() { // acquire common mutex to check idle list Firebird::MutexLockGuard guard(m_mutex); if (m_idleWorkers) { // wake up idle thread Worker* idle = m_idleWorkers; idle->setState(true); idle->m_sem.release(); return true; } // no idle threads, create one more if allowed return (m_cntAll >= MAX_THREADS); } You see - waiting is not protected by the common m_mutex and deadlock is not possible. Regards, Vlad PS I can't help without reproducible example |