[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-devel
Subject: Re: Race Condition Issue with KJob and QNetworkAccessManager
From: Adrián_Chaves_Fernández <adriyetichaves () gmail ! com>
Date: 2013-03-05 20:25:13
Message-ID: 6397477.QKkKV224tz () afonso
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
O Martes, 5 de Marzo de 2013 11:53:13 Frank Reininghaus escribiu:
> I'm not a network expert, and I don't know what the cause of the
> problem is, but I noticed two things:
>
> 1. I think the access to "m_request" in FakeServer::*Request() needs
> to be protected by locking m_mutex. Doing that does not seem to fix
> the issue, but not protecting it might lead to other problems at some
> point.
>
> 2. The class FakeServer follows the "You're doing it wrong" pattern
> (it contains the line "moveToThread(this);") , see
>
> http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
> http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html
>
> This might or might not be part of the problem.
Many thanks for the input!
I think I've solve both issues, but the race condition persists.
I've uploaded a tar.xz with the current state of the test files to Gitorious: \
https://gitorious.org/libmediawiki/libmediawiki/blobs/raw/gallaecio/examples/raceissue/2ndAttemptToAvoidRaceCondition.tar.xz
The files can also be found at \
https://gitorious.org/libmediawiki/libmediawiki/trees/gallaecio/examples/raceissue
I followed the lead of the Qt documentation, and the main function looks like this \
now:
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QThread *serverThread = new QThread();
FakeServer *fakeserver = new FakeServer;
QObject::connect(serverThread, SIGNAL(started()), fakeserver, SLOT(run()));
QObject::connect(serverThread, SIGNAL(finished()), fakeserver, \
SLOT(deleteLater())); fakeserver->moveToThread(serverThread);
serverThread->start();
for (int i = 0; i < 10000; i++) {
Job job;
job.exec();
QList<FakeServer::Request> requests = fakeserver->getRequest();
if (requests.size() != 1) qDebug() << requests.size() << "? WTF?";
else qDebug() << requests.size() << ", as expected.";
fakeserver->clearRequest();
}
serverThread->quit();
return 0;
}
[Attachment #5 (unknown)]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" \
"http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" \
content="1" /><style type="text/css"> p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'Oxygen'; font-size:10pt; font-weight:400; \
font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">O Martes, 5 \
de Marzo de 2013 11:53:13 Frank Reininghaus escribiu:</p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;">> I'm not a network expert, and I don't know \
what the cause of the</p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;">> problem is, but I noticed two things:</p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> </p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> 1. I think the access to \
"m_request" in FakeServer::*Request() needs</p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;">> to be protected by locking m_mutex. Doing \
that does not seem to fix</p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;">> the issue, but not protecting it might lead to other problems \
at some</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> \
point.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> </p> \
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> 2. The class FakeServer \
follows the "You're doing it wrong" pattern</p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;">> (it contains the line \
"moveToThread(this);") , see</p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;">> </p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;">> \
http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/</p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> \
http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html</p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> </p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">> This might or might not \
be part of the problem.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; "> </p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;">Many thanks for the input!</p> <p style="-qt-paragraph-type:empty; \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; "> </p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;">I think I've solve both issues, but the race \
condition persists.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; "> </p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;">I've uploaded a tar.xz with the current state of the test files to \
Gitorious: https://gitorious.org/libmediawiki/libmediawiki/blobs/raw/gallaecio/examples/raceissue/2ndAttemptToAvoidRaceCondition.tar.xz</p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; "> </p> \
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">The files can also be found \
at https://gitorious.org/libmediawiki/libmediawiki/trees/gallaecio/examples/raceissue</p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; "> </p> \
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;">I followed the lead of the Qt \
documentation, and the main function looks like this now:</p> <p \
style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; "> </p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span style=" \
font-family:'monospace';">int main(int argc, char* argv[])</span></p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span style=" \
font-family:'monospace';">{</span></p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;"><span style=" font-family:'monospace';"> QCoreApplication \
a(argc, argv);</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; "> </p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;"><span style=" font-family:'monospace';"> QThread *serverThread \
= new QThread();</span></p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;"><span style=" font-family:'monospace';"> FakeServer *fakeserver \
= new FakeServer;</span></p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;"><span style=" font-family:'monospace';"> \
QObject::connect(serverThread, SIGNAL(started()), fakeserver, \
SLOT(run()));</span></p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;"><span style=" font-family:'monospace';"> \
QObject::connect(serverThread, SIGNAL(finished()), fakeserver, \
SLOT(deleteLater()));</span></p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;"><span style=" font-family:'monospace';"> \
fakeserver->moveToThread(serverThread);</span></p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;"><span style=" font-family:'monospace';"> \
serverThread->start();</span></p> <p style="-qt-paragraph-type:empty; \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; "> </p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;"><span style=" font-family:'monospace';"> for \
(int i = 0; i < 10000; i++) {</span></p> <p style="-qt-paragraph-type:empty; \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; "> </p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;"><span style=" font-family:'monospace';"> \
Job job;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span \
style=" font-family:'monospace';"> job.exec();</span></p> <p \
style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; "> </p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span style=" \
font-family:'monospace';"> QList<FakeServer::Request> requests = \
fakeserver->getRequest();</span></p> <p style=" margin-top:0px; margin-bottom:0px; \
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; \
-qt-user-state:0;"><span style=" font-family:'monospace';"> if \
(requests.size() != 1) qDebug() << requests.size() << "? \
WTF?";</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span \
style=" font-family:'monospace';"> else qDebug() << \
requests.size() << ", as expected.";</span></p> <p \
style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; "> </p> <p style=" \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span style=" \
font-family:'monospace';"> fakeserver->clearRequest();</span></p> <p \
style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span style=" \
font-family:'monospace';"> }</span></p> <p style="-qt-paragraph-type:empty; \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; "> </p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;"><span style=" font-family:'monospace';"> \
serverThread->quit();</span></p> <p style="-qt-paragraph-type:empty; \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; "> </p> <p style=" margin-top:0px; \
margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; \
text-indent:0px; -qt-user-state:0;"><span style=" font-family:'monospace';"> \
return 0;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; \
margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><span \
style=" font-family:'monospace';">}</span></p> <p style="-qt-paragraph-type:empty; \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; "> </p> <p style="-qt-paragraph-type:empty; \
margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; \
-qt-block-indent:0; text-indent:0px; "> </p></body></html>
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic