cpp-redis/cpp_redis

cpp_redis on windows-x86_64, WSACleanup function call causes abort()

oaleshina opened this issue · 2 comments

WSACleanup function call raises abort() due to mutex destruction while it's locked.

Steps to reproduce:
Call WSACleanup() to terminate working with ws2_32.dll

I use VS 2017 ver 15.9.17
Code snippet what i am trying to do:

WORD version = MAKEWORD(2, 2);
WSADATA data;

if (WSAStartup(version, &data) != 0) {
    std::cerr << "WSAStartup() failure" << std::endl;
    return -1;
}
cpp_redis::client client;

client.connect(host, port, [](const std::string& host, std::size_t port, cpp_redis::client::connect_state status) {
    if (status == cpp_redis::client::connect_state::dropped) {
        std::cout << "client disconnected from " << host << ":" << port << std::endl;
    }
});

// .... some code here ....

client.sync_commit();
client.disconnect(true);

WSACleanup();

Output:
f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c(51): mutex destroyed while busy

 issue_debug_notification(const wchar_t * const message) Line 28	C++
__acrt_report_runtime_error(const wchar_t * message) Line 154	C++
abort() Line 61	C++
[External Code]	
tacopie::io_service::~io_service() Line 85	C++
[External Code]	
_execute_onexit_table::__l2::<lambda>() Line 206	C++
__crt_seh_guarded_call<int>::operator()<void <lambda>(void),int <lambda>(void) & __ptr64,void <lambda>(void) >(__acrt_lock_and_call::__l2::void <lambda>(void) && setup, _execute_onexit_table::__l2::int <lambda>(void) & action, __acrt_lock_and_call::__l2::void <lambda>(void) && cleanup) Line 204	C++
__acrt_lock_and_call<int <lambda>(void) >(const __acrt_lock_id lock_id, _execute_onexit_table::__l2::int <lambda>(void) && action) Line 940	C++
_execute_onexit_table(_onexit_table_t * table) Line 231	C++

Removing the WSACleanup() call helps to avoid the crash, but it causes memory leaks.
Several questions:

  1. Is it known about this issue and how to eliminate it ?
  2. Why after disconnect(true) call the WSACleanup() causes abort() ? Does tacopie::io_service finish client's socket connections after disconnect(true) call ?

Expected behavior:
Release resources and finish program execution without any abort() calls

Desktop:

  • OS: windows 10 19h1_release

After cli->disconnect(true) call, listening socket is still alive ( that is created through self_pipe ). WSACleanup does force close of this socket, this can lead to a problem.

I resolved it by using tacopie::set_default_io_service({}); before WSACleanup() call. It helps to decrease ref count of the shared_ptr<io_service> to finally release all resources. It is workaround of course and should be fixed in tacopie