Resource Manager

Hi, All

I wrote a resource manager to get _IO_MSG messages. And when it started
to get bigger messages I found problem with receiving ones.

I send a message 7932 byte and get:
ctp->info.srcmsglen = 2077
ctp->info.msglen = 2077
cpt->size = 41

Why srcmsglen doesn’t equal 7932?
Why msglen doesn’t equal size?
What difference between ctp->info.msglen and cpt->size?

I tried to change resmgr_attr.msg_max_size from 2048 to 4096 and what
I saw:
ctp->info.srcmsglen = 4104
ctp->info.msglen = 4104
cpt->size = 41

Looking to the documentation:
msg_max_size
The minimum amount of room to reserve for receiving a message
that’s allocated in resmgr_context_alloc(). If the value is too
low, or you specify it as 0, resmgr_attach() picks a value
that’s usable.

So if I understand right msg_max_size is just a buffer, not a upper size
of incoming message. Then why I can get message more then msg_max_size?

I am using QNX 6.2.1A


Sergiy Uvarov

Sergiy Uvarov <colonel@rts-ukraine.com> wrote:

Hi, All

I wrote a resource manager to get _IO_MSG messages. And when it started
to get bigger messages I found problem with receiving ones.

I send a message 7932 byte and get:
ctp->info.srcmsglen = 2077
ctp->info.msglen = 2077
cpt->size = 41

Why srcmsglen doesn’t equal 7932?

For srcmsglen to be valid, the _NTO_CHF_SENDER_LEN flag must
be set when the channel was created. From both the behaviour
here (and in my 6.3.0 Beta test), and from looking at the source
to the resmgr library, that flag does not appear to be set. So,
srcmsglen does not have a dependable length. (Also the destmsglen
won’t be valid, as _NTO_CHF_REPLY_LEN is not set either.)

Why msglen doesn’t equal size?

I’m not sure why – in my test (again, 6.3.0 beta), ctp->size
was 2077, the same as ctp->info.msglen.

This may be something that was changed/fixed between 6.2.1A
and what I’m using.

Looking to the documentation:
msg_max_size
The minimum amount of room to reserve for receiving a message
that’s allocated in resmgr_context_alloc(). If the value is too
low, or you specify it as 0, resmgr_attach() picks a value
that’s usable.

So if I understand right msg_max_size is just a buffer, not a upper size
of incoming message. Then why I can get message more then msg_max_size?

Yes, msg_max_size is the size of the receive buffer, think of it as the
largest message that can be received in one piece.

To get the rest of your message, you’ll have to look at something like
MsgRead(), which will copy missing stuff out of the sender’s send buffer.

And, since the srcmsglen isn’t valid, you’ll have to put information in
the message header as to the amount of data actually to be handled (or
to know the amount based on the type of message.)

-David

Please follow-up to newsgroup, rather than personal email.
David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs <dagibbs@qnx.com> wrote:

Sergiy Uvarov <> colonel@rts-ukraine.com> > wrote:

And, since the srcmsglen isn’t valid, you’ll have to put information in
the message header as to the amount of data actually to be handled (or
to know the amount based on the type of message.)

Or, instead of calling dispatch_create(), you may be able to do the
following (not verified vs 6.2.1A, but works in 6.3.0, undocumented
extension of the resource manager API, use at your own risk):

/* prototype the function to make compiler happy */
dispatch_t * _dispatch_create(int chid, int flags );

/* we used to call dispatch_create /
/
dpp = dispatch_create(); */

/* now we create a channel with the expected flags, and our length requesting
flags set */
chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN );
dpp = _dispatch_create( chid, 0 );


As a side note, for anyone using name_attach():

chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN | _NTO_CHF_COID_DISCONNECT );
dpp = _dispatch_create( chid, 0 );
attach = name_attach( dpp, “name_to_register”, 0 );

Will get you the flags you want for your name_attach()'d
channel.

-David

Please follow-up to newsgroup, rather than personal email.
David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs <dagibbs@qnx.com> wrote:

Sergiy Uvarov <> colonel@rts-ukraine.com> > wrote:
To get the rest of your message, you’ll have to look at something like
MsgRead(), which will copy missing stuff out of the sender’s send buffer.

From within a resmgr use the “resmgr_msgread()” routine instead, it
will also take care of combine messages by applying an internal offset
into the message-pass data … refer to the HelpViewer docs.

John Garvey <jgarvey@qnx.com> wrote:

David Gibbs <> dagibbs@qnx.com> > wrote:
Sergiy Uvarov <> colonel@rts-ukraine.com> > wrote:
To get the rest of your message, you’ll have to look at something like
MsgRead(), which will copy missing stuff out of the sender’s send buffer.

From within a resmgr use the “resmgr_msgread()” routine instead, it
will also take care of combine messages by applying an internal offset
into the message-pass data … refer to the HelpViewer docs.

Is it possible to have a combine message including an IO_MSG type?
For something like an IO_WRITE message, that makes perfect sense – but
for an IO_MSG I wouldn’t have thought a combine was possible… well,
unless they’re hand-crafting combine messages on the client side, too.

So, yeah, resmgr_msgread() is probably the way to go.

-David

Please follow-up to newsgroup, rather than personal email.
David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs wrote:

David Gibbs <> dagibbs@qnx.com> > wrote:

Sergiy Uvarov <> colonel@rts-ukraine.com> > wrote:


And, since the srcmsglen isn’t valid, you’ll have to put information in
the message header as to the amount of data actually to be handled (or
to know the amount based on the type of message.)


Or, instead of calling dispatch_create(), you may be able to do the
following (not verified vs 6.2.1A, but works in 6.3.0, undocumented
extension of the resource manager API, use at your own risk):

/* prototype the function to make compiler happy */
dispatch_t * _dispatch_create(int chid, int flags );

/* we used to call dispatch_create /
/
dpp = dispatch_create(); */

/* now we create a channel with the expected flags, and our length requesting
flags set */
chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN );
dpp = _dispatch_create( chid, 0 );


As a side note, for anyone using name_attach():

chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN | _NTO_CHF_COID_DISCONNECT );
dpp = _dispatch_create( chid, 0 );
attach = name_attach( dpp, “name_to_register”, 0 );

Will get you the flags you want for your name_attach()'d
channel.

-David

David, could you give us some more information about srcmsglen and the
_NTO_CHF_SENDER_LEN flag? The docs say srcmsglen isn’t valid unless
_NTO_CHF_SENDER_LEN was set when ChannelCreate was called, and yet I
haven’t been able to find a case in my (resource manager based) apps
where it isn’t valid. Does that mean that dispatch_create now sets the
flag, or that sometimes it’s valid and sometimes it isn’t; and if the
latter, what is the controlling factor? In fact, why is there the
option to make srcmsglen invalid in the first place? Is there an
inordinate overhead associated with setting _NTO_CHF_SENDER_LEN?

If it IS still necessary to use _dispatch_create, what about the case of
_NTO_CHF_COID_DISCONNECT? The old, outdated CVS code indicates that the
_DISPATCH_CHANNEL_COIDDEATH flag should be included in the
_dispatch_create flags in that case; is that no longer true?

Murf

John A. Murphy <murf@perftech.com> wrote:

David Gibbs wrote:
David Gibbs <> dagibbs@qnx.com> > wrote:

Sergiy Uvarov <> colonel@rts-ukraine.com> > wrote:


And, since the srcmsglen isn’t valid, you’ll have to put information in
the message header as to the amount of data actually to be handled (or
to know the amount based on the type of message.)


Or, instead of calling dispatch_create(), you may be able to do the
following (not verified vs 6.2.1A, but works in 6.3.0, undocumented
extension of the resource manager API, use at your own risk):

/* prototype the function to make compiler happy */
dispatch_t * _dispatch_create(int chid, int flags );

/* we used to call dispatch_create /
/
dpp = dispatch_create(); */

/* now we create a channel with the expected flags, and our length requesting
flags set */
chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN );
dpp = _dispatch_create( chid, 0 );


As a side note, for anyone using name_attach():

chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN | _NTO_CHF_COID_DISCONNECT );
dpp = _dispatch_create( chid, 0 );
attach = name_attach( dpp, “name_to_register”, 0 );

Will get you the flags you want for your name_attach()'d
channel.

-David

David, could you give us some more information about srcmsglen and the
_NTO_CHF_SENDER_LEN flag? The docs say srcmsglen isn’t valid unless
_NTO_CHF_SENDER_LEN was set when ChannelCreate was called, and yet I
haven’t been able to find a case in my (resource manager based) apps
where it isn’t valid. Does that mean that dispatch_create now sets the
flag, or that sometimes it’s valid and sometimes it isn’t; and if the
latter, what is the controlling factor? In fact, why is there the
option to make srcmsglen invalid in the first place? Is there an
inordinate overhead associated with setting _NTO_CHF_SENDER_LEN?

From my testing – non-resmgr based – if you don’t set SENDER_LEN
flag, and you use MsgSend() it will be fine; if you don’t set SENDER_LEN
and you use MsgSendv(), then the length you are given will be the length
of the FIRST iov passed to MsgSendv(). In many cases (e.g. handling
a write() message) this will not be what you want. Setting SENDER_LEN
asks the kernel to walk all the iovs, adding the size of each, to give
you the length value – normally it doesn’t do this work.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs wrote:

John A. Murphy <> murf@perftech.com> > wrote:

David Gibbs wrote:

David Gibbs <> dagibbs@qnx.com> > wrote:


Sergiy Uvarov <> colonel@rts-ukraine.com> > wrote:


And, since the srcmsglen isn’t valid, you’ll have to put information in
the message header as to the amount of data actually to be handled (or
to know the amount based on the type of message.)


Or, instead of calling dispatch_create(), you may be able to do the
following (not verified vs 6.2.1A, but works in 6.3.0, undocumented
extension of the resource manager API, use at your own risk):

/* prototype the function to make compiler happy */
dispatch_t * _dispatch_create(int chid, int flags );

/* we used to call dispatch_create /
/
dpp = dispatch_create(); */

/* now we create a channel with the expected flags, and our length requesting
flags set */
chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN );
dpp = _dispatch_create( chid, 0 );


As a side note, for anyone using name_attach():

chid = ChannelCreate( _NTO_CHF_UNBLOCK | _NTO_CHF_DISCONNECT |
_NTO_CHF_SENDER_LEN | _NTO_CHF_REPLY_LEN | _NTO_CHF_COID_DISCONNECT );
dpp = _dispatch_create( chid, 0 );
attach = name_attach( dpp, “name_to_register”, 0 );

Will get you the flags you want for your name_attach()'d
channel.

-David


David, could you give us some more information about srcmsglen and the
_NTO_CHF_SENDER_LEN flag? The docs say srcmsglen isn’t valid unless
_NTO_CHF_SENDER_LEN was set when ChannelCreate was called, and yet I
haven’t been able to find a case in my (resource manager based) apps
where it isn’t valid. Does that mean that dispatch_create now sets the
flag, or that sometimes it’s valid and sometimes it isn’t; and if the
latter, what is the controlling factor? In fact, why is there the
option to make srcmsglen invalid in the first place? Is there an
inordinate overhead associated with setting _NTO_CHF_SENDER_LEN?


From my testing – non-resmgr based – if you don’t set SENDER_LEN
flag, and you use MsgSend() it will be fine; if you don’t set SENDER_LEN
and you use MsgSendv(), then the length you are given will be the length
of the FIRST iov passed to MsgSendv(). In many cases (e.g. handling
a write() message) this will not be what you want. Setting SENDER_LEN
asks the kernel to walk all the iovs, adding the size of each, to give
you the length value – normally it doesn’t do this work.

-David

Ah, that explains why I’ve never been able to make it fail!

Thanks for the help!

Murf