[Qt-interest] QProcess could close the reading pipe, thus killing the child process with SIGPIPE
Thiago Macieira
thiago.macieira at trolltech.com
Sun May 3 18:53:11 CEST 2009
Thiago Macieira wrote:
>The code you posted seemed right at first glance, except for the
>waitForReadyRead calls (and the use of a thread in the first place). The
>use of a thread points to the only other possibility here: there's a
>threading mismatch and the QIODevice object is actually being touched
>from outside its thread. I'm going to take a quick look at your code.
In Imap/Parser/Parser.cpp:
Parser::Parser( QObject* parent, Imap::Mailbox::SocketFactoryPtr factory
):
QObject(parent), _factory(factory), _lastTagUsed(0),
_workerThread( this ),
This sets WorkerThread::_parser to "this". The Parser object is a QObject
whose thread affinity is the calling thread (not the worker thread).
In Parser.h:
WorkerHelper( Parser* parser ): _parser(parser) {};
This does the same thing. In both cases, you're passing QObject pointers
as parameters to QObject-derived class constructors, but in neither case
it's set as the parent QObject. That is quite confusing, because when I
read:
_workerThread(this)
or helper = new WorkerHelper( _parser );
I think it's setting the parent
Note: the semicolon after {} is wrong.
In any case, the WorkerHelper class is created inside the run() function,
so its thread-affinity is the worker thread.
In Streams/SocketFactory.cpp, all create() functions create QIODevice
derivatives without a parent, so they all also have affinity to the worker
thread.
Since both sender (the QIODevice) and receiver are in the same thread, the
delivering of the queued signal will interrupt any work done in the file
descriptor. That also means Parser::processLine will be called and run
outside its thread.
That means Parser::processLine and any functions it calls are safe.
What bothers me is the executeACommand() function, which accesses the
socket. From your construction, it seems that that function is called only
after the commandQueued signal is emitted, which is delivered to the
helper object (which, as we established, has affinity to the worker thread).
That means the signal is delivered via a queued connection. (btw, in
executeIfPossible you unnecessarily unlocks the mutex).
As I said before, there's nothing that stands out to the eye. But there's
a lot of things I wouldn't do, starting with the use of a thread. If you
remove the reason you added the thread in the first place (the
waitForBytesWritten and waitForReadyRead calls), you won't need a thread
and your problem should disappear.
--
Thiago Macieira - thiago.macieira (AT) nokia.com
Senior Product Manager - Nokia, Qt Software
Sandakerveien 116, NO-0402 Oslo, Norway
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20090503/4f0529d4/attachment.bin
More information about the Qt-interest-old
mailing list