FileSendChunked(): replace sendfile by splice()
authorWilfried Goesgens <dothebart@citadel.org>
Sun, 10 Jun 2012 15:12:58 +0000 (17:12 +0200)
committerWilfried Goesgens <dothebart@citadel.org>
Sun, 10 Jun 2012 15:12:58 +0000 (17:12 +0200)
FileSendChunked+FileRecvChunked: handle situations in which the first splice reads more then the second can send.

libcitadel/lib/libcitadel.h
libcitadel/lib/stringbuf.c

index 3eee3728f998e274ea8bc3142b3f7ffa001ac34f..4258341c1eb6be25eb5b12de742549a2997549ce 100644 (file)
@@ -255,6 +255,7 @@ typedef struct __fd_iobuffer {
        IOBuffer *IOB;
        int OtherFD;
        int SplicePipe[2];
+       int PipeSize;
        long TotalSendSize;
        long TotalSentAlready;
        long ChunkSize;
index 359538d9611584c957bd032062ff9840be85607e..79b5f5d2f3ab2116e0d2cd6604bf3db6e60a0f5e 100644 (file)
@@ -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