关键词搜索

源码搜索 ×
×

漫话Redis源码之一百二十一

发布2022-06-19浏览386次

详情内容

rio的connwrite和connread该怎么写呢?折腾我很久,参考开源代码后,搞定:

  1. static size_t rioConnWrite(rio *r, const void *buf, size_t len) {
  2. UNUSED(r);
  3. UNUSED(buf);
  4. UNUSED(len);
  5. return 0; /* Error, this target does not yet support writing. */
  6. }
  7. /* Returns 1 or 0 for success/failure. */
  8. static size_t rioConnRead(rio *r, void *buf, size_t len) {
  9. size_t avail = sdslen(r->io.conn.buf)-r->io.conn.pos;
  10. /* If the buffer is too small for the entire request: realloc. */
  11. if (sdslen(r->io.conn.buf) + sdsavail(r->io.conn.buf) < len)
  12. r->io.conn.buf = sdsMakeRoomFor(r->io.conn.buf, len - sdslen(r->io.conn.buf));
  13. /* If the remaining unused buffer is not large enough: memmove so that we
  14. * can read the rest. */
  15. if (len > avail && sdsavail(r->io.conn.buf) < len - avail) {
  16. sdsrange(r->io.conn.buf, r->io.conn.pos, -1);
  17. r->io.conn.pos = 0;
  18. }
  19. /* If we don't already have all the data in the sds, read more */
  20. while (len > sdslen(r->io.conn.buf) - r->io.conn.pos) {
  21. size_t buffered = sdslen(r->io.conn.buf) - r->io.conn.pos;
  22. size_t needs = len - buffered;
  23. /* Read either what's missing, or PROTO_IOBUF_LEN, the bigger of
  24. * the two. */
  25. size_t toread = needs < PROTO_IOBUF_LEN ? PROTO_IOBUF_LEN: needs;
  26. if (toread > sdsavail(r->io.conn.buf)) toread = sdsavail(r->io.conn.buf);
  27. if (r->io.conn.read_limit != 0 &&
  28. r->io.conn.read_so_far + buffered + toread > r->io.conn.read_limit)
  29. {
  30. /* Make sure the caller didn't request to read past the limit.
  31. * If they didn't we'll buffer till the limit, if they did, we'll
  32. * return an error. */
  33. if (r->io.conn.read_limit >= r->io.conn.read_so_far + len)
  34. toread = r->io.conn.read_limit - r->io.conn.read_so_far - buffered;
  35. else {
  36. errno = EOVERFLOW;
  37. return 0;
  38. }
  39. }
  40. int retval = connRead(r->io.conn.conn,
  41. (char*)r->io.conn.buf + sdslen(r->io.conn.buf),
  42. toread);
  43. if (retval <= 0) {
  44. if (errno == EWOULDBLOCK) errno = ETIMEDOUT;
  45. return 0;
  46. }
  47. sdsIncrLen(r->io.conn.buf, retval);
  48. }
  49. memcpy(buf, (char*)r->io.conn.buf + r->io.conn.pos, len);
  50. r->io.conn.read_so_far += len;
  51. r->io.conn.pos += len;
  52. return len;
  53. }

相关技术文章

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

提示信息

×

选择支付方式

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