Problems with "divides" IO_WRITE-Messages

Hello,

I write a ResMsg. The ResMgr handles IO_WRITE-Msg. But the Problem is, if the write data block is bigger than ? KB, the write function which is called by an application will be divided in more IO_WRITE messages.

But I must know the beginning and ending of the data transfer between application an my ResMgr via write().

The best way to solve my problem is to switch off the dividing, but I think it is never possible.

Now my questions are:

  • Can I change the maximum message block size?
  • It is possible to figure out, is write() complete

Thx
Andreas Hauser

AFAIK write() should not change the size of the request. Maybe you are talking about fwrite(), if it is you can switch to using write() or turn buffering off with setvbuff().

I beleive old version (<6.2) may slit the size but from memory starting with 6.2.1 size of message is limited by RAM or 2G which ever comes first ;-)

Are you sure you are handling the write properly in the resgmr. If the data receive is bigger then the initial resmgr buffer size you need to call manual get the extra data.

Thank you mario for your answer.

I can’t influence usage of write/fwrite :confused:

Okay, I think the 2GB-limit is okay for my device.

I hope :slight_smile:. I have take the example (see below) of ResMgr and io_write() form “Writing a Resource Manager” to “emulate” my problem. It will be the same. IO_WRITE-Msgs are divided into 4K Buffers by ResMgrLib. Now, I have found following comment in io_write(). I delete it before I read it ;(

Okay, I sounds possible that I have to do it manually to get the extra data. Can you give me a short hint? Must I use MsgReceive…?

I’m not sure that I understand the comment right. Mean it

  • the sender (application) don’t send the data complete before the ResMgrLib transmit it to the device

or

  • the sender send data complete to ResMgrLib, but ResMgrLib divided into a multiple buffer msg (IOV), with the result that io_write() is multible called by ResMgrLib.

The only thing I must known is the total payload size of multiple buffer msg.

Thx.
Andreas Hauser


int io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)              
{                                                                                 
    int     status;                                                               
    char    *buf;       
                                                                                  
    if ((status = iofunc_write_verify(ctp, msg, ocb, NULL)) != EOK)               
        return (status);                                                          
                                                                                  
    if (msg->i.xtype & _IO_XTYPE_MASK != _IO_XTYPE_NONE)                          
        return(ENOSYS);                                                           
                                                                                  
    /* set up the number of bytes (returned by client's write()) */
                                                                                  
    _IO_SET_WRITE_NBYTES (ctp, msg->i.nbytes);                                    
                                                                                  
    buf = (char *) malloc(msg->i.nbytes + 1);                                     
    if (buf == NULL)                                                              
        return(ENOMEM);                                                           
                                                                                  
    resmgr_msgread(ctp, buf, msg->i.nbytes, sizeof(msg->i));                   
    printf ("Received %d bytes = \n", msg -> i.nbytes);                  
    free(buf);                                                                    
                                                                                  
    if (msg->i.nbytes > 0)                                                        
        ocb->attr->flags |= IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;                
                                                                                  
    return (_RESMGR_NPARTS (0));                                                  
}     

The piece of code you posted looks good to me, resmgr_msgread will read the extra data that doesn’t fit in the buffer allocated by the resmgr frame.

I’m fairly sure the resmgr doesn’t slip write request on its own. What is important is the number of writen byte returned to the application. In the code you posted “nbytes” is returned which is the size of the request, that’s good. It’s legal to return a size smaller then what the client requested.

Now if the application is using fwrite and you cannot change it, you are screwed. There is nothing you can do in the resgmr to go around that.

I’m almost certain your problem in is the client not in the resmgr.

Your are absulotly right!!!

I tried it out with write() and fwrite() & setvbuf().

write() send it in one piece.
fwrite() send it in one or more “setvbuf()-size” big pieces.

When I use “cat” like “cat HugeFile> /dev/mydriver” it use fwrite() with a 4K buffer :frowning:. That is my problem - you said it:

But now I have a clear reason of my problem and a solution ;) I write into the docu “don’t use fwrite() with out setvbuf()”.

Thank you very much.

Kind regards,
Andreas Hauser

It is possible to differ an open() connect request from a fopen()?

From the resource manager? I don’t think so.