pthread_join навсегда зависает C ++ - PullRequest
0 голосов
/ 25 мая 2020

Я запускаю этот g_test, где я просто инициализирую и закрываю клиента.

TEST(safIpc, createAndCloseClient)
{
    std::shared_ptr<fnv::ipcsvc::IpcSvc> safIpc = std::make_shared<fnv::ipcsvc::IpcSvc>();
    const std::string& app1 {"/testApp1"};
    const std::string& groupName {"wir_clients"};
    fnv::ipcsvc::IpcSvcAttrMq attr(fnv::ipcsvc::IpcSvcAttrType::MQ_CLIENT,
                                   app1,
                                   groupName,
                                   "/server");
    std::shared_ptr<IpcSvcTestSafHandler> msgHandler = std::make_shared<IpcSvcTestSafHandler>();

    // initialize the ipc library
    IpcSvcPriv::SharedPtr ipcPrivData {nullptr};
    fnv::ipcsvc::IpcSvcRet ret = safIpc->init(attr, msgHandler, ipcPrivData);
    EXPECT_EQ(ret, fnv::ipcsvc::IpcSvcRet::SUCCESS);
    EXPECT_NE(ipcPrivData, nullptr);

    ret = safIpc->close(ipcPrivData, app1); //HANGS here
    EXPECT_EQ(fnv::ipcsvc::IpcSvcRet::SUCCESS, ret);
}

В init я создаю 3 потока: (вот соответствующая часть кода инициализации):

1- Поток процесса 2- Поток приема 3- Поток таймера

    int rc = pthread_create(&m_timerThread,
                            NULL,
                            &IpcSvcImpl::timer_start,
                            this);

    if (rc != 0)
    {
        ipcSvcLog(LOGE, "Failed to create timer thread!");
        close(tmpPrivData,
              attr.getAppId());
        return error;
    }
    pthread_setname_np(m_timerThread,
                       "IpcSvcTimerThread");
}

// Start the worker threads
int rc = pthread_create(&m_receiveThread,
                        NULL,
                        &IpcSvcImpl::receive,
                        this);
if (rc != 0)
{
    //TODO some error log
    close(tmpPrivData,
          attr.getAppId());
    return error;
}
pthread_setname_np(m_receiveThread,
                   "IpcSvcReceiveThread");

rc = pthread_create(&m_processThread,
                    NULL,
                    &IpcSvcImpl::process,
                    this);
if (rc != 0)
{
    //TODO some error log
    close(tmpPrivData,
          attr.getAppId());
    return error;
}
pthread_setname_np(m_processThread,
                   "IpcSvcProcessThread");

Вот функция закрытия:

IpcSvcRet IpcSvcImpl::close(IpcSvcPriv::SharedPtr privateData,
                            const std::string& appId)
{
    if (!privateData)
    {
        //TODO log about client not providing sane private data
        return IpcSvcRet::FAIL;
    }

    // acquire the mutex and set close called to true
    {
        std::lock_guard<std::mutex> guard(m_closeMtx);
        m_closed = true;
    }

    if (m_msgQueue)
    {
        m_msgQueue->mutexInit();

        // writing dummy message to process thread
        std::pair<std::array<uint8_t, IPCSVC_MAX_MSG_SIZE>, ssize_t> queueMsg;
        m_msgQueue->enqueue(queueMsg);
    }

    // writing dummy message to receive thread
    uint32_t buffer = 0;
    sendData(privateData,
             (void*)&buffer,
             sizeof(uint32_t),
             appId);

    pthread_join(m_receiveThread,
                 NULL);
    pthread_join(m_processThread,
                 NULL);

    if (m_isClient)
    {
        m_cv.notify_one();
        printf("timer thread hangs\n"); // HANGS HERE ///////////////////////////////////////
        pthread_join(m_timerThread,
                     NULL);
//This line is never reached..
    }

    delete m_msgQueue;
    m_msgQueue  = nullptr;

    // close the ipc layer
    if (m_ipc)
    {
        m_ipc->close();
        delete m_ipc;
        m_ipc = nullptr;
    }

    m_clientsList.clear();
    m_hbManager = { };

    return IpcSvcRet::SUCCESS;
}

Вот функция timer_start: Поток таймера таймер, который продолжает цикл бесконечно, если f c -> m_closed не установлено в true. Он запускает f c -> timerExpiry () каждые 2 секунды.

// timer thread entry
void* IpcSvcImpl::timer_start(void *arg)
{
    if (!arg)
    {
        return nullptr;
    }
    printf("starting timer\n");
    IpcSvcImpl* fc = static_cast<IpcSvcImpl *>(arg);
    std::unique_lock<std::mutex> lock(fc->m_closeMtx);
    while (!(fc->m_closed))
    {
        printf("Entering loop\n");

        lock.unlock();
        auto expireAt = std::chrono::steady_clock::now() +
                        std::chrono::seconds(fc->getTimerInterval());
        fc->timerExpiry();
        lock.lock();
        printf("here?\n");
        fc->m_cv.wait_until(lock, expireAt);
        printf("Here 2\n");

    }
    printf("Exited loop\n\n");


    return nullptr;
}

Результат unittest:

[----------] 5 tests from safIpc
[ RUN      ] safIpc.createAndCloseClient
starting timer
Entering loop
closing..
timer thread hangs

соединение pthread зависает навсегда, я не уверен, почему. Отпечатки "здесь" никогда не попадают, что кажется странным.

Спасибо за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...