Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

ThreadPool::~ThreadPool() Windows Deadlock Posible Solution #408

Copy link
Copy link
Open
@sldr

Description

@sldr
Issue body actions

The ThreadPool destructor will still deadlock when
log4cplus::Initializer initializer;
is at top of main if main starts a thread and in that thread exit(2); is called.

The following will fix the issue and doesn't require log4cplus::Initializer initializer; in main.

  • version: 2.0.4
  • operating system, CPU, bitness: Windows 10 Enterprise 1809 17763.437, Intel Xeon E5-2670 0 @ 2.60GHz (2 processors), x64
  • configure script, or CMake, etc., flags and settings: VS 2017 15.9.11 built using:
    msbuild /nologo /m /nr:false /p:"Platform=x64" /p:Configuration=Release /t:log4cplus ".\log4cplus\msvc14\log4cplus.sln"
    Note: updated projects to 8.1 and 141 using VS 2017 GUI first

What is happening is that the threadpool threads are not going thru normal run down during exit(…) call so the workers vector isn't empty when the condition_consumers condition is signaled so the predicate check fails. I modified the predicate check to go thru the workers and check if they still exist. If none exist I have to detach() the threads otherwise thread destructor throws when it tries to join a thread. Hope this helps!

SLDR
(Stephen L. De Rudder)

Here is the new ThreadPool destructor:

inline ThreadPool::~ThreadPool()
{
    std::unique_lock<std::mutex> lock(queue_mutex);
    stop = true;
    condition_consumers.notify_all();
    condition_producers.notify_all();
    pool_size = 0;
    condition_consumers.wait(lock,
      [this]
    {
      //return this->workers.empty();
      if (this->workers.empty()) {
        return true;
      } else {
#if defined (_WIN32)
        for (std::vector< std::thread >::reverse_iterator i = this->workers.rbegin(); i < this->workers.rend(); ++i) {
          HANDLE hThread = i->native_handle();
          if (WaitForSingleObject(hThread, 0) != WAIT_OBJECT_0) {
            return false;
          }
        }
        for (std::vector< std::thread >::reverse_iterator i = this->workers.rbegin(); i < this->workers.rend(); ++i) {
          i->detach();
        }
        return true;
#else
        return false;
#endif
      }
    });
    assert(in_flight == 0);
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.