/* Synchronous socket and file I/O operations useful across the core.** Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>* All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions are met:** * Redistributions of source code must retain the above copyright notice,* this list of conditions and the following disclaimer.* * Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* * Neither the name of Redis nor the names of its contributors may be used* to endorse or promote products derived from this software without* specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE* POSSIBILITY OF SUCH DAMAGE.*/#include "server.h"/* ----------------- Blocking sockets I/O with timeouts --------------------- *//* Redis performs most of the I/O in a nonblocking way, with the exception* of the SYNC command where the slave does it in a blocking way, and* the MIGRATE command that must be blocking in order to be atomic from the* point of view of the two instances (one migrating the key and one receiving* the key). This is why need the following blocking I/O functions.** All the functions take the timeout in milliseconds. */#define SYNCIO__RESOLUTION 10 /* Resolution in milliseconds *//* Write the specified payload to 'fd'. If writing the whole payload will be* done within 'timeout' milliseconds the operation succeeds and 'size' is* returned. Otherwise the operation fails, -1 is returned, and an unspecified* partial write could be performed against the file descriptor. */ssize_t syncWrite(int fd, char *ptr, ssize_t size, PORT_LONGLONG timeout) {ssize_t nwritten, ret = size;PORT_LONGLONG start = mstime();PORT_LONGLONG remaining = timeout;while(1) {PORT_LONGLONG wait = (remaining > SYNCIO__RESOLUTION) ?remaining : SYNCIO__RESOLUTION;PORT_LONGLONG elapsed;/* Optimistically try to write before checking if the file descriptor* is actually writable. At worst we get EAGAIN. */nwritten = write(fd,ptr,size);if (nwritten == -1) {if (errno != EAGAIN) return -1;} else {ptr += nwritten;size -= nwritten;}if (size == 0) return ret;/* Wait */aeWait(fd,AE_WRITABLE,wait);elapsed = mstime() - start;if (elapsed >= timeout) {errno = ETIMEDOUT;return -1;}remaining = timeout - elapsed;}}/* Read the specified amount of bytes from 'fd'. If all the bytes are read* within 'timeout' milliseconds the operation succeed and 'size' is returned.* Otherwise the operation fails, -1 is returned, and an unspecified amount of* data could be read from the file descriptor. */ssize_t syncRead(int fd, char *ptr, ssize_t size, PORT_LONGLONG timeout) {ssize_t nread, totread = 0;PORT_LONGLONG start = mstime();PORT_LONGLONG remaining = timeout;if (size == 0) return 0;while(1) {PORT_LONGLONG wait = (remaining > SYNCIO__RESOLUTION) ?remaining : SYNCIO__RESOLUTION;PORT_LONGLONG elapsed;/* Optimistically try to read before checking if the file descriptor* is actually readable. At worst we get EAGAIN. */nread = read(fd,ptr,size);if (nread == 0) return -1; /* short read. */if (nread == -1) {if (errno != EAGAIN) return -1;} else {ptr += nread;size -= nread;totread += nread;}if (size == 0) return totread;/* Wait */aeWait(fd,AE_READABLE,wait);elapsed = mstime() - start;if (elapsed >= timeout) {errno = ETIMEDOUT;return -1;}remaining = timeout - elapsed;}}/* Read a line making sure that every char will not require more than 'timeout'* milliseconds to be read.** On success the number of bytes read is returned, otherwise -1.* On success the string is always correctly terminated with a 0 byte. */ssize_t syncReadLine(int fd, char *ptr, ssize_t size, PORT_LONGLONG timeout) {ssize_t nread = 0;size--;while(size) {char c;if (syncRead(fd,&c,1,timeout) == -1) return -1;if (c == '\n') {*ptr = '0円';if (nread && *(ptr-1) == '\r') *(ptr-1) = '0円';return nread;} else {*ptr++ = c;*ptr = '0円';nread++;}size--;}return nread;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。