drm_hwcomposer: add optional timeout for WaitForSignalOrExitLocked
Change-Id: I5beef0833cc0a384aa76e821694183e024a8850c
diff --git a/worker.cpp b/worker.cpp
index e169911..1cebedc 100644
--- a/worker.cpp
+++ b/worker.cpp
@@ -23,11 +23,14 @@
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/signal.h>
+#include <time.h>
#include <cutils/log.h>
namespace android {
+static const int64_t kBillion = 1000000000LL;
+
Worker::Worker(const char *name, int priority)
: name_(name), priority_(priority), exit_(false), initialized_(false) {
}
@@ -42,7 +45,10 @@
}
int Worker::InitWorker() {
- int ret = pthread_cond_init(&cond_, NULL);
+ pthread_condattr_t cond_attr;
+ pthread_condattr_init(&cond_attr);
+ pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
+ int ret = pthread_cond_init(&cond_, &cond_attr);
if (ret) {
ALOGE("Failed to int thread %s condition %d", name_.c_str(), ret);
return ret;
@@ -128,11 +134,25 @@
return exit_ret;
}
-int Worker::WaitForSignalOrExitLocked() {
+int Worker::WaitForSignalOrExitLocked(int64_t max_nanoseconds) {
if (exit_)
return -EINTR;
- int ret = pthread_cond_wait(&cond_, &lock_);
+ int ret = 0;
+ if (max_nanoseconds < 0) {
+ ret = pthread_cond_wait(&cond_, &lock_);
+ } else {
+ struct timespec abs_deadline;
+ ret = clock_gettime(CLOCK_MONOTONIC, &abs_deadline);
+ if (ret)
+ return ret;
+ int64_t nanos = (int64_t)abs_deadline.tv_nsec + max_nanoseconds;
+ abs_deadline.tv_sec += nanos / kBillion;
+ abs_deadline.tv_nsec = nanos % kBillion;
+ ret = pthread_cond_timedwait(&cond_, &lock_, &abs_deadline);
+ if (ret == ETIMEDOUT)
+ ret = -ETIMEDOUT;
+ }
if (exit_)
return -EINTR;
diff --git a/worker.h b/worker.h
index 492693c..7015178 100644
--- a/worker.h
+++ b/worker.h
@@ -18,6 +18,7 @@
#define ANDROID_WORKER_H_
#include <pthread.h>
+#include <stdint.h>
#include <string>
namespace android {
@@ -46,10 +47,12 @@
virtual void Routine() = 0;
/*
- * Must be called with the lock acquired.
- * Returns -EINTR if interrupted by exit request
+ * Must be called with the lock acquired. max_nanoseconds may be negative to
+ * indicate infinite timeout, otherwise it indicates the maximum time span to
+ * wait for a signal before returning.
+ * Returns -EINTR if interrupted by exit request, or -ETIMEDOUT if timed out
*/
- int WaitForSignalOrExitLocked();
+ int WaitForSignalOrExitLocked(int64_t max_nanoseconds = -1);
private:
static void *InternalRoutine(void *worker);