summaryrefslogtreecommitdiffstats
path: root/src/iperf_pthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/iperf_pthread.c')
-rw-r--r--src/iperf_pthread.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/iperf_pthread.c b/src/iperf_pthread.c
new file mode 100644
index 0000000..ea4918b
--- /dev/null
+++ b/src/iperf_pthread.c
@@ -0,0 +1,40 @@
+#include "iperf_config.h"
+
+#if defined(HAVE_PTHREAD) && defined(__ANDROID__)
+
+/* Workaround for `pthread_cancel()` in Android, using `pthread_kill()` instead,
+ * as Android NDK does not support `pthread_cancel()`.
+ */
+
+#include <signal.h>
+#include "iperf_pthread.h"
+
+int pthread_setcanceltype(int type, int *oldtype) { return 0; }
+int pthread_setcancelstate(int state, int *oldstate) { return 0; }
+int pthread_cancel(pthread_t thread_id) {
+ int status;
+ if ((status = iperf_set_thread_exit_handler()) == 0) {
+ status = pthread_kill(thread_id, SIGUSR1);
+ }
+ return status;
+}
+
+void iperf_thread_exit_handler(int sig)
+{
+ pthread_exit(0);
+}
+
+int iperf_set_thread_exit_handler() {
+ int rc;
+ struct sigaction actions;
+
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = iperf_thread_exit_handler;
+
+ rc = sigaction(SIGUSR1, &actions, NULL);
+ return rc;
+}
+
+#endif // defined(HAVE_PTHREAD) && defined(__ANDROID__)