Close blocking QLocalServer from other thread

I am running a blocking QLocalServer in a thread:

void QThread::stopServer()
{
    m_abort = true;
    m_server.close(); // QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread 
}

void QThread::run()
{
    m_server = new QLocalServer();
    m_server->Listen("PipeName");
    while (!m_abort)
    {
        if (m_server->waitForNewConnection())
        {
            // handle the connection
        }
    }
    delete m_server;
}

How can the server be closed from another thread? Or is the only way to use non-blocking events?

Regards,

1 answer

  • answered 2020-05-10 17:33 Vladimir Bershov

    Why just not wait until run() closes or deletes the connection itself, after m_abort will be set?

    void QThread::stopServer()
    {
        m_abort = true; // shall be thread-safe (std::atomic<bool>, etc)
        wait(); // It’s optional to use it here
    }
    
    void QThread::run()
    {
        m_server = new QLocalServer();
        m_server->Listen("PipeName");
        while (!m_abort)
        {
            if (m_server->waitForNewConnection())
            {
                /* Most likely you cannot handle the connection
                which was closed in another place, therefore сlose (delete)
                it after leaving here */
            }
        }
        delete m_server;
    }
    

    Please note you can use the standard QThread::requestInterruption and isInterruptionRequested() methods instead of creating own m_abort variable.

    From the doc:

    This function can be used to make long running tasks cleanly interruptible. Never checking or acting on the value returned by this function is safe, however it is advisable do so regularly in long running functions. Take care not to call it too often, to keep the overhead low.

    So you can write:

    void QThread::stopServer()
    {
        requestInterruption();
        wait(); // It’s optional to use it here
    }
    
    void QThread::run()
    {
        m_server = new QLocalServer();
        m_server->Listen("PipeName");
        while (!isInterruptionRequested())
        {
            if (m_server->waitForNewConnection(100)) // 100 ms for not to call too often
            {
                /* Most likely you cannot handle the connection
                which was closed in another place, therefore сlose (delete)
                it after leaving here */
            }
        }
        delete m_server;
    }
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum