multi-threads and message passing

Hello,

I’ve got a communication problem between the threads of two different
processes:

I have two server processes (Central_Server and Local_Server) and one client
process (Local_Client) running on one machine. The task is intended as
follows (please take a pen and a piece of paper) :wink: :

  1. Local_Server sends a message “REQUEST” to Central_Server, who was receive
    blocked before. This message is received and sent to Local_Server, who was
    receive blocked. Local_Server immediately replies (Central_Server so
    unblocks again). Central_Server receive blocks for further messages.
  2. After Local_Server has processed the “REQUEST” it sends the “ANSWER” to
    Central_Server who replies the “ANSWER” at first back to Local_Client, who
    was still waiting and now unblocks. Then Central_Server replies back to
    Local_Server, who unblocks.

In theory and practice everything runs fine as long as Local_Client,
Local_Server and Central_Server are all one-threaded processes. But I have
to design Local_Server as two-threaded: One thread (2) always receive blocks
while the other thread (1) is free for user inputs that effect the messages
to be reacted on. In Central_Server I use a list that stores the rcvids of
the single reply-tasks. But when I try to unblock Local_Server (thread 2) by
Central_Server after sending a reply to Local_Client, the message does not
arrive at Local_Server although Central_Server has sent it correctly.

Does anybody know why this happens and what thread 2 of Local_Server can do
to be able to receive the reply from Central_Server?

I hope that I was able to describe this (maybe easy problem) properly. Thank
you.

Nnamdi

Nnamdi Kohn <nnamdi.kohn@tu-bs.de> wrote:

Hello,

I’ve got a communication problem between the threads of two different
processes:

I have two server processes (Central_Server and Local_Server) and one client
process (Local_Client) running on one machine. The task is intended as
follows (please take a pen and a piece of paper) > :wink: > :

  1. Local_Server sends a message “REQUEST” to Central_Server, who was receive
    blocked before. This message is received and sent to Local_Server, who was
    receive blocked. Local_Server immediately replies (Central_Server so
    unblocks again). Central_Server receive blocks for further messages.
  2. After Local_Server has processed the “REQUEST” it sends the “ANSWER” to
    Central_Server who replies the “ANSWER” at first back to Local_Client, who
    was still waiting and now unblocks. Then Central_Server replies back to
    Local_Server, who unblocks.

In theory and practice everything runs fine as long as Local_Client,
Local_Server and Central_Server are all one-threaded processes.

Actually, in theory you have a problem. You have a potential deadlock
between local_server and central_server – for instance if Central_server
sends a “REQUEST” to local_server and at the same time local_server
sends the “ANSWER” to a previous request to Central_server. You will
end up with a deadlock situation.

This would be better restructured as:
When Local_Server has an “ANSWER” he delivers a pulse to Central_Server,
Central_Server then sends a “GET ANSWER” to Local_Server which replies
with the ANSWER, Central_Server then replies to Local_Client with the
answer.

But I have
to design Local_Server as two-threaded: One thread (2) always receive blocks
while the other thread (1) is free for user inputs that effect the messages
to be reacted on. In Central_Server I use a list that stores the rcvids of
the single reply-tasks. But when I try to unblock Local_Server (thread 2) by
Central_Server after sending a reply to Local_Client, the message does not
arrive at Local_Server although Central_Server has sent it correctly.

By “try to unblock” I assume you mean do a MsgReply(). Do you check the
return value from your MsgReply()? Does it succeed or fail? If it fails,
what is errno?

Does anybody know why this happens and what thread 2 of Local_Server can do
to be able to receive the reply from Central_Server?

All thread2 needs to be is REPLY-blocked on Central_server to get a reply.
Most likely, you’ve got a bug somewhere, getting/using your stored rcvids
or something like that, or replying to soon, and trying to reply again
later.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Actually, in theory you have a problem. You have a potential deadlock
between local_server and central_server – for instance if Central_server
sends a “REQUEST” to local_server and at the same time local_server
sends the “ANSWER” to a previous request to Central_server. You will
end up with a deadlock situation.

You are right, but I always check for deadlocks through comparing open
communication activities in the central_server before passing on a further
request to a local_server. It might not be the best solution but in general
it should avoid deadlocks.

This would be better restructured as:
When Local_Server has an “ANSWER” he delivers a pulse to Central_Server,
Central_Server then sends a “GET ANSWER” to Local_Server which replies
with the ANSWER, Central_Server then replies to Local_Client with the
answer.

good idea, I might implement it like this in a further version.

But I have
to design Local_Server as two-threaded: One thread (2) always receive
blocks
while the other thread (1) is free for user inputs that effect the
messages
to be reacted on. In Central_Server I use a list that stores the rcvids
of
the single reply-tasks. But when I try to unblock Local_Server (thread
2) by
Central_Server after sending a reply to Local_Client, the message does
not
arrive at Local_Server although Central_Server has sent it correctly.

By “try to unblock” I assume you mean do a MsgReply(). Do you check the
return value from your MsgReply()? Does it succeed or fail? If it fails,
what is errno?

errno is 3 - “no such process”

Does anybody know why this happens and what thread 2 of Local_Server can
do
to be able to receive the reply from Central_Server?

All thread2 needs to be is REPLY-blocked on Central_server to get a reply.
Most likely, you’ve got a bug somewhere, getting/using your stored rcvids
or something like that, or replying to soon, and trying to reply again
later.

I’ll have to check this in detail. But in general: Is the rcvid the only
thing a Reply() needs to localize the associated thread regardless in which
process the thread lies?

Nnamdi

Nnamdi Kohn <nnamdi.kohn@tu-bs.de> wrote:

By “try to unblock” I assume you mean do a MsgReply(). Do you check the
return value from your MsgReply()? Does it succeed or fail? If it fails,
what is errno?

errno is 3 - “no such process”

(Assuming it fails, and errno is 3…)

ESRCH. Ok, this generally means that the thread you are trying to
reply to is not REPLY blocked on your process – it could be due
to the fact that the thread does not exist any more, more likely the
thread does exist, but is not REPLY blocked, or not REPLY blocked on
your process.

All thread2 needs to be is REPLY-blocked on Central_server to get a reply.
Most likely, you’ve got a bug somewhere, getting/using your stored rcvids
or something like that, or replying to soon, and trying to reply again
later.

I’ll have to check this in detail. But in general: Is the rcvid the only
thing a Reply() needs to localize the associated thread regardless in which
process the thread lies?

Yes, rcvid is all you need to find the correct thread for a MsgReply().
(It is the only parameter a MsgReply() takes that directs where the reply
should go.)

The fact that you are getting ESRCH for the error on the reply strongly
suggests you have one of two errors:
– you’re saving/restoring/replying to the wrong rcvid
– in this case, if you look at system state, you should see the
thread in Local_server still REPLY blocked on Central_server
– this can be checked with the system information perspective
in the IDE, or with the pidin command-line utility
– your sequences/state changes are incorrect, likely in that you have
already replied to the thread. If you have replied to it once, you
can not reply to it again until/unless it sends to you again. A reply
can not unblock a MsgReceive() call or transfer/transmit any information
to a RECEIVE blocked thread.
– again, check the state of the threads with the IDE or pidin

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hey David, thank you for your help.

I was stupid (as usual) and overlooked that rcvids can be 32bit variables.
In my program there were sometimes 16bit variables used to store them. pidin
showed exactly what you said: REPLY blocked on the central_server.

Nnamdi

“David Gibbs” <dagibbs@qnx.com> schrieb im Newsbeitrag
news:b6sfpk$7gj$1@nntp.qnx.com

Nnamdi Kohn <> nnamdi.kohn@tu-bs.de> > wrote:
By “try to unblock” I assume you mean do a MsgReply(). Do you check
the
return value from your MsgReply()? Does it succeed or fail? If it
fails,
what is errno?

errno is 3 - “no such process”

(Assuming it fails, and errno is 3…)

ESRCH. Ok, this generally means that the thread you are trying to
reply to is not REPLY blocked on your process – it could be due
to the fact that the thread does not exist any more, more likely the
thread does exist, but is not REPLY blocked, or not REPLY blocked on
your process.

All thread2 needs to be is REPLY-blocked on Central_server to get a
reply.
Most likely, you’ve got a bug somewhere, getting/using your stored
rcvids
or something like that, or replying to soon, and trying to reply again
later.

I’ll have to check this in detail. But in general: Is the rcvid the only
thing a Reply() needs to localize the associated thread regardless in
which
process the thread lies?

Yes, rcvid is all you need to find the correct thread for a MsgReply().
(It is the only parameter a MsgReply() takes that directs where the reply
should go.)

The fact that you are getting ESRCH for the error on the reply strongly
suggests you have one of two errors:
– you’re saving/restoring/replying to the wrong rcvid
– in this case, if you look at system state, you should see the
thread in Local_server still REPLY blocked on Central_server
– this can be checked with the system information perspective
in the IDE, or with the pidin command-line utility
– your sequences/state changes are incorrect, likely in that you have
already replied to the thread. If you have replied to it once, you
can not reply to it again until/unless it sends to you again. A
reply
can not unblock a MsgReceive() call or transfer/transmit any
information
to a RECEIVE blocked thread.
– again, check the state of the threads with the IDE or pidin

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.