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

Qt-interest Archive, March 2008
QSocket connection bug with parent/child processes ?


Message 1 in thread

1. I create a parent-child pair of processes using QProcess::start().
Both parent and child listen on an ephemeral port using QTcpListener.

2. When the parent spawns the child, it tells it via an environment
variable which port it listens on. When the child has created its
QTcpListener, it sends a text message back to the parent via stdout
to tell the parent which port it listens on.

3. Neither the parent nor the child can connect to the other
via QTcpSocket object. QTcpSocket::connect() consistently
returns "connection refused" (QAbstractSocket::ConnectionRefusedError)
I assume that this corresponds directly to ECONNREFUSED.

4. An unrelated process, however, can connect and communicate correctly
to either process, via TCP, using identical code.

As far as I know, the only time a connect attempt will get ECONNREFUSED
is when no process has bound to the port, but this is clearly
not the case here. Does anyone have any suggestion as to what's going
on, as I'm baffled at the moment.

-- 
 [ signature omitted ] 

Message 2 in thread

Stephen Collyer wrote:
>As far as I know, the only time a connect attempt will get ECONNREFUSED
>is when no process has bound to the port, but this is clearly
>not the case here. Does anyone have any suggestion as to what's going
>on, as I'm baffled at the moment.

Can you post a code sample or at least the strace output?

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 3 in thread

Thiago Macieira wrote:
> Stephen Collyer wrote:
>> As far as I know, the only time a connect attempt will get ECONNREFUSED
>> is when no process has bound to the port, but this is clearly
>> not the case here. Does anyone have any suggestion as to what's going
>> on, as I'm baffled at the moment.
> 
> Can you post a code sample or at least the strace output?

Thanks for the response. Don't you guys take a break at weekends ?

Anyway, I believe I know what the problem is, and I think that I
have fixed it. It seems to be due to the fact that I was creating
the QTcpSocket in a different thread to that which called its
methods. If I delay creation of the socket until the start of
run(), it all works fine. The reason that the unrelated process
worked was due to its creating and using the socket in the main thread.

This is a pretty fertile source of problems, as I've managed
to do something similar at least twice before. Is it possible for
this kind of problem to be detected and flagged at run-time
somehow ?

-- 
 [ signature omitted ] 

Message 4 in thread

Stephen Collyer wrote:
>Thiago Macieira wrote:
>> Stephen Collyer wrote:
>>> As far as I know, the only time a connect attempt will get
>>> ECONNREFUSED is when no process has bound to the port, but this is
>>> clearly not the case here. Does anyone have any suggestion as to
>>> what's going on, as I'm baffled at the moment.
>>
>> Can you post a code sample or at least the strace output?
>
>Thanks for the response. Don't you guys take a break at weekends ?

qt-interest is entirely voluntary. I'm not being paid to answer messages 
here. And since I'm home just watching TV, I read email every now and 
then. :-)

>Anyway, I believe I know what the problem is, and I think that I
>have fixed it. It seems to be due to the fact that I was creating
>the QTcpSocket in a different thread to that which called its
>methods. If I delay creation of the socket until the start of
>run(), it all works fine. The reason that the unrelated process
>worked was due to its creating and using the socket in the main thread.

The usual source of problems: threads. Don't use threads if you don't have 
to. Qt doesn't require threading for sockets. Or for almost anything...

I don't know if this is your case, but I think it's bad Java behaviour. 
Instead of making proper non-blocking operations in Java, they make you 
use threads. And then that's what people are taught to be the only way...

The other extreme is Alan Cox: "threads are for people who can't program a 
state machine" :-)

>This is a pretty fertile source of problems, as I've managed
>to do something similar at least twice before. Is it possible for
>this kind of problem to be detected and flagged at run-time
>somehow ?

Qt does warn you when you try to create objects with parents in other 
threads.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 5 in thread

On Saturday 15 March 2008 18:30:27 Thiago Macieira wrote:
> The other extreme is Alan Cox: "threads are for people who can't program a
> state machine" :-)
heh. and he's darn right :P

-- 
 [ signature omitted ] 

Message 6 in thread

Thiago Macieira wrote:

>> The reason that the unrelated process
>> worked was due to its creating and using the socket in the main thread.
> 
> The usual source of problems: threads. Don't use threads if you don't have 
> to. Qt doesn't require threading for sockets. Or for almost anything...
> 
> I don't know if this is your case, but I think it's bad Java behaviour. 
> Instead of making proper non-blocking operations in Java, they make you 
> use threads. And then that's what people are taught to be the only way...

In my case, it's not a bad habit picked up from Java (maybe from too
much pthreads, though ...). I'm porting some originally non-threaded
code with a multiprocess message-passing architecture. To minimize
changes, I want to run code that looks like:

while(receive message)
{
    process message
}

But that raises the problem of running a Qt message loop at the
same time, which I want to do, in order to use QTcpServer et al.

So to fix this, I put the code above into its own thread, and
run QTcpServer in the main thread, which does have an event loop,
and have it deliver messages to the message processing thread.
That way, I get the signal-slot goodness, but can isolate the
existing code more-or-less unchanged. But, of course, I still
have to worry about creating objects in the correct thread, hence
my problem. If I was starting from a clean slate, I'd redo it
all using signals and slots.

> The other extreme is Alan Cox: "threads are for people who can't program a 
> state machine" :-)

That's not particularly extreme: VMS, for example, once very
main stream, was based almost totally on an asynchronous API,
with no concept of threads at all. And there have been state
machine program design approaches in the past (Auto-G, for
example).

>> This is a pretty fertile source of problems, as I've managed
>> to do something similar at least twice before. Is it possible for
>> this kind of problem to be detected and flagged at run-time
>> somehow ?
> 
> Qt does warn you when you try to create objects with parents in other 
> threads.

It'd be nice if it could warn you by throwing an exception,
so that it's impossible to ignore.

-- 
 [ signature omitted ] 

Message 7 in thread

On Sunday 16 March 2008 15:21:42 Stephen Collyer wrote:
> while(receive message)
> {
>     process message
> }
>
> But that raises the problem of running a Qt message loop at the
> same time, which I want to do, in order to use QTcpServer et al.
QApplication::processEvents if you cant rewrite it properly. You can also go 
for a zero duration timer, or a nested eventloop. All ugly solutions for 
problems that shouldn't ocure normaly :(
> > Qt does warn you when you try to create objects with parents in other
> > threads.
> It'd be nice if it could warn you by throwing an exception,
> so that it's impossible to ignore.
i assume you mean abort. And i don't find stderr output ignoreable :P


-- 
 [ signature omitted ] 

Message 8 in thread

Arvid Ephraim Picciani wrote:
> On Sunday 16 March 2008 15:21:42 Stephen Collyer wrote:
>> while(receive message)
>> {
>>     process message
>> }
>>
>> But that raises the problem of running a Qt message loop at the
>> same time, which I want to do, in order to use QTcpServer et al.
> QApplication::processEvents if you cant rewrite it properly. You can also go 
> for a zero duration timer, or a nested eventloop. All ugly solutions for 
> problems that shouldn't ocure normaly :(

I think I posted a much more elegant solution, which cleanly
separates the signal-slot code from the message passing code.

>>> Qt does warn you when you try to create objects with parents in other
>>> threads.
>> It'd be nice if it could warn you by throwing an exception,
>> so that it's impossible to ignore.
> i assume you mean abort. 

No. I'm not sure what you mean. I was suggesting that it'd
be preferable to take out the whole process via an unhandled
exception than to let it continue with a design flaw.

> And i don't find stderr output ignoreable :P

In my case the problem was occurring in processes where
stderr was not connected to a controlling terminal.

-- 
 [ signature omitted ] 

Message 9 in thread

Stephen Collyer wrote:
>> And i don't find stderr output ignoreable :P
>
>In my case the problem was occurring in processes where
>stderr was not connected to a controlling terminal.

Run your applications with QT_FATAL_WARNINGS=1.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 10 in thread

Thiago Macieira wrote:
> Stephen Collyer wrote:
>>> And i don't find stderr output ignoreable :P
>> In my case the problem was occurring in processes where
>> stderr was not connected to a controlling terminal.
> 
> Run your applications with QT_FATAL_WARNINGS=1.

Thanks. That's very helpful.

-- 
 [ signature omitted ]