Variable-length reply messages?

Here’s a problem I’d like some help with - variable length replies to ‘Send’
messages. Being a newcomer to qnx the answer isn’t clear to me.
Proc A sends a message to Proc B. The message could be variable in length.
Proc B can determine the length/content from a message header and so with a
combination of Receive/Receivemx and Readmsg/Readmsgmx it can happily read
and deal with a variable length message. The reply that Proc B send back to
Proc A is also variable. I can see that by using Reply/Replymx &
Writemsg/Writemsgmx it can write back a message of variable length/content.
My problem comes back at Proc A where before the call to ‘Send()’, it may
not know how big the reply is going to be and therefore how much buffer to
allocate/manage.
Now I can see that at some point both the send and reply buffers need to be
of finite size. Since Proc A governs the lifetime of the transaction I guess
it’s only logical that this therefore has to be the one to manage the
buffers and therefore be the one to put a finite size on them. I note that
the ‘Reply.’ functions write back the minimum size of that specified by the
receiver & sender. I could implement various schemes whereby Proc A can take
an educated guess at the size of the reply and therefore allocate or
over-allocate to cope with this. I’m just wondering whether I’ve missed
something blindingly obvious or if the qnx-veterans have a nice ‘dodge’ to
get round this.
Can anyone help?

Is this for QNX4?
If so the example under Send in the helpviewer shows a good way-
a union of messages, with a common id field to tell you which
message was received. As the size of the union is the max size
of any contituent struct, using a message of the union type
will be the max size you should ever receive.
All participating processes will have the same message definition,
commonly declared in a separate include file.

andy parker wrote:

Here’s a problem I’d like some help with - variable length replies to ‘Send’
messages. Being a newcomer to qnx the answer isn’t clear to me.
Proc A sends a message to Proc B. The message could be variable in length.
Proc B can determine the length/content from a message header and so with a
combination of Receive/Receivemx and Readmsg/Readmsgmx it can happily read
and deal with a variable length message. The reply that Proc B send back to
Proc A is also variable. I can see that by using Reply/Replymx &
Writemsg/Writemsgmx it can write back a message of variable length/content.
My problem comes back at Proc A where before the call to ‘Send()’, it may
not know how big the reply is going to be and therefore how much buffer to
allocate/manage.
Now I can see that at some point both the send and reply buffers need to be
of finite size. Since Proc A governs the lifetime of the transaction I guess
it’s only logical that this therefore has to be the one to manage the
buffers and therefore be the one to put a finite size on them. I note that
the ‘Reply.’ functions write back the minimum size of that specified by the
receiver & sender. I could implement various schemes whereby Proc A can take
an educated guess at the size of the reply and therefore allocate or
over-allocate to cope with this. I’m just wondering whether I’ve missed
something blindingly obvious or if the qnx-veterans have a nice ‘dodge’ to
get round this.
Can anyone help?

andy parker <parker@ultra.demon.co.uk> wrote:

Here’s a problem I’d like some help with - variable length replies to ‘Send’
messages. Being a newcomer to qnx the answer isn’t clear to me.
Proc A sends a message to Proc B. The message could be variable in length.
Proc B can determine the length/content from a message header and so with a
combination of Receive/Receivemx and Readmsg/Readmsgmx it can happily read
and deal with a variable length message. The reply that Proc B send back to
Proc A is also variable. I can see that by using Reply/Replymx &
Writemsg/Writemsgmx it can write back a message of variable length/content.
My problem comes back at Proc A where before the call to ‘Send()’, it may
not know how big the reply is going to be and therefore how much buffer to
allocate/manage.

Yes, this is a limitation – because the Reply() unblocks the client,
and doesn’t block the server, there is no way to pass a header, allocate
the buffer, then get the rest of the data on a Reply(). You end up having
a couple of choices:
– allocate on the client side a big enough buffer for the largest possible
Reply() that could happen
– use a more complicated protocol
probably do something like have a field in your request that is sent
to the server that specifies how big your reply buffer is, then the
server would indicate with a flag in the reply header that it has
filled your buffer, and still has more data for you. You’d then
send another message requesting this data.
(FWIW, read() is implemented this way – it does a series of 32K
transfers until it has gotten all the client requested or all the
server has available.)

Now I can see that at some point both the send and reply buffers need to be
of finite size. Since Proc A governs the lifetime of the transaction I guess
it’s only logical that this therefore has to be the one to manage the
buffers and therefore be the one to put a finite size on them. I note that
the ‘Reply.’ functions write back the minimum size of that specified by the
receiver & sender. I could implement various schemes whereby Proc A can take
an educated guess at the size of the reply and therefore allocate or
over-allocate to cope with this. I’m just wondering whether I’ve missed
something blindingly obvious or if the qnx-veterans have a nice ‘dodge’ to
get round this.

Nope, no nice dodge – sorry. See above for suggestion of a reasonable way
to handle this.

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs <dagibbs@qnx.com> wrote:

(FWIW, read() is implemented this way – it does a series of 32K
transfers until it has gotten all the client requested or all the
server has available.)

BTW, that is only the QNX4 read(). It has to deal with an environment
where the msg pass is limitted to 64K, and it might even be dealing with
16-bit servers. Under QNX Neutrino OS, the read() will do it all in one
go. (Of course, the server is still allowed to only partially fill the
reply buffer, say if it doesn’t have enough data, and the client is
allowed to use multiple smaller read() calls to work through a large
chunk of data.)

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs <dagibbs@qnx.com> wrote:

andy parker <> parker@ultra.demon.co.uk> > wrote:
Here’s a problem I’d like some help with - variable length replies to ‘Send’
messages. Being a newcomer to qnx the answer isn’t clear to me.
Proc A sends a message to Proc B. The message could be variable in length.
Proc B can determine the length/content from a message header and so with a
combination of Receive/Receivemx and Readmsg/Readmsgmx it can happily read
and deal with a variable length message. The reply that Proc B send back to
Proc A is also variable. I can see that by using Reply/Replymx &
Writemsg/Writemsgmx it can write back a message of variable length/content.
My problem comes back at Proc A where before the call to ‘Send()’, it may
not know how big the reply is going to be and therefore how much buffer to
allocate/manage.

Yes, this is a limitation – because the Reply() unblocks the client,
and doesn’t block the server, there is no way to pass a header, allocate
the buffer, then get the rest of the data on a Reply(). You end up having
a couple of choices:
– allocate on the client side a big enough buffer for the largest possible
Reply() that could happen
– use a more complicated protocol
probably do something like have a field in your request that is sent
to the server that specifies how big your reply buffer is, then the
server would indicate with a flag in the reply header that it has
filled your buffer, and still has more data for you. You’d then
send another message requesting this data.
(FWIW, read() is implemented this way – it does a series of 32K
transfers until it has gotten all the client requested or all the
server has available.)

There is a dirty way that I saw some people use a while ago:

The client don’t need to tell server how much buffer it has. The server
just blindly “WriteMsg()”, and check the return value to make sure
everything is write out. If Server found out that not everything is
in client’s buffer, then it Reply() “I need xxxK for reply”, and
client do Send() again with that much buffer.

This is dirty because if client/server cross the network, this won’t
work.

If you implementing something from scratch, always let client tell
server how much it’s receiver buffer is.

-xtang

Now I can see that at some point both the send and reply buffers need to be
of finite size. Since Proc A governs the lifetime of the transaction I guess
it’s only logical that this therefore has to be the one to manage the
buffers and therefore be the one to put a finite size on them. I note that
the ‘Reply.’ functions write back the minimum size of that specified by the
receiver & sender. I could implement various schemes whereby Proc A can take
an educated guess at the size of the reply and therefore allocate or
over-allocate to cope with this. I’m just wondering whether I’ve missed
something blindingly obvious or if the qnx-veterans have a nice ‘dodge’ to
get round this.

Nope, no nice dodge – sorry. See above for suggestion of a reasonable way
to handle this.

-David

QNX Training Services
dagibbs@qnx.com