io_write / message format/contents of the reply message

Hello,

what is the correct format/contents of a reply message if a worker
thread of a resource manager has to do a delayed reponse? What must
be supplied in status parameter of the MsgRepy() call ?

The nbytes field my reply message (io_write_t) is set to the
number of written bytes.

A ‘cat file.txt > /dev/xyz’ works fine, but the termination message
is: ‘–stdio–: No error’.

A ‘cp file.txt /dev/xyz’ sends constantly the same message to the
resource manager after replying :frowning:

Armin

There’s no reply structure for a write, just:

MsgReply(rcvid, nbytes, NULL, 0);

The status (here nbytes) is returned to the client’s MsgSend()
which in turn is returned out of the write().

-seanb

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

: Hello,

: what is the correct format/contents of a reply message if a worker
: thread of a resource manager has to do a delayed reponse? What must
: be supplied in status parameter of the MsgRepy() call ?

: The nbytes field my reply message (io_write_t) is set to the
: number of written bytes.

: A ‘cat file.txt > /dev/xyz’ works fine, but the termination message
: is: ‘–stdio–: No error’.

: A ‘cp file.txt /dev/xyz’ sends constantly the same message to the
: resource manager after replying :frowning:

: Armin

Sean Boudreau wrote:

There’s no reply structure for a write, just:

MsgReply(rcvid, nbytes, NULL, 0);

The status (here nbytes) is returned to the client’s MsgSend()
which in turn is returned out of the write().

IMHO … this is also correct for a delayed reponse for a io_read.

Please add it to the resource manager documentation!!

BTW … are there any ioctl()-Calls supported by the devc-yxz
drivers ??

Thanks

Armin

-seanb

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

: Hello,

: what is the correct format/contents of a reply message if a worker
: thread of a resource manager has to do a delayed reponse? What must
: be supplied in status parameter of the MsgRepy() call ?

: The nbytes field my reply message (io_write_t) is set to the
: number of written bytes.

: A ‘cat file.txt > /dev/xyz’ works fine, but the termination message
: is: ‘–stdio–: No error’.

: A ‘cp file.txt /dev/xyz’ sends constantly the same message to the
: resource manager after replying > :frowning:

: Armin

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

Hello,

what is the correct format/contents of a reply message if a worker
thread of a resource manager has to do a delayed reponse? What must
be supplied in status parameter of the MsgRepy() call ?

Are you talking about the case where somebody said, say, write(4k)
and you can only deal with 1k, say, immediately… and then have to
do more work?

Well, then you have to check:
– has the client opened the fd with O_NONBLOCK?
– if so, reply to the client that you’ve handled 1K
_IO_SET_WRITE_NBYTES( ctp, 1k );
return( _RESMGR_NPARTS(0) );
– if you can’t handle anything, fail the call with EWOULDBLOCK
return( EWOULDBLOCK)
– if you can block the client, you don’t reply:
– store away rcvid & any info you’ll need
return( RESMGR_NOREPLY )

And, in some other code, when you’re done processing, issue a
MsgReply() to the client directly.

But, the basic idea is if you’re going to take time to finish processing
and not do it in the direct call, then you don’t reply to the client until
the work is done.

Hope this helps,

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs wrote:

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

Hello,

what is the correct format/contents of a reply message if a worker
thread of a resource manager has to do a delayed reponse? What must
be supplied in status parameter of the MsgRepy() call ?

Are you talking about the case where somebody said, say, write(4k)
and you can only deal with 1k, say, immediately… and then have to
do more work?

Well, then you have to check:
– has the client opened the fd with O_NONBLOCK?
– if so, reply to the client that you’ve handled 1K
_IO_SET_WRITE_NBYTES( ctp, 1k );
return( _RESMGR_NPARTS(0) );

Does it mean that the client (e.g. cp) will send the rest of the 4k
in messages with the size of 1k … after receiving the first 1k
reply?

– if you can’t handle anything, fail the call with EWOULDBLOCK
return( EWOULDBLOCK)

OK … I will switch from EAGAIN to EWOULDBLOCK.

– if you can block the client, you don’t reply:
– store away rcvid & any info you’ll need
return( RESMGR_NOREPLY )

And, in some other code, when you’re done processing, issue a
MsgReply() to the client directly.

… how to do that MsgReply in the case of a io_write was the
problem.

Armin

But, the basic idea is if you’re going to take time to finish processing
and not do it in the direct call, then you don’t reply to the client until
the work is done.

Hope this helps,

-David

QNX Training Services
dagibbs@qnx.com

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

David Gibbs wrote:


Well, then you have to check:
– has the client opened the fd with O_NONBLOCK?
– if so, reply to the client that you’ve handled 1K
_IO_SET_WRITE_NBYTES( ctp, 1k );
return( _RESMGR_NPARTS(0) );

Does it mean that the client (e.g. cp) will send the rest of the 4k
in messages with the size of 1k … after receiving the first 1k
reply?

The client could, but need not. But, the client should be checking
the return value of write() and if they asked for 4K, and only got
1K written, should try to send the rest of the 4K – either as a 3K
chunk, or as the first 3K of their next 4K chunk. I don’t know how
carefully cp or cat are written – cp may assume this is a “disk full”
situation and fail at that point. (As it is presumed to be writing
to a filesystem, and that would either handle it all, or fail, and
would have O_NONBLOCK set anyway, so would be unlikely to end up in
that situation.)

– if you can’t handle anything, fail the call with EWOULDBLOCK
return( EWOULDBLOCK)

OK … I will switch from EAGAIN to EWOULDBLOCK.

Won’t make any difference, from errno.h :

#define EWOULDBLOCK EAGAIN /* Operation would block */



– if you can block the client, you don’t reply:
– store away rcvid & any info you’ll need
return( RESMGR_NOREPLY )

And, in some other code, when you’re done processing, issue a
MsgReply() to the client directly.

… how to do that MsgReply in the case of a io_write was the
problem.

The status field in the MsgReply becomes the return value from the
clients MsgSendv(), and the write() library routine basically passes
that back up to the client.

The write() library routine basically looks like:

int write( fd, buf,nbytes)
{
iov_t iov[2];
write_hdr hdr;

hdr.nbytes = nbytes;
hdr.type = _IO_WRITE;
SETIOV(&iov[0], &hdr, sizeof(hdr) );
SETIOV(&iov[1], buf, nbytes );

return MsgSendv(fd, iov, 2, NULL, 0 );
}

So, you would:

MsgReply( rcvid, bytes_handled, NULL, 0 );

Once you’ve handled the data.

-David

QNX Training Services
dagibbs@qnx.com

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

Thanks for your detailed answer.

You are welcome.

-David

QNX Training Services
dagibbs@qnx.com

Thanks for your detailed answer.

Armin

David Gibbs wrote:

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

David Gibbs wrote:


Well, then you have to check:
– has the client opened the fd with O_NONBLOCK?
– if so, reply to the client that you’ve handled 1K
_IO_SET_WRITE_NBYTES( ctp, 1k );
return( _RESMGR_NPARTS(0) );

Does it mean that the client (e.g. cp) will send the rest of the 4k
in messages with the size of 1k … after receiving the first 1k
reply?

The client could, but need not. But, the client should be checking
the return value of write() and if they asked for 4K, and only got
1K written, should try to send the rest of the 4K – either as a 3K
chunk, or as the first 3K of their next 4K chunk. I don’t know how
carefully cp or cat are written – cp may assume this is a “disk full”
situation and fail at that point. (As it is presumed to be writing
to a filesystem, and that would either handle it all, or fail, and
would have O_NONBLOCK set anyway, so would be unlikely to end up in
that situation.)

– if you can’t handle anything, fail the call with EWOULDBLOCK
return( EWOULDBLOCK)

OK … I will switch from EAGAIN to EWOULDBLOCK.

Won’t make any difference, from errno.h :

#define EWOULDBLOCK EAGAIN /* Operation would block */

– if you can block the client, you don’t reply:
– store away rcvid & any info you’ll need
return( RESMGR_NOREPLY )

And, in some other code, when you’re done processing, issue a
MsgReply() to the client directly.

… how to do that MsgReply in the case of a io_write was the
problem.

The status field in the MsgReply becomes the return value from the
clients MsgSendv(), and the write() library routine basically passes
that back up to the client.

The write() library routine basically looks like:

int write( fd, buf,nbytes)
{
iov_t iov[2];
write_hdr hdr;

hdr.nbytes = nbytes;
hdr.type = _IO_WRITE;
SETIOV(&iov[0], &hdr, sizeof(hdr) );
SETIOV(&iov[1], buf, nbytes );

return MsgSendv(fd, iov, 2, NULL, 0 );
}

So, you would:

MsgReply( rcvid, bytes_handled, NULL, 0 );

Once you’ve handled the data.

-David

QNX Training Services
dagibbs@qnx.com

Armin Steinhoff <A-Steinhoff@web_.de> wrote:


Sean Boudreau wrote:

There’s no reply structure for a write, just:

MsgReply(rcvid, nbytes, NULL, 0);

The status (here nbytes) is returned to the client’s MsgSend()
which in turn is returned out of the write().



IMHO … this is also correct for a delayed reponse for a io_read.

Please add it to the resource manager documentation!!

It is already there in the “Writing a Resource Manager” book
under the section:
Programmers Guide → Writing a Resource Manager →
Doing your own thing → Different ways of returning/replying.

Though I would suggest that you read the book from start to
finish (WARM that is). We are currently re-factoring this
to make the topics and sections more apparent.

BTW … are there any ioctl()-Calls supported by the devc-yxz
drivers ??

Yes … you will want to take a look at the header file for
the libio-char.a and the header <sys/io-char.h>. This library
is a character device helper library which is not documented
(yet … we don’t have a DDK for character devices yet) which
is why it is only available statically.

Thomas

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

: Hello,

: what is the correct format/contents of a reply message if a worker
: thread of a resource manager has to do a delayed reponse? What must
: be supplied in status parameter of the MsgRepy() call ?

: The nbytes field my reply message (io_write_t) is set to the
: number of written bytes.

: A ‘cat file.txt > /dev/xyz’ works fine, but the termination message
: is: ‘–stdio–: No error’.

: A ‘cp file.txt /dev/xyz’ sends constantly the same message to the
: resource manager after replying > :frowning:

: Armin

Thomas Fletcher wrote:

Armin Steinhoff <A-Steinhoff@web_.de> wrote:

Sean Boudreau wrote:

There’s no reply structure for a write, just:

MsgReply(rcvid, nbytes, NULL, 0);

The status (here nbytes) is returned to the client’s MsgSend()
which in turn is returned out of the write().

IMHO … this is also correct for a delayed reponse for a io_read.

Please add it to the resource manager documentation!!

It is already there in the “Writing a Resource Manager” book
under the section:
Programmers Guide → Writing a Resource Manager –
Doing your own thing → Different ways of returning/replying.

Though I would suggest that you read the book from start to
finish (WARM that is).

OK … show me a single statement about a delayed reply for a
io_write/io_read if it has to be done by a worker thread (and not by
the library)!

The documentation is just incomplete!

We are currently re-factoring this to make the topics and sections more apparent.

… and you have good reasons for it.

BTW … are there any ioctl()-Calls supported by the devc-yxz
drivers ??

Yes … you will want to take a look at the header file for
the libio-char.a and the header <sys/io-char.h>. This library
is a character device helper library which is not documented
(yet … we don’t have a DDK for character devices yet) which
is why it is only available statically.

Are there any plans to build a shared library io-char.so … as
mentioned in the architecture guide ?

Armin