aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/vsock/timeout.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-12-06 23:37:06 +0100
committerIngo Molnar <mingo@kernel.org>2017-12-06 23:37:06 +0100
commitd0300e5e8d2fb74852f8116f26546e12cfa66735 (patch)
treea6580aa74a0ebd7965dbc37767717b4f73dd9d79 /tools/testing/vsock/timeout.c
parentMerge tag 'perf-core-for-mingo-4.16-20171206' of git://git.kernel.org/pub/scm... (diff)
parenttooling/headers: Synchronize updated s390 and x86 UAPI headers (diff)
downloadlinux-d0300e5e8d2fb74852f8116f26546e12cfa66735.tar.gz
linux-d0300e5e8d2fb74852f8116f26546e12cfa66735.zip
Merge branch 'perf/urgent' into perf/core, to pick up fixes and to refresh to v4.15
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/testing/vsock/timeout.c')
-rw-r--r--tools/testing/vsock/timeout.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/tools/testing/vsock/timeout.c b/tools/testing/vsock/timeout.c
new file mode 100644
index 000000000000..c49b3003b2db
--- /dev/null
+++ b/tools/testing/vsock/timeout.c
@@ -0,0 +1,64 @@
+/* Timeout API for single-threaded programs that use blocking
+ * syscalls (read/write/send/recv/connect/accept).
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+/* Use the following pattern:
+ *
+ * timeout_begin(TIMEOUT);
+ * do {
+ * ret = accept(...);
+ * timeout_check("accept");
+ * } while (ret < 0 && ret == EINTR);
+ * timeout_end();
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "timeout.h"
+
+static volatile bool timeout;
+
+/* SIGALRM handler function. Do not use sleep(2), alarm(2), or
+ * setitimer(2) while using this API - they may interfere with each
+ * other.
+ */
+void sigalrm(int signo)
+{
+ timeout = true;
+}
+
+/* Start a timeout. Call timeout_check() to verify that the timeout hasn't
+ * expired. timeout_end() must be called to stop the timeout. Timeouts cannot
+ * be nested.
+ */
+void timeout_begin(unsigned int seconds)
+{
+ alarm(seconds);
+}
+
+/* Exit with an error message if the timeout has expired */
+void timeout_check(const char *operation)
+{
+ if (timeout) {
+ fprintf(stderr, "%s timed out\n", operation);
+ exit(EXIT_FAILURE);
+ }
+}
+
+/* Stop a timeout */
+void timeout_end(void)
+{
+ alarm(0);
+ timeout = false;
+}