| 20 | namespace phxsqlproxy { |
| 21 | |
| 22 | int RoutineConnectWithTimeout(int fd, const struct sockaddr *address, socklen_t address_len, |
| 23 | int timeout_ms) { |
| 24 | assert(IsNonBlock(fd)); |
| 25 | //1.sys call |
| 26 | int ret = connect(fd, address, address_len); |
| 27 | |
| 28 | //2.wait |
| 29 | int pollret = 0; |
| 30 | struct pollfd pf = { 0 }; |
| 31 | |
| 32 | for (int i = 0; i < 3; i++) //25s * 3 = 75s |
| 33 | { |
| 34 | memset(&pf, 0, sizeof(pf)); |
| 35 | pf.fd = fd; |
| 36 | pf.events = (POLLOUT | POLLERR | POLLHUP); |
| 37 | |
| 38 | pollret = poll(&pf, 1, timeout_ms); |
| 39 | |
| 40 | if (1 == pollret) { |
| 41 | break; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | if (pf.revents & POLLOUT) //connect succ |
| 46 | { |
| 47 | errno = 0; |
| 48 | return 0; |
| 49 | } |
| 50 | |
| 51 | //3.set errno |
| 52 | int err = 0; |
| 53 | socklen_t errlen = sizeof(err); |
| 54 | getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen); |
| 55 | if (err) { |
| 56 | errno = err; |
| 57 | } else { |
| 58 | errno = ETIMEDOUT; |
| 59 | } |
| 60 | return ret; |
| 61 | } |
| 62 | |
| 63 | int RoutineReadWithTimeout(int source_fd, char * buf, int buf_size, int timeout_ms) { |
| 64 | assert(IsNonBlock(source_fd)); |
no test coverage detected