added mio_foff_t.

adding sendfile support to the core
This commit is contained in:
2020-07-17 15:28:18 +00:00
parent 7adf19f01d
commit e439c29cb8
6 changed files with 115 additions and 28 deletions

View File

@ -1549,30 +1549,98 @@ enqueue_completed_write:
return __enqueue_completed_write(dev, len, wrctx, dstaddr);
}
static int __dev_sendfile (mio_dev_t* dev, mio_syshnd_t in_fd, mio_uintmax_t offset, mio_iolen_t len, const mio_ntime_t* tmout, void* wrctx, const mio_devaddr_t* dstaddr)
static int __dev_sendfile (mio_dev_t* dev, mio_syshnd_t in_fd, mio_foff_t foff, mio_iolen_t len, const mio_ntime_t* tmout, void* wrctx)
{
#if 1
mio_t* mio = dev->mio;
mio_foff_t uoff;
mio_iolen_t urem, ulen;
int x;
if (dev->dev_cap & MIO_DEV_CAP_OUT_CLOSED)
{
mio_seterrbfmt (mio, MIO_ENOCAPA, "unable to write to closed device");
mio_seterrbfmt (mio, MIO_ENOCAPA, "unable to sendfile to closed device");
return -1;
}
uoff = foff;
urem = len;
if (!MIO_WQ_IS_EMPTY(&dev->wq))
{
/* if the writing queue is not empty, enqueue this request immediately */
/* the writing queue is not empty.
* enqueue this request immediately */
goto enqueue_data;
}
return 1;
if (dev->dev_cap & MIO_DEV_CAP_STREAM)
{
/* use the do..while() loop to be able to send a zero-length data */
do
{
ulen = urem;
x = dev->dev_mth->sendfile(dev, in_fd, foff, &ulen);
if (x <= -1) return -1;
else if (x == 0)
{
/* [NOTE]
* the write queue is empty at this moment. a zero-length
* request for a stream device can still get enqueued if the
* write callback returns 0 though i can't figure out if there
* is a compelling reason to do so
*/
goto enqueue_data; /* enqueue remaining data */
}
else
{
/* the write callback should return at most the number of requested
* bytes. but returning more is harmless as urem is of a signed type.
* for a zero-length request, it's necessary to return at least 1
* to indicate successful acknowlegement. otherwise, it gets enqueued
* as shown in the 'if' block right above. */
urem -= ulen;
uoff += ulen;
}
}
while (urem > 0);
if (len <= 0) /* original length */
{
/* a zero-length writing request is to close the writing end. this causes further write request to fail */
dev->dev_cap |= MIO_DEV_CAP_OUT_CLOSED;
}
/* if i trigger the write completion callback here, the performance
* may increase, but there can be annoying recursion issues if the
* callback requests another writing operation. it's imperative to
* delay the callback until this write function is finished.
* ---> if (dev->dev_evcb->on_write(dev, len, wrctx, dstaddr) <= -1) return -1; */
goto enqueue_completed_write;
}
else
{
mio_seterrbfmt (mio, MIO_ENOCAPA, "unable to sendfile over a non-stream device");
return -1;
}
return 1; /* written immediately and called on_write callback. but this line will never be reached */
enqueue_data:
/*return __enqueue_pending_write(dev, len, urem, iov, iovcnt, index, tmout, wrctx, dstaddr);*/
#if 0
iov.iov_ptr = (void*)uptr;
iov.iov_len = urem;
return __enqueue_pending_write(dev, len, urem, &iov, 1, 0, tmout, wrctx, dstaddr);
#else
/* TODO: */
return -1;
#endif
enqueue_completed_write:
/*return __enqueue_completed_write(dev, len, wrctx, dstaddr);*/
return __enqueue_completed_write(dev, len, wrctx, dstaddr);
#else
return 0;
#endif
}
int mio_dev_write (mio_dev_t* dev, const void* data, mio_iolen_t len, void* wrctx, const mio_devaddr_t* dstaddr)