Skip to content

Commit

Permalink
Make thread shutdown more tolerant.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bmah888 committed Nov 8, 2023
1 parent 2e80758 commit a40c9b3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
41 changes: 30 additions & 11 deletions src/iperf_client_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,16 +704,23 @@ iperf_run_client(struct iperf_test * test)
(test->settings->blocks != 0 && (test->blocks_sent >= test->settings->blocks ||
test->blocks_received >= test->settings->blocks)))) {

/* Cancel sender threads */
/* Cancel outstanding sender threads */
SLIST_FOREACH(sp, &test->streams, streams) {
if (sp->sender) {
int rc;
sp->done = 1;
if (pthread_cancel(sp->thr) != 0) {
rc = pthread_cancel(sp->thr);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADCANCEL;
errno = rc;
iperf_err(test, "sender cancel in pthread_cancel - %s", iperf_strerror(i_errno));
goto cleanup_and_fail;
}
if (pthread_join(sp->thr, NULL) != 0) {
rc = pthread_join(sp->thr, NULL);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADJOIN;
errno = rc;
iperf_err(test, "sender cancel in pthread_join - %s", iperf_strerror(i_errno));
goto cleanup_and_fail;
}
if (test->debug_level >= DEBUG_LEVEL_INFO) {
Expand All @@ -735,16 +742,23 @@ iperf_run_client(struct iperf_test * test)
}
}

/* Cancel receiver threads */
/* Cancel outstanding receiver threads */
SLIST_FOREACH(sp, &test->streams, streams) {
if (!sp->sender) {
int rc;
sp->done = 1;
if (pthread_cancel(sp->thr) != 0) {
rc = pthread_cancel(sp->thr);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADCANCEL;
errno = rc;
iperf_err(test, "receiver cancel in pthread_cancel - %s", iperf_strerror(i_errno));
goto cleanup_and_fail;
}
if (pthread_join(sp->thr, NULL) != 0) {
rc = pthread_join(sp->thr, NULL);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADJOIN;
errno = rc;
iperf_err(test, "receiver cancel in pthread_join - %s", iperf_strerror(i_errno));
goto cleanup_and_fail;
}
if (test->debug_level >= DEBUG_LEVEL_INFO) {
Expand All @@ -769,17 +783,22 @@ iperf_run_client(struct iperf_test * test)
return 0;

cleanup_and_fail:
/* Cancel all threads */
/* Cancel all outstanding threads */
i_errno_save = i_errno;
SLIST_FOREACH(sp, &test->streams, streams) {
sp->done = 1;
if (pthread_cancel(sp->thr) != 0) {
int rc;
rc = pthread_cancel(sp->thr);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADCANCEL;
iperf_err(test, "cleanup_and_fail in cancel - %s", iperf_strerror(i_errno));
errno = rc;
iperf_err(test, "cleanup_and_fail in pthread_cancel - %s", iperf_strerror(i_errno));
}
if (pthread_join(sp->thr, NULL) != 0) {
rc = pthread_join(sp->thr, NULL);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADJOIN;
iperf_err(test, "cleanup_and_fail in join - %s", iperf_strerror(i_errno));
errno = rc;
iperf_err(test, "cleanup_and_fail in pthread_join - %s", iperf_strerror(i_errno));
}
if (test->debug >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Thread FD %d stopped\n", sp->socket);
Expand Down
15 changes: 10 additions & 5 deletions src/iperf_server_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,17 +415,22 @@ cleanup_server(struct iperf_test *test)
{
struct iperf_stream *sp;

/* Cancel threads */
/* Cancel outstanding threads */
int i_errno_save = i_errno;
SLIST_FOREACH(sp, &test->streams, streams) {
int rc;
sp->done = 1;
if (pthread_cancel(sp->thr) != 0) {
rc = pthread_cancel(sp->thr);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADCANCEL;
iperf_err(test, "cleanup_server in cancel - %s", iperf_strerror(i_errno));
errno = rc;
iperf_err(test, "cleanup_server in pthread_cancel - %s", iperf_strerror(i_errno));
}
if (pthread_join(sp->thr, NULL) != 0) {
rc = pthread_join(sp->thr, NULL);
if (rc != 0 && rc != ESRCH) {
i_errno = IEPTHREADJOIN;
iperf_err(test, "cleanup_server in join - %s", iperf_strerror(i_errno));
errno = rc;
iperf_err(test, "cleanup_server in pthread_join - %s", iperf_strerror(i_errno));
}
if (test->debug >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Thread FD %d stopped\n", sp->socket);
Expand Down

0 comments on commit a40c9b3

Please sign in to comment.