Skip to content

Commit a360f70

Browse files
committed
Improve error handling.
While here, also fix a place where we forgot to join after cancel.
1 parent 6bcbb20 commit a360f70

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

src/iperf_api.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,9 @@ enum {
457457
IEBINDDEVNOSUPPORT = 146, // `ip%%dev` is not supported as system does not support bind to device
458458
IEHOSTDEV = 147, // host device name (ip%%<dev>) is supported (and required) only for IPv6 link-local address
459459
IESETUSERTIMEOUT = 148, // Unable to set TCP USER_TIMEOUT (check perror)
460+
IEPTHREADCREATE=150, // Unable to create thread (check perror)
461+
IEPTHREADCANCEL=151, // Unable to cancel thread (check perror)
462+
IEPTHREADJOIN=152, // Unable to join thread (check perror)
460463
/* Stream errors */
461464
IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror)
462465
IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror)

src/iperf_client_api.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ iperf_run_client(struct iperf_test * test)
535535
int64_t t_usecs;
536536
int64_t timeout_us;
537537
int64_t rcv_timeout_us;
538+
int i_errno_save;
538539

539540
if (NULL == test)
540541
{
@@ -639,7 +640,8 @@ iperf_run_client(struct iperf_test * test)
639640

640641
SLIST_FOREACH(sp, &test->streams, streams) {
641642
if (pthread_create(&(sp->thr), &attr, &iperf_client_worker_start, sp) != 0) {
642-
perror("pthread_create");
643+
i_errno = IEPTHREADCREATE;
644+
goto cleanup_and_fail;
643645
}
644646
if (test->debug_level >= DEBUG_LEVEL_INFO) {
645647
iperf_printf(test, "Thread FD %d created\n", sp->socket);
@@ -699,7 +701,12 @@ iperf_run_client(struct iperf_test * test)
699701
SLIST_FOREACH(sp, &test->streams, streams) {
700702
if (sp->sender) {
701703
if (pthread_cancel(sp->thr) != 0) {
702-
perror("pthread_cancel");
704+
i_errno = IEPTHREADCANCEL;
705+
goto cleanup_and_fail;
706+
}
707+
if (pthread_join(sp->thr, NULL) != 0) {
708+
i_errno = IEPTHREADJOIN;
709+
goto cleanup_and_fail;
703710
}
704711
sp->thr = 0;
705712
if (test->debug_level >= DEBUG_LEVEL_INFO) {
@@ -741,10 +748,12 @@ iperf_run_client(struct iperf_test * test)
741748
SLIST_FOREACH(sp, &test->streams, streams) {
742749
if (!sp->sender) {
743750
if (pthread_cancel(sp->thr) != 0) {
744-
perror("pthread_cancel");
751+
i_errno = IEPTHREADCANCEL;
752+
goto cleanup_and_fail;
745753
}
746754
if (pthread_join(sp->thr, NULL) != 0) {
747-
perror("pthread_join");
755+
i_errno = IEPTHREADJOIN;
756+
goto cleanup_and_fail;
748757
}
749758
sp->thr = 0;
750759
if (test->debug_level >= DEBUG_LEVEL_INFO) {
@@ -770,12 +779,15 @@ iperf_run_client(struct iperf_test * test)
770779

771780
cleanup_and_fail:
772781
/* Cancel all threads */
782+
i_errno_save = i_errno;
773783
SLIST_FOREACH(sp, &test->streams, streams) {
774784
if (pthread_cancel(sp->thr) != 0) {
775-
perror("pthread_cancel");
785+
i_errno = IEPTHREADCANCEL;
786+
iperf_err(test, "cleanup_and_fail - %s", iperf_strerror(i_errno));
776787
}
777788
if (pthread_join(sp->thr, NULL) != 0) {
778-
perror("pthread_join");
789+
i_errno = IEPTHREADCANCEL;
790+
iperf_err(test, "cleanup_and_fail - %s", iperf_strerror(i_errno));
779791
}
780792
if (test->debug >= DEBUG_LEVEL_INFO) {
781793
iperf_printf(test, "Thread FD %d cancelled\n", sp->socket);
@@ -784,6 +796,7 @@ iperf_run_client(struct iperf_test * test)
784796
if (test->debug_level >= DEBUG_LEVEL_INFO) {
785797
iperf_printf(test, "All threads cancelled\n");
786798
}
799+
i_errno = i_errno_save;
787800

788801
iperf_client_end(test);
789802
if (test->json_output) {

src/iperf_error.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,18 @@ iperf_strerror(int int_errno)
470470
snprintf(errstr, len, "unable to set TCP USER_TIMEOUT");
471471
perr = 1;
472472
break;
473+
case IEPTHREADCREATE:
474+
snprintf(errstr, len, "unable to create thread");
475+
perr = 1;
476+
break;
477+
case IEPTHREADCANCEL:
478+
snprintf(errstr, len, "unable to cancel thread");
479+
perr = 1;
480+
break;
481+
case IEPTHREADJOIN:
482+
snprintf(errstr, len, "unable to join thread");
483+
perr = 1;
484+
break;
473485
default:
474486
snprintf(errstr, len, "int_errno=%d", int_errno);
475487
perr = 1;

src/iperf_server_api.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,17 +402,22 @@ cleanup_server(struct iperf_test *test)
402402
struct iperf_stream *sp;
403403

404404
/* Cancel threads */
405+
int i_errno_save = i_errno;
405406
SLIST_FOREACH(sp, &test->streams, streams) {
406407
if (pthread_cancel(sp->thr) != 0) {
407-
perror("pthread_cancel");
408+
i_errno = IEPTHREADCANCEL;
409+
iperf_err(test, "cleanup_server - %s", iperf_strerror(i_errno));
408410
}
409411
if (pthread_join(sp->thr, NULL) != 0) {
410-
perror("pthread_join");
412+
i_errno = IEPTHREADJOIN;
413+
iperf_err(test, "cleanup_server - %s", iperf_strerror(i_errno));
411414
}
412415
if (test->debug >= DEBUG_LEVEL_INFO) {
413416
iperf_printf(test, "Thread FD %d cancelled\n", sp->socket);
414417
}
415418
}
419+
i_errno = i_errno_save;
420+
416421
if (test->debug_level >= DEBUG_LEVEL_INFO) {
417422
iperf_printf(test, "All threads cancelled\n");
418423
}
@@ -839,7 +844,9 @@ iperf_run_server(struct iperf_test *test)
839844

840845
SLIST_FOREACH(sp, &test->streams, streams) {
841846
if (pthread_create(&(sp->thr), &attr, &iperf_server_worker_start, sp) != 0) {
842-
perror("pthread_create");
847+
i_errno = IEPTHREADCREATE;
848+
cleanup_server(test);
849+
return -1;
843850
}
844851
if (test->debug_level >= DEBUG_LEVEL_INFO) {
845852
iperf_printf(test, "Thread FD %d created\n", sp->socket);

0 commit comments

Comments
 (0)