if (rs->cm_id->recv_cq_channel)
ret = fcntl(rs->cm_id->recv_cq_channel->fd, F_SETFL, arg);
- if (!ret && rs->state != rs_connected)
+ if (!ret && rs->state < rs_connected)
ret = fcntl(rs->cm_id->channel->fd, F_SETFL, arg);
return ret;
}
}
- if (rs->state == rs_connected) {
+ if (rs->state != rs_error) {
while (!ret && rcnt--)
ret = rdma_post_recvv(rs->cm_id, NULL, NULL, 0);
if (!ret) {
ibv_ack_cq_events(rs->cm_id->recv_cq, 1);
rs->cq_armed = 0;
- } else if (errno != EAGAIN && rs->state == rs_connected) {
+ } else if (errno != EAGAIN) {
rs->state = rs_error;
}
}
/* fall through */
case rs_connected:
+ case rs_shutdown_rd:
+ case rs_shutdown_wr:
case rs_disconnected:
case rs_error:
rs_process_cq(rs, nonblock, test);
revents |= POLLIN;
if ((events & POLLOUT) && rs_can_send(rs))
revents |= POLLOUT;
- if (rs->state == rs_disconnected)
- revents |= POLLHUP;
- else if (rs->state == rs_error)
- revents |= POLLERR;
+ if (rs->state > rs_connected) {
+ if (rs->state == rs_error)
+ revents |= POLLERR;
+ else
+ revents |= POLLHUP;
+ }
return revents;
case rs_connect_error:
struct rsocket *rs;
int ret = 0;
+ if (how == SHUT_RD)
+ return 0;
+
rs = idm_at(&idm, socket);
if (rs->fd_flags & O_NONBLOCK)
rs_set_nonblocking(rs, 0);
if (rs->state == rs_connected) {
- rs->state = rs_disconnected;
+ if (how == SHUT_RDWR)
+ rs->state = rs_disconnected;
if (!rs_can_send_ctrl(rs)) {
ret = rs_process_cq(rs, 0, rs_can_send_ctrl);
if (ret)
if (!rs_all_sends_done(rs) && rs->state != rs_error)
rs_process_cq(rs, 0, rs_all_sends_done);
+ if ((rs->fd_flags & O_NONBLOCK) && (how == SHUT_WR))
+ rs_set_nonblocking(rs, 1);
+
return 0;
}