Skip to content

Commit a40c9b3

Browse files
committed
Make thread shutdown more tolerant.
We now handle the case where the worker threads exited on their own accord before the main thread had a chance to cancel them. While here, tweaked some of the error messages. Fixes IPERF-179.
1 parent 2e80758 commit a40c9b3

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

src/iperf_client_api.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -704,16 +704,23 @@ iperf_run_client(struct iperf_test * test)
704704
(test->settings->blocks != 0 && (test->blocks_sent >= test->settings->blocks ||
705705
test->blocks_received >= test->settings->blocks)))) {
706706

707-
/* Cancel sender threads */
707+
/* Cancel outstanding sender threads */
708708
SLIST_FOREACH(sp, &test->streams, streams) {
709709
if (sp->sender) {
710+
int rc;
710711
sp->done = 1;
711-
if (pthread_cancel(sp->thr) != 0) {
712+
rc = pthread_cancel(sp->thr);
713+
if (rc != 0 && rc != ESRCH) {
712714
i_errno = IEPTHREADCANCEL;
715+
errno = rc;
716+
iperf_err(test, "sender cancel in pthread_cancel - %s", iperf_strerror(i_errno));
713717
goto cleanup_and_fail;
714718
}
715-
if (pthread_join(sp->thr, NULL) != 0) {
719+
rc = pthread_join(sp->thr, NULL);
720+
if (rc != 0 && rc != ESRCH) {
716721
i_errno = IEPTHREADJOIN;
722+
errno = rc;
723+
iperf_err(test, "sender cancel in pthread_join - %s", iperf_strerror(i_errno));
717724
goto cleanup_and_fail;
718725
}
719726
if (test->debug_level >= DEBUG_LEVEL_INFO) {
@@ -735,16 +742,23 @@ iperf_run_client(struct iperf_test * test)
735742
}
736743
}
737744

738-
/* Cancel receiver threads */
745+
/* Cancel outstanding receiver threads */
739746
SLIST_FOREACH(sp, &test->streams, streams) {
740747
if (!sp->sender) {
748+
int rc;
741749
sp->done = 1;
742-
if (pthread_cancel(sp->thr) != 0) {
750+
rc = pthread_cancel(sp->thr);
751+
if (rc != 0 && rc != ESRCH) {
743752
i_errno = IEPTHREADCANCEL;
753+
errno = rc;
754+
iperf_err(test, "receiver cancel in pthread_cancel - %s", iperf_strerror(i_errno));
744755
goto cleanup_and_fail;
745756
}
746-
if (pthread_join(sp->thr, NULL) != 0) {
757+
rc = pthread_join(sp->thr, NULL);
758+
if (rc != 0 && rc != ESRCH) {
747759
i_errno = IEPTHREADJOIN;
760+
errno = rc;
761+
iperf_err(test, "receiver cancel in pthread_join - %s", iperf_strerror(i_errno));
748762
goto cleanup_and_fail;
749763
}
750764
if (test->debug_level >= DEBUG_LEVEL_INFO) {
@@ -769,17 +783,22 @@ iperf_run_client(struct iperf_test * test)
769783
return 0;
770784

771785
cleanup_and_fail:
772-
/* Cancel all threads */
786+
/* Cancel all outstanding threads */
773787
i_errno_save = i_errno;
774788
SLIST_FOREACH(sp, &test->streams, streams) {
775789
sp->done = 1;
776-
if (pthread_cancel(sp->thr) != 0) {
790+
int rc;
791+
rc = pthread_cancel(sp->thr);
792+
if (rc != 0 && rc != ESRCH) {
777793
i_errno = IEPTHREADCANCEL;
778-
iperf_err(test, "cleanup_and_fail in cancel - %s", iperf_strerror(i_errno));
794+
errno = rc;
795+
iperf_err(test, "cleanup_and_fail in pthread_cancel - %s", iperf_strerror(i_errno));
779796
}
780-
if (pthread_join(sp->thr, NULL) != 0) {
797+
rc = pthread_join(sp->thr, NULL);
798+
if (rc != 0 && rc != ESRCH) {
781799
i_errno = IEPTHREADJOIN;
782-
iperf_err(test, "cleanup_and_fail in join - %s", iperf_strerror(i_errno));
800+
errno = rc;
801+
iperf_err(test, "cleanup_and_fail in pthread_join - %s", iperf_strerror(i_errno));
783802
}
784803
if (test->debug >= DEBUG_LEVEL_INFO) {
785804
iperf_printf(test, "Thread FD %d stopped\n", sp->socket);

src/iperf_server_api.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,22 @@ cleanup_server(struct iperf_test *test)
415415
{
416416
struct iperf_stream *sp;
417417

418-
/* Cancel threads */
418+
/* Cancel outstanding threads */
419419
int i_errno_save = i_errno;
420420
SLIST_FOREACH(sp, &test->streams, streams) {
421+
int rc;
421422
sp->done = 1;
422-
if (pthread_cancel(sp->thr) != 0) {
423+
rc = pthread_cancel(sp->thr);
424+
if (rc != 0 && rc != ESRCH) {
423425
i_errno = IEPTHREADCANCEL;
424-
iperf_err(test, "cleanup_server in cancel - %s", iperf_strerror(i_errno));
426+
errno = rc;
427+
iperf_err(test, "cleanup_server in pthread_cancel - %s", iperf_strerror(i_errno));
425428
}
426-
if (pthread_join(sp->thr, NULL) != 0) {
429+
rc = pthread_join(sp->thr, NULL);
430+
if (rc != 0 && rc != ESRCH) {
427431
i_errno = IEPTHREADJOIN;
428-
iperf_err(test, "cleanup_server in join - %s", iperf_strerror(i_errno));
432+
errno = rc;
433+
iperf_err(test, "cleanup_server in pthread_join - %s", iperf_strerror(i_errno));
429434
}
430435
if (test->debug >= DEBUG_LEVEL_INFO) {
431436
iperf_printf(test, "Thread FD %d stopped\n", sp->socket);

0 commit comments

Comments
 (0)