1

I have a thread subclass like this

class MyThread : public QThread
{
public:
    MyThread (void);
    ~MyThread (void);

    void run();

    void stop(); // close server and terminate thread

public slots:
    void slotCloseServer();

signals:
    void signalCloseServer();

private:
    QTcpServer* m_pServer;
};

and the run() and the overall class definition is outlined below

MyThread::MyThread()
{
    connect(this, SIGNAL(signalCloseServer()), this, SLOT(slotCloseServer()));
}

void MyThread::run()
{
    m_pServer = new QTcpServer();

    if(m_pServer->listen(QHostAddress(QHostAddress::LocalHost), 8888) == 0)
    {
        qCritical("Server listen failed.");
    }
    else
    {
        exec();
    }
}

void MyThread::stop()
{
    emit signalCloseServer();
    quit(); // terminate thread
}

void MyThread::slotCloseServer()
{
    if (m_pServer && m_pServer->isListening())
    {
        m_pServer->close();
    }
}

Now from the main thread, I want to call stop() so it would signal to the thread instance to close the server and terminate itself but it never gets to slotCloseServer() and the listening port does not get released.

Any thoughts as to how to release the server socket before the terminating the thread?

Thanks,

Professor Chaos
  • 8,850
  • 8
  • 38
  • 54
  • What about trying to use a signal to call stop, not direct function call? – liuyanghejerry Oct 10 '12 at 14:14
  • @liuyanghejerry I have not tried that. instead calling `thread->stop()`, if I did `QTimer::singleShot(0, thread, SLOT(stop()))`, would that help ? – Professor Chaos Oct 10 '12 at 14:24
  • I think it should be. In multi thread Qt program, using signal and slot to call functions is a good way to prevent calling functions in different thread. Because if we use signal and slot, function calls will become a message from different thread, not a direct call. – liuyanghejerry Oct 10 '12 at 14:51
  • Try connecting to QThread::finished () or QThread::terminated (), those should fire after the thread is died so your main thread to stop the server and destroy the object. – Thadeux Oct 10 '12 at 19:20

2 Answers2

0

Why not call slotCloseServer() from stop()?

void MyThread::stop()
{
    slotCloseServer(); // close server

    quit(); // terminate thread
}

void MyThread::slotCloseServer()
{
    if (m_pServer && m_pServer->isListening())
    {
        m_pServer->close();
    }
}
Lwin Htoo Ko
  • 2,326
  • 4
  • 26
  • 38
0

I think for the cases when something should be done when a created object is destroyed(in you case thread termination) better to state needed actions in destructor of class of that object:

MyThread ::~MyThread (void)
{
    m_pServer->close();
}
spin_eight
  • 3,925
  • 10
  • 39
  • 61