help-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: libtrivfs/glibc questions


From: Marcus Brinkmann
Subject: Re: libtrivfs/glibc questions
Date: Wed, 3 Jan 2001 18:38:16 +0100
User-agent: Mutt/1.1.4i

On Wed, Jan 03, 2001 at 12:51:44AM +0100, Moritz Schulte wrote:
> Hi,
> 
> can anybody please explain me what this 'data_len' parameter in
> trivfs_S_io_read() trans/hello.c is for?
> Where does it come from?

data_len is the size of the buffer *data (note that data is a pointer to a
buffer pointer, read: an array). You can fill up to data_len bytes in the
buffer *data[0] to *data[data_len - 1].

This is an initial buffer for your convenience. If this is not big enough,
because the amount to read is more than this buffer, you have to allocate a
bigger buffer and fill that. You don't need to release the original buffer,
that is done by the caller. This is what the Hurd manual calls the "usual
Mach buffer-return semantics". I think *data and data_len can both be zero,
which means that you have to allocate the buffer no matter what.

Look how careful hello.c is to follow this scheme:

      /* Possibly allocate a new buffer. */
      if (*data_len < amount)
        *data = (vm_address_t) mmap (0, amount, PROT_READ|PROT_WRITE,
                                     MAP_ANON, 0, 0);

You can find similar constructs everywhere where buffers are passed in MiG
RPCs. (For example, in the pager interface).

The initial size depends on MiG. In my generated code libtrivfs/ioServer.c,
it is 2048 bytes:

/* Routine io_read */
mig_internal void _Xio_read
        (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
{

[...]


        typedef struct {
                mach_msg_header_t Head;
                mach_msg_type_t RetCodeType;
                kern_return_t RetCode;
                mach_msg_type_long_t dataType;
                char data[2048];
        } Reply;

[...]

        mach_msg_type_number_t dataCnt;
        char *dataP;

[...]

        dataP = OutP->data;
        dataCnt = 2048;

        OutP->RetCode = trivfs_S_io_read(io_object, In0P->Head.msgh_reply_port,
                                         
MACH_MSGH_BITS_REPLY(In0P->Head.msgh_bits),
                                         &dataP, &dataCnt, In0P->offset, 
In0P->amount);

[...]
Now, in the above MiG code, the data is inline. If you requested and got
more than 2048 bytes, the data is not send inline. It also says to
deallocate the memory by setting a special flag. MiG checks this by
comparing the pointers (note how it sets the message size accordingly,
either by adding the inline datacount or just adding the size of a pointer):
[...]

        if (dataP != OutP->data) {
                OutP->dataType.msgtl_header.msgt_inline = FALSE;
                OutP->dataType.msgtl_header.msgt_deallocate = TRUE;
                *((char **)OutP->data) = dataP;
                msgh_simple = FALSE;
        }

        OutP->dataType.msgtl_number = dataCnt;
        OutP->Head.msgh_size = 44 + ((OutP->dataType.msgtl_header.msgt_inline) 
? (dataCnt + 3) & ~3
: sizeof(char *));

[...]
}

Hope this helps,
Marcus

-- 
`Rhubarb is no Egyptian god.' Debian http://www.debian.org brinkmd@debian.org
Marcus Brinkmann              GNU    http://www.gnu.org    marcus@gnu.org
Marcus.Brinkmann@ruhr-uni-bochum.de
http://www.marcus-brinkmann.de



reply via email to

[Prev in Thread] Current Thread [Next in Thread]