Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 5

Qt-interest Archive, January 2007
QThread more .... QUdpsocket ?


Message 1 in thread

Hi,

I am trying to use QUdpsocket in a QThread with event loop .... and it's 
seems to be quite difficult ....
I wants to create a QUdpsocket in a thread like this :

void ClientThread::run()
{   
    udpSocket=new QUdpSocket();
    udpSocket->bind(PORT);
    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    exec();
}

void ClientThread::readyRead()
{
    while (udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        
udpSocket->readDatagram(datagram.data(),datagram.size(),&sender,&senderPort);
        .....
    }
}


the readyRead is reach one time then when I reach the readDatagram I 
have the following warning " QSocketNotifier:: socket notifier cannot be 
enabled from another thread" ?????
I have tryed to add updsocket->moveToThread(this) ... I don't what I can 
do ? It seems that using an exec loop in a thread is quite useless ... 
there is always something you have to do that you can do !
Is there any way to do this ?

Best regards,

Yannick

--
 [ signature omitted ] 

Message 2 in thread

Ooops ....
I have found the mistake ....
I have changed to 
connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);
and it works now ... but I don't understand why I have to implicitly say 
that ... it's a connection in the same thread !!!! is it a bug  ? In any 
case, I think that the qT documentation is not very clear about this point.
best regards

yannick

yannick kohn a écrit :
> Hi,
>
> I am trying to use QUdpsocket in a QThread with event loop .... and 
> it's seems to be quite difficult ....
> I wants to create a QUdpsocket in a thread like this :
>
> void ClientThread::run()
> {      udpSocket=new QUdpSocket();
>    udpSocket->bind(PORT);
>    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead()));
>    exec();
> }
>
> void ClientThread::readyRead()
> {
>    while (udpSocket->hasPendingDatagrams())
>    {
>        QByteArray datagram;
>        datagram.resize(udpSocket->pendingDatagramSize());
>        QHostAddress sender;
>        quint16 senderPort;
>        
> udpSocket->readDatagram(datagram.data(),datagram.size(),&sender,&senderPort); 
>
>        .....
>    }
> }
>
>
> the readyRead is reach one time then when I reach the readDatagram I 
> have the following warning " QSocketNotifier:: socket notifier cannot 
> be enabled from another thread" ?????
> I have tryed to add updsocket->moveToThread(this) ... I don't what I 
> can do ? It seems that using an exec loop in a thread is quite useless 
> ... there is always something you have to do that you can do !
> Is there any way to do this ?
>
> Best regards,
>
> Yannick
>
> -- 
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>

--
 [ signature omitted ] 

Message 3 in thread

> I am trying to use QUdpsocket in a QThread with event loop .... and it's 
> seems to be quite difficult ....
> I wants to create a QUdpsocket in a thread like this :
>
> void ClientThread::run()
> {   udpSocket=new QUdpSocket();
>    udpSocket->bind(PORT);
>    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead()));
>    exec();
> }


"udpSocket", the sender, lives in the thread controlled by "this". "this", 
the receiver objects, lives however in the thread that created "this", and 
not in the thread controlled by "this".

Hence you will always have a queued connection, resulting in the 
"readyRead" slot being called in the thread that created the 
"ClientThread" object (most likely the GUI thread, and definitely not the 
thread that controls the udpSocket).


> void ClientThread::readyRead()
> {
>    while (udpSocket->hasPendingDatagrams())
>    {
>        QByteArray datagram;
>        datagram.resize(udpSocket->pendingDatagramSize());
>        QHostAddress sender;
>        quint16 senderPort;
> 
> udpSocket->readDatagram(datagram.data(),datagram.size(),&sender,&senderPort);
>        .....
>    }
> }

The slot above is executed by the GUI thread, NOT by the worker thread 
created by the ClientThread instance.

>
> the readyRead is reach one time then when I reach the readDatagram I 
> have the following warning " QSocketNotifier:: socket notifier cannot be 
> enabled from another thread" ?????
> I have tryed to add updsocket->moveToThread(this) ... I don't what I can 
> do ? It seems that using an exec loop in a thread is quite useless ... 
> there is always something you have to do that you can do !
> Is there any way to do this ?

The receiver objects should be another object, and that object should be 
created in the run() function as well.

Volker


--
 [ signature omitted ] 

Message 4 in thread

Hi,

is it correct to do 
"connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection); 
" (in fact it works ... but there is perhaps side effect ?)

regards,

Yannick

Volker Hilsheimer a écrit :
>> I am trying to use QUdpsocket in a QThread with event loop .... and it's 
>> seems to be quite difficult ....
>> I wants to create a QUdpsocket in a thread like this :
>>
>> void ClientThread::run()
>> {   udpSocket=new QUdpSocket();
>>    udpSocket->bind(PORT);
>>    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead()));
>>    exec();
>> }
>>     
>
>
> "udpSocket", the sender, lives in the thread controlled by "this". "this", 
> the receiver objects, lives however in the thread that created "this", and 
> not in the thread controlled by "this".
>
> Hence you will always have a queued connection, resulting in the 
> "readyRead" slot being called in the thread that created the 
> "ClientThread" object (most likely the GUI thread, and definitely not the 
> thread that controls the udpSocket).
>
>
>   
>> void ClientThread::readyRead()
>> {
>>    while (udpSocket->hasPendingDatagrams())
>>    {
>>        QByteArray datagram;
>>        datagram.resize(udpSocket->pendingDatagramSize());
>>        QHostAddress sender;
>>        quint16 senderPort;
>>
>> udpSocket->readDatagram(datagram.data(),datagram.size(),&sender,&senderPort);
>>        .....
>>    }
>> }
>>     
>
> The slot above is executed by the GUI thread, NOT by the worker thread 
> created by the ClientThread instance.
>
>   
>> the readyRead is reach one time then when I reach the readDatagram I 
>> have the following warning " QSocketNotifier:: socket notifier cannot be 
>> enabled from another thread" ?????
>> I have tryed to add updsocket->moveToThread(this) ... I don't what I can 
>> do ? It seems that using an exec loop in a thread is quite useless ... 
>> there is always something you have to do that you can do !
>> Is there any way to do this ?
>>     
>
> The receiver objects should be another object, and that object should be 
> created in the run() function as well.
>
> Volker
>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>   


Message 5 in thread

"yannick kohn" <kohny@xxxxxxxxxxxx> wrote in message 
news:45B8DBA7.3040102@xxxxxxxxxxxxxxx
> Hi,
>
> is it correct to do
> "connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);
> " (in fact it works ... but there is perhaps side effect ?)
>
> regards,
>
> Yannick

It will make readRead be called by the worker thread, which will at least 
make your calls to the udpSocket succeed.

However, this introduces a potential for a race condition, i.e. if other 
code also calls your readyRead function, and then from a different thread. 
You can probably avoid this by making this function a private slot (which 
doesn't stop connections from work, but will at least make the intention 
clear), and by adding

Q_ASSERT(QThread::currentThread() == udpSocket->thread());

on top.


Volker


--
 [ signature omitted ]