Skip to content

Commit 07c6bee

Browse files
committed
Merge branch 'unstable' of github.com:/antirez/redis into unstable
2 parents b407590 + 4016155 commit 07c6bee

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

src/config.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ void setproctitle(const char *fmt, ...);
133133
/* Byte ordering detection */
134134
#include <sys/types.h> /* This will likely define BYTE_ORDER */
135135

136+
/* Define redis_sendfile. */
137+
#if defined(__linux__) || (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_5))
138+
#define HAVE_SENDFILE 1
139+
ssize_t redis_sendfile(int out_fd, int in_fd, off_t offset, size_t count);
140+
#endif
141+
136142
#ifndef BYTE_ORDER
137143
#if (BSD >= 199103)
138144
# include <machine/endian.h>

src/replication.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -973,10 +973,41 @@ void removeRDBUsedToSyncReplicas(void) {
973973
}
974974
}
975975

976+
#if HAVE_SENDFILE
977+
/* Implements redis_sendfile to transfer data between file descriptors and
978+
* avoid transferring data to and from user space.
979+
*
980+
* The function prototype is just like sendfile(2) on Linux. in_fd is a file
981+
* descriptor opened for reading and out_fd is a descriptor opened for writing.
982+
* offset specifies where to start reading data from in_fd. count is the number
983+
* of bytes to copy between the file descriptors.
984+
*
985+
* The return value is the number of bytes written to out_fd, if the transfer
986+
* was successful. On error, -1 is returned, and errno is set appropriately. */
987+
ssize_t redis_sendfile(int out_fd, int in_fd, off_t offset, size_t count) {
988+
#if defined(__linux__)
989+
#include <sys/sendfile.h>
990+
return sendfile(out_fd, in_fd, &offset, count);
991+
992+
#elif defined(__APPLE__)
993+
off_t len = count;
994+
/* Notice that it may return -1 and errno is set to EAGAIN even if some
995+
* bytes have been sent successfully and the len argument is set correctly
996+
* when using a socket marked for non-blocking I/O. */
997+
if (sendfile(in_fd, out_fd, offset, &len, NULL, 0) == -1 &&
998+
errno != EAGAIN) return -1;
999+
else
1000+
return (ssize_t)len;
1001+
1002+
#endif
1003+
errno = ENOSYS;
1004+
return -1;
1005+
}
1006+
#endif
1007+
9761008
void sendBulkToSlave(connection *conn) {
9771009
client *slave = connGetPrivateData(conn);
978-
char buf[PROTO_IOBUF_LEN];
979-
ssize_t nwritten, buflen;
1010+
ssize_t nwritten;
9801011

9811012
/* Before sending the RDB file, we send the preamble as configured by the
9821013
* replication process. Currently the preamble is just the bulk count of
@@ -1002,6 +1033,21 @@ void sendBulkToSlave(connection *conn) {
10021033
}
10031034

10041035
/* If the preamble was already transferred, send the RDB bulk data. */
1036+
#if HAVE_SENDFILE
1037+
if ((nwritten = redis_sendfile(conn->fd,slave->repldbfd,
1038+
slave->repldboff,PROTO_IOBUF_LEN)) == -1)
1039+
{
1040+
if (errno != EAGAIN) {
1041+
serverLog(LL_WARNING,"Sendfile error sending DB to replica: %s",
1042+
strerror(errno));
1043+
freeClient(slave);
1044+
}
1045+
return;
1046+
}
1047+
#else
1048+
ssize_t buflen;
1049+
char buf[PROTO_IOBUF_LEN];
1050+
10051051
lseek(slave->repldbfd,slave->repldboff,SEEK_SET);
10061052
buflen = read(slave->repldbfd,buf,PROTO_IOBUF_LEN);
10071053
if (buflen <= 0) {
@@ -1018,6 +1064,7 @@ void sendBulkToSlave(connection *conn) {
10181064
}
10191065
return;
10201066
}
1067+
#endif
10211068
slave->repldboff += nwritten;
10221069
server.stat_net_output_bytes += nwritten;
10231070
if (slave->repldboff == slave->repldbsize) {

0 commit comments

Comments
 (0)