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 ]