diff options
Diffstat (limited to 'examples/redis-unstable/src/syncio.c')
| -rw-r--r-- | examples/redis-unstable/src/syncio.c | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/examples/redis-unstable/src/syncio.c b/examples/redis-unstable/src/syncio.c deleted file mode 100644 index fc1f553..0000000 --- a/examples/redis-unstable/src/syncio.c +++ /dev/null | |||
| @@ -1,125 +0,0 @@ | |||
| 1 | /* Synchronous socket and file I/O operations useful across the core. | ||
| 2 | * | ||
| 3 | * Copyright (c) 2009-Present, Redis Ltd. | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Licensed under your choice of (a) the Redis Source Available License 2.0 | ||
| 7 | * (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the | ||
| 8 | * GNU Affero General Public License v3 (AGPLv3). | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include "server.h" | ||
| 12 | |||
| 13 | /* ----------------- Blocking sockets I/O with timeouts --------------------- */ | ||
| 14 | |||
| 15 | /* Redis performs most of the I/O in a nonblocking way, with the exception | ||
| 16 | * of the SYNC command where the slave does it in a blocking way, and | ||
| 17 | * the MIGRATE command that must be blocking in order to be atomic from the | ||
| 18 | * point of view of the two instances (one migrating the key and one receiving | ||
| 19 | * the key). This is why need the following blocking I/O functions. | ||
| 20 | * | ||
| 21 | * All the functions take the timeout in milliseconds. */ | ||
| 22 | |||
| 23 | #define SYNCIO__RESOLUTION 10 /* Resolution in milliseconds */ | ||
| 24 | |||
| 25 | /* Write the specified payload to 'fd'. If writing the whole payload will be | ||
| 26 | * done within 'timeout' milliseconds the operation succeeds and 'size' is | ||
| 27 | * returned. Otherwise the operation fails, -1 is returned, and an unspecified | ||
| 28 | * partial write could be performed against the file descriptor. */ | ||
| 29 | ssize_t syncWrite(int fd, char *ptr, ssize_t size, long long timeout) { | ||
| 30 | ssize_t nwritten, ret = size; | ||
| 31 | long long start = mstime(); | ||
| 32 | long long remaining = timeout; | ||
| 33 | |||
| 34 | while(1) { | ||
| 35 | long long wait = (remaining > SYNCIO__RESOLUTION) ? | ||
| 36 | remaining : SYNCIO__RESOLUTION; | ||
| 37 | long long elapsed; | ||
| 38 | |||
| 39 | /* Optimistically try to write before checking if the file descriptor | ||
| 40 | * is actually writable. At worst we get EAGAIN. */ | ||
| 41 | nwritten = write(fd,ptr,size); | ||
| 42 | if (nwritten == -1) { | ||
| 43 | if (errno != EAGAIN) return -1; | ||
| 44 | } else { | ||
| 45 | ptr += nwritten; | ||
| 46 | size -= nwritten; | ||
| 47 | } | ||
| 48 | if (size == 0) return ret; | ||
| 49 | |||
| 50 | /* Wait */ | ||
| 51 | aeWait(fd,AE_WRITABLE,wait); | ||
| 52 | elapsed = mstime() - start; | ||
| 53 | if (elapsed >= timeout) { | ||
| 54 | errno = ETIMEDOUT; | ||
| 55 | return -1; | ||
| 56 | } | ||
| 57 | remaining = timeout - elapsed; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | /* Read the specified amount of bytes from 'fd'. If all the bytes are read | ||
| 62 | * within 'timeout' milliseconds the operation succeed and 'size' is returned. | ||
| 63 | * Otherwise the operation fails, -1 is returned, and an unspecified amount of | ||
| 64 | * data could be read from the file descriptor. */ | ||
| 65 | ssize_t syncRead(int fd, char *ptr, ssize_t size, long long timeout) { | ||
| 66 | ssize_t nread, totread = 0; | ||
| 67 | long long start = mstime(); | ||
| 68 | long long remaining = timeout; | ||
| 69 | |||
| 70 | if (size == 0) return 0; | ||
| 71 | while(1) { | ||
| 72 | long long wait = (remaining > SYNCIO__RESOLUTION) ? | ||
| 73 | remaining : SYNCIO__RESOLUTION; | ||
| 74 | long long elapsed; | ||
| 75 | |||
| 76 | /* Optimistically try to read before checking if the file descriptor | ||
| 77 | * is actually readable. At worst we get EAGAIN. */ | ||
| 78 | nread = read(fd,ptr,size); | ||
| 79 | if (nread == 0) return -1; /* short read. */ | ||
| 80 | if (nread == -1) { | ||
| 81 | if (errno != EAGAIN) return -1; | ||
| 82 | } else { | ||
| 83 | ptr += nread; | ||
| 84 | size -= nread; | ||
| 85 | totread += nread; | ||
| 86 | } | ||
| 87 | if (size == 0) return totread; | ||
| 88 | |||
| 89 | /* Wait */ | ||
| 90 | aeWait(fd,AE_READABLE,wait); | ||
| 91 | elapsed = mstime() - start; | ||
| 92 | if (elapsed >= timeout) { | ||
| 93 | errno = ETIMEDOUT; | ||
| 94 | return -1; | ||
| 95 | } | ||
| 96 | remaining = timeout - elapsed; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | /* Read a line making sure that every char will not require more than 'timeout' | ||
| 101 | * milliseconds to be read. | ||
| 102 | * | ||
| 103 | * On success the number of bytes read is returned, otherwise -1. | ||
| 104 | * On success the string is always correctly terminated with a 0 byte. */ | ||
| 105 | ssize_t syncReadLine(int fd, char *ptr, ssize_t size, long long timeout) { | ||
| 106 | ssize_t nread = 0; | ||
| 107 | |||
| 108 | size--; | ||
| 109 | while(size) { | ||
| 110 | char c; | ||
| 111 | |||
| 112 | if (syncRead(fd,&c,1,timeout) == -1) return -1; | ||
| 113 | if (c == '\n') { | ||
| 114 | *ptr = '\0'; | ||
| 115 | if (nread && *(ptr-1) == '\r') *(ptr-1) = '\0'; | ||
| 116 | return nread; | ||
| 117 | } else { | ||
| 118 | *ptr++ = c; | ||
| 119 | *ptr = '\0'; | ||
| 120 | nread++; | ||
| 121 | } | ||
| 122 | size--; | ||
| 123 | } | ||
| 124 | return nread; | ||
| 125 | } | ||
