关键词搜索

源码搜索 ×
×

漫话Redis源码之十二

发布2021-11-28浏览485次

详情内容

学习网络编程的人,一定要重视基础知识,对于一些特殊的错误也要清楚,比如:EAGAIN

  1. #include "server.h"
  2. /* ----------------- Blocking sockets I/O with timeouts --------------------- */
  3. /* Redis performs most of the I/O in a nonblocking way, with the exception
  4. * of the SYNC command where the slave does it in a blocking way, and
  5. * the MIGRATE command that must be blocking in order to be atomic from the
  6. * point of view of the two instances (one migrating the key and one receiving
  7. * the key). This is why need the following blocking I/O functions.
  8. *
  9. * All the functions take the timeout in milliseconds. */
  10. #define SYNCIO__RESOLUTION 10 /* Resolution in milliseconds */
  11. /* Write the specified payload to 'fd'. If writing the whole payload will be
  12. * done within 'timeout' milliseconds the operation succeeds and 'size' is
  13. * returned. Otherwise the operation fails, -1 is returned, and an unspecified
  14. * partial write could be performed against the file descriptor. */
  15. ssize_t syncWrite(int fd, char *ptr, ssize_t size, long long timeout) {
  16. ssize_t nwritten, ret = size;
  17. long long start = mstime();
  18. long long remaining = timeout;
  19. while(1) {
  20. long long wait = (remaining > SYNCIO__RESOLUTION) ?
  21. remaining : SYNCIO__RESOLUTION;
  22. long long elapsed;
  23. /* Optimistically try to write before checking if the file descriptor
  24. * is actually writable. At worst we get EAGAIN. */
  25. nwritten = write(fd,ptr,size);
  26. if (nwritten == -1) {
  27. if (errno != EAGAIN) return -1;
  28. } else {
  29. ptr += nwritten;
  30. size -= nwritten;
  31. }
  32. if (size == 0) return ret;
  33. /* Wait */
  34. aeWait(fd,AE_WRITABLE,wait);
  35. elapsed = mstime() - start;
  36. if (elapsed >= timeout) {
  37. errno = ETIMEDOUT;
  38. return -1;
  39. }
  40. remaining = timeout - elapsed;
  41. }
  42. }
  43. /* Read the specified amount of bytes from 'fd'. If all the bytes are read
  44. * within 'timeout' milliseconds the operation succeed and 'size' is returned.
  45. * Otherwise the operation fails, -1 is returned, and an unspecified amount of
  46. * data could be read from the file descriptor. */
  47. ssize_t syncRead(int fd, char *ptr, ssize_t size, long long timeout) {
  48. ssize_t nread, totread = 0;
  49. long long start = mstime();
  50. long long remaining = timeout;
  51. if (size == 0) return 0;
  52. while(1) {
  53. long long wait = (remaining > SYNCIO__RESOLUTION) ?
  54. remaining : SYNCIO__RESOLUTION;
  55. long long elapsed;
  56. /* Optimistically try to read before checking if the file descriptor
  57. * is actually readable. At worst we get EAGAIN. */
  58. nread = read(fd,ptr,size);
  59. if (nread == 0) return -1; /* short read. */
  60. if (nread == -1) {
  61. if (errno != EAGAIN) return -1;
  62. } else {
  63. ptr += nread;
  64. size -= nread;
  65. totread += nread;
  66. }
  67. if (size == 0) return totread;
  68. /* Wait */
  69. aeWait(fd,AE_READABLE,wait);
  70. elapsed = mstime() - start;
  71. if (elapsed >= timeout) {
  72. errno = ETIMEDOUT;
  73. return -1;
  74. }
  75. remaining = timeout - elapsed;
  76. }
  77. }
  78. /* Read a line making sure that every char will not require more than 'timeout'
  79. * milliseconds to be read.
  80. *
  81. * On success the number of bytes read is returned, otherwise -1.
  82. * On success the string is always correctly terminated with a 0 byte. */
  83. ssize_t syncReadLine(int fd, char *ptr, ssize_t size, long long timeout) {
  84. ssize_t nread = 0;
  85. size--;
  86. while(size) {
  87. char c;
  88. if (syncRead(fd,&c,1,timeout) == -1) return -1;
  89. if (c == '\n') {
  90. *ptr = '\0';
  91. if (nread && *(ptr-1) == '\r') *(ptr-1) = '\0';
  92. return nread;
  93. } else {
  94. *ptr++ = c;
  95. *ptr = '\0';
  96. nread++;
  97. }
  98. size--;
  99. }
  100. return nread;
  101. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载