From 12de56d09f34360b97cfbd61920fc253eb34349d Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Sun, 10 Jun 2012 17:12:58 +0200 Subject: [PATCH] FileSendChunked(): replace sendfile by splice() FileSendChunked+FileRecvChunked: handle situations in which the first splice reads more then the second can send. --- libcitadel/lib/libcitadel.h | 1 + libcitadel/lib/stringbuf.c | 55 +++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 3eee3728f..4258341c1 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -255,6 +255,7 @@ typedef struct __fd_iobuffer { IOBuffer *IOB; int OtherFD; int SplicePipe[2]; + int PipeSize; long TotalSendSize; long TotalSentAlready; long ChunkSize; diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index 359538d96..79b5f5d2f 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -3909,17 +3909,38 @@ void FDIOBufferDelete(FDIOBuffer *FDB) int FileSendChunked(FDIOBuffer *FDB, const char **Err) { + ssize_t sent, pipesize; #ifdef LINUX_SPLICE - ssize_t sent; - sent = sendfile(FDB->IOB->fd, FDB->OtherFD, &FDB->TotalSentAlready, FDB->ChunkSendRemain); + if (FDB->PipeSize == 0) + { + pipesize = splice(FDB->OtherFD, + &FDB->TotalSentAlready, + FDB->SplicePipe[1], + NULL, + FDB->ChunkSendRemain, + SPLICE_F_MOVE); + + if (pipesize == -1) + { + *Err = strerror(errno); + return pipesize; + } + FDB->PipeSize = pipesize; + } + sent = splice(FDB->SplicePipe[0], + NULL, + FDB->IOB->fd, + NULL, + FDB->PipeSize, + SPLICE_F_MORE | SPLICE_F_MOVE | SPLICE_F_NONBLOCK); if (sent == -1) { *Err = strerror(errno); return sent; } + FDB->PipeSize -= sent; FDB->ChunkSendRemain -= sent; - FDB->TotalSentAlready += sent; - return FDB->ChunkSendRemain; + return sent; #else char *pRead; @@ -3956,18 +3977,21 @@ int FileRecvChunked(FDIOBuffer *FDB, const char **Err) ssize_t sent, pipesize; #ifdef LINUX_SPLICE - - pipesize = splice(FDB->IOB->fd, - NULL, - FDB->SplicePipe[1], - NULL, - FDB->ChunkSendRemain, - SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK); - - if (pipesize == -1) + if (FDB->PipeSize == 0) { - *Err = strerror(errno); - return pipesize; + pipesize = splice(FDB->IOB->fd, + NULL, + FDB->SplicePipe[1], + NULL, + FDB->ChunkSendRemain, + SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK); + + if (pipesize == -1) + { + *Err = strerror(errno); + return pipesize; + } + FDB->PipeSize = pipesize; } sent = splice(FDB->SplicePipe[0], @@ -3982,6 +4006,7 @@ int FileRecvChunked(FDIOBuffer *FDB, const char **Err) *Err = strerror(errno); return sent; } + FDB->PipeSize -= sent; FDB->ChunkSendRemain -= sent; return sent; #else -- 2.30.2