Skip to content

Commit

Permalink
Improve error handling.
Browse files Browse the repository at this point in the history
While here, also fix a place where we forgot to join after cancel.
  • Loading branch information
bmah888 committed Nov 8, 2023
1 parent 6bcbb20 commit a360f70
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/iperf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,9 @@ enum {
IEBINDDEVNOSUPPORT = 146, // `ip%%dev` is not supported as system does not support bind to device
IEHOSTDEV = 147, // host device name (ip%%<dev>) is supported (and required) only for IPv6 link-local address
IESETUSERTIMEOUT = 148, // Unable to set TCP USER_TIMEOUT (check perror)
IEPTHREADCREATE=150, // Unable to create thread (check perror)
IEPTHREADCANCEL=151, // Unable to cancel thread (check perror)
IEPTHREADJOIN=152, // Unable to join thread (check perror)
/* Stream errors */
IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror)
Expand Down
25 changes: 19 additions & 6 deletions src/iperf_client_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ iperf_run_client(struct iperf_test * test)
int64_t t_usecs;
int64_t timeout_us;
int64_t rcv_timeout_us;
int i_errno_save;

if (NULL == test)
{
Expand Down Expand Up @@ -639,7 +640,8 @@ iperf_run_client(struct iperf_test * test)

SLIST_FOREACH(sp, &test->streams, streams) {
if (pthread_create(&(sp->thr), &attr, &iperf_client_worker_start, sp) != 0) {
perror("pthread_create");
i_errno = IEPTHREADCREATE;
goto cleanup_and_fail;
}
if (test->debug_level >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Thread FD %d created\n", sp->socket);
Expand Down Expand Up @@ -699,7 +701,12 @@ iperf_run_client(struct iperf_test * test)
SLIST_FOREACH(sp, &test->streams, streams) {
if (sp->sender) {
if (pthread_cancel(sp->thr) != 0) {
perror("pthread_cancel");
i_errno = IEPTHREADCANCEL;
goto cleanup_and_fail;
}
if (pthread_join(sp->thr, NULL) != 0) {
i_errno = IEPTHREADJOIN;
goto cleanup_and_fail;
}
sp->thr = 0;
if (test->debug_level >= DEBUG_LEVEL_INFO) {
Expand Down Expand Up @@ -741,10 +748,12 @@ iperf_run_client(struct iperf_test * test)
SLIST_FOREACH(sp, &test->streams, streams) {
if (!sp->sender) {
if (pthread_cancel(sp->thr) != 0) {
perror("pthread_cancel");
i_errno = IEPTHREADCANCEL;
goto cleanup_and_fail;
}
if (pthread_join(sp->thr, NULL) != 0) {
perror("pthread_join");
i_errno = IEPTHREADJOIN;
goto cleanup_and_fail;
}
sp->thr = 0;
if (test->debug_level >= DEBUG_LEVEL_INFO) {
Expand All @@ -770,12 +779,15 @@ iperf_run_client(struct iperf_test * test)

cleanup_and_fail:
/* Cancel all threads */
i_errno_save = i_errno;
SLIST_FOREACH(sp, &test->streams, streams) {
if (pthread_cancel(sp->thr) != 0) {
perror("pthread_cancel");
i_errno = IEPTHREADCANCEL;
iperf_err(test, "cleanup_and_fail - %s", iperf_strerror(i_errno));
}
if (pthread_join(sp->thr, NULL) != 0) {
perror("pthread_join");
i_errno = IEPTHREADCANCEL;
iperf_err(test, "cleanup_and_fail - %s", iperf_strerror(i_errno));
}
if (test->debug >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Thread FD %d cancelled\n", sp->socket);
Expand All @@ -784,6 +796,7 @@ iperf_run_client(struct iperf_test * test)
if (test->debug_level >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "All threads cancelled\n");
}
i_errno = i_errno_save;

iperf_client_end(test);
if (test->json_output) {
Expand Down
12 changes: 12 additions & 0 deletions src/iperf_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,18 @@ iperf_strerror(int int_errno)
snprintf(errstr, len, "unable to set TCP USER_TIMEOUT");
perr = 1;
break;
case IEPTHREADCREATE:
snprintf(errstr, len, "unable to create thread");
perr = 1;
break;
case IEPTHREADCANCEL:
snprintf(errstr, len, "unable to cancel thread");
perr = 1;
break;
case IEPTHREADJOIN:
snprintf(errstr, len, "unable to join thread");
perr = 1;
break;
default:
snprintf(errstr, len, "int_errno=%d", int_errno);
perr = 1;
Expand Down
13 changes: 10 additions & 3 deletions src/iperf_server_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,17 +402,22 @@ cleanup_server(struct iperf_test *test)
struct iperf_stream *sp;

/* Cancel threads */
int i_errno_save = i_errno;
SLIST_FOREACH(sp, &test->streams, streams) {
if (pthread_cancel(sp->thr) != 0) {
perror("pthread_cancel");
i_errno = IEPTHREADCANCEL;
iperf_err(test, "cleanup_server - %s", iperf_strerror(i_errno));
}
if (pthread_join(sp->thr, NULL) != 0) {
perror("pthread_join");
i_errno = IEPTHREADJOIN;
iperf_err(test, "cleanup_server - %s", iperf_strerror(i_errno));
}
if (test->debug >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Thread FD %d cancelled\n", sp->socket);
}
}
i_errno = i_errno_save;

if (test->debug_level >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "All threads cancelled\n");
}
Expand Down Expand Up @@ -839,7 +844,9 @@ iperf_run_server(struct iperf_test *test)

SLIST_FOREACH(sp, &test->streams, streams) {
if (pthread_create(&(sp->thr), &attr, &iperf_server_worker_start, sp) != 0) {
perror("pthread_create");
i_errno = IEPTHREADCREATE;
cleanup_server(test);
return -1;
}
if (test->debug_level >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Thread FD %d created\n", sp->socket);
Expand Down

0 comments on commit a360f70

Please sign in to comment.