|
36 | 36 | #include <stdlib.h> |
37 | 37 | #include <stdio.h> |
38 | 38 | #include <errno.h> |
| 39 | +#include <unistd.h> |
| 40 | +#include <sys/poll.h> |
| 41 | +#include <sys/eventfd.h> |
39 | 42 | #include <sys/types.h> |
40 | 43 | #include <sys/socket.h> |
41 | 44 | #include <netdb.h> |
@@ -151,6 +154,7 @@ struct rping_cb { |
151 | 154 | int validate; /* validate ping data */ |
152 | 155 |
|
153 | 156 | /* CM stuff */ |
| 157 | + int eventfd; |
154 | 158 | pthread_t cmthread; |
155 | 159 | struct rdma_event_channel *cm_channel; |
156 | 160 | struct rdma_cm_id *cm_id; /* connection on client side,*/ |
@@ -666,18 +670,36 @@ static void *cm_thread(void *arg) |
666 | 670 | { |
667 | 671 | struct rping_cb *cb = arg; |
668 | 672 | struct rdma_cm_event *event; |
| 673 | + struct pollfd pfds[2]; |
669 | 674 | int ret; |
670 | 675 |
|
| 676 | + pfds[0].fd = cb->eventfd; |
| 677 | + pfds[0].events = POLLIN; |
| 678 | + pfds[1].fd = cb->cm_channel->fd; |
| 679 | + pfds[1].events = POLLIN; |
| 680 | + |
671 | 681 | while (1) { |
672 | | - ret = rdma_get_cm_event(cb->cm_channel, &event); |
673 | | - if (ret) { |
674 | | - perror("rdma_get_cm_event"); |
| 682 | + ret = poll(pfds, 2, -1); |
| 683 | + if (ret == -1 && errno != EINTR) { |
| 684 | + perror("poll failed"); |
675 | 685 | exit(ret); |
| 686 | + } else if (ret < 1) |
| 687 | + continue; |
| 688 | + |
| 689 | + if (pfds[0].revents & POLLIN) |
| 690 | + return NULL; |
| 691 | + |
| 692 | + if (pfds[1].revents & POLLIN) { |
| 693 | + ret = rdma_get_cm_event(cb->cm_channel, &event); |
| 694 | + if (ret) { |
| 695 | + perror("rdma_get_cm_event"); |
| 696 | + exit(ret); |
| 697 | + } |
| 698 | + ret = rping_cma_event_handler(event->id, event); |
| 699 | + rdma_ack_cm_event(event); |
| 700 | + if (ret) |
| 701 | + exit(ret); |
676 | 702 | } |
677 | | - ret = rping_cma_event_handler(event->id, event); |
678 | | - rdma_ack_cm_event(event); |
679 | | - if (ret) |
680 | | - exit(ret); |
681 | 703 | } |
682 | 704 | } |
683 | 705 |
|
@@ -1279,6 +1301,7 @@ int main(int argc, char *argv[]) |
1279 | 1301 | int op; |
1280 | 1302 | int ret = 0; |
1281 | 1303 | int persistent_server = 0; |
| 1304 | + const uint64_t efdw = 1; |
1282 | 1305 |
|
1283 | 1306 | cb = malloc(sizeof(*cb)); |
1284 | 1307 | if (!cb) |
@@ -1366,6 +1389,13 @@ int main(int argc, char *argv[]) |
1366 | 1389 | goto out; |
1367 | 1390 | } |
1368 | 1391 |
|
| 1392 | + cb->eventfd = eventfd(0, EFD_NONBLOCK); |
| 1393 | + if (cb->eventfd == -1) { |
| 1394 | + perror("Could not create event FD"); |
| 1395 | + ret = errno; |
| 1396 | + goto out; |
| 1397 | + } |
| 1398 | + |
1369 | 1399 | cb->cm_channel = create_event_channel(); |
1370 | 1400 | if (!cb->cm_channel) { |
1371 | 1401 | ret = errno; |
@@ -1397,6 +1427,10 @@ int main(int argc, char *argv[]) |
1397 | 1427 | DEBUG_LOG("destroy cm_id %p\n", cb->cm_id); |
1398 | 1428 | rdma_destroy_id(cb->cm_id); |
1399 | 1429 | out2: |
| 1430 | + if (write(cb->eventfd, &efdw, sizeof(efdw)) != sizeof(efdw)) |
| 1431 | + fprintf(stderr, "Failed to signal CM thread\n"); |
| 1432 | + |
| 1433 | + pthread_join(cb->cmthread, NULL); |
1400 | 1434 | rdma_destroy_event_channel(cb->cm_channel); |
1401 | 1435 | out: |
1402 | 1436 | free(cb); |
|
0 commit comments