Loading media/codec2/vndk/C2Fence.cpp +62 −59 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <android-base/unique_fd.h> #include <cutils/native_handle.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <ui/Fence.h> #include <C2FenceFactory.h> Loading Loading @@ -631,26 +632,39 @@ C2Fence _C2FenceFactory::CreateMultiSyncFence( */ class _C2FenceFactory::PipeFenceImpl: public C2Fence::Impl { private: bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp, bool *event) const { // Wait for an event using ::ppoll() and handle any interruptions by signals // (EINTR) by retrying and accounting for time already waited. // Note: while ppoll in theory supports blocking signals, Linux NPTL library does // not allow blocking 2 realtime signals (see man nptl), so we do need to handle // signal interruptions. bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp) const { if (!mValid) { *hangUp = true; return true; return false; } struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; int64_t waitTimeNs = kPipeFenceWaitLimitSecs * 1000000000LL; if (timeoutNs >= 0) { ts.tv_sec = int(timeoutNs / 1000000000); ts.tv_nsec = timeoutNs % 1000000000; waitTimeNs = timeoutNs; } else { ALOGD("polling for indefinite duration requested, but changed to wait for %d sec", kPipeFenceWaitLimitSecs); ts.tv_sec = kPipeFenceWaitLimitSecs; ts.tv_nsec = 0; } int64_t startTsNs = android::elapsedRealtimeNano(); int64_t elapsedTsNs = 0; int tryNum = 0; int noEvent = 0; do { struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; ts.tv_sec = int((waitTimeNs - elapsedTsNs) / 1000000000); ts.tv_nsec = (waitTimeNs - elapsedTsNs) % 1000000000; ++tryNum; int ret = ::ppoll(&pfd, 1, &ts, nullptr); if (ret >= 0) { if (pfd.revents) { Loading @@ -659,22 +673,25 @@ private: *hangUp = true; mValid = false; ALOGD("PipeFenceImpl: pipe fd hangup or err event returned"); return false; } *event = true; return true; } // event not ready yet. return true; } if (errno == EINTR) { // poll() was cancelled by signal or inner kernel status. return false; } // Since poll error happened here, treat the error is irrecoverable. ++noEvent; // retry if the deadline does not meet yet. } else if (errno != EINTR) { ALOGE("PipeFenceImpl: poll() error %d", errno); *hangUp = true; mValid = false; return true; return false; } elapsedTsNs = android::elapsedRealtimeNano() - startTsNs; } while (elapsedTsNs < waitTimeNs); // EINTR till the end. // treat this as event not ready yet. ALOGV("PipeFenceImpl: tried %d times NoEvent %d times, spent %lld nanosecs", tryNum, noEvent, (long long)elapsedTsNs); return false; } public: Loading @@ -683,8 +700,7 @@ public: return C2_BAD_STATE; } bool hangUp = false; bool event = false; if (waitEvent(timeoutNs, &hangUp, &event)) { bool event = waitEvent(timeoutNs, &hangUp); if (hangUp) { return C2_BAD_STATE; } Loading @@ -692,9 +708,6 @@ public: return C2_OK; } return C2_TIMED_OUT; } else { return C2_CANCELED; } } virtual bool valid() const { Loading @@ -702,13 +715,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (hangUp) { return false; } } return true; (void)waitEvent(0, &hangUp); return !hangUp; } virtual bool ready() const { Loading @@ -716,13 +724,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (event) { return true; } } return false; bool event = waitEvent(0, &hangUp); return event; } virtual int fd() const { Loading Loading
media/codec2/vndk/C2Fence.cpp +62 −59 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <android-base/unique_fd.h> #include <cutils/native_handle.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <ui/Fence.h> #include <C2FenceFactory.h> Loading Loading @@ -631,26 +632,39 @@ C2Fence _C2FenceFactory::CreateMultiSyncFence( */ class _C2FenceFactory::PipeFenceImpl: public C2Fence::Impl { private: bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp, bool *event) const { // Wait for an event using ::ppoll() and handle any interruptions by signals // (EINTR) by retrying and accounting for time already waited. // Note: while ppoll in theory supports blocking signals, Linux NPTL library does // not allow blocking 2 realtime signals (see man nptl), so we do need to handle // signal interruptions. bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp) const { if (!mValid) { *hangUp = true; return true; return false; } struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; int64_t waitTimeNs = kPipeFenceWaitLimitSecs * 1000000000LL; if (timeoutNs >= 0) { ts.tv_sec = int(timeoutNs / 1000000000); ts.tv_nsec = timeoutNs % 1000000000; waitTimeNs = timeoutNs; } else { ALOGD("polling for indefinite duration requested, but changed to wait for %d sec", kPipeFenceWaitLimitSecs); ts.tv_sec = kPipeFenceWaitLimitSecs; ts.tv_nsec = 0; } int64_t startTsNs = android::elapsedRealtimeNano(); int64_t elapsedTsNs = 0; int tryNum = 0; int noEvent = 0; do { struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; ts.tv_sec = int((waitTimeNs - elapsedTsNs) / 1000000000); ts.tv_nsec = (waitTimeNs - elapsedTsNs) % 1000000000; ++tryNum; int ret = ::ppoll(&pfd, 1, &ts, nullptr); if (ret >= 0) { if (pfd.revents) { Loading @@ -659,22 +673,25 @@ private: *hangUp = true; mValid = false; ALOGD("PipeFenceImpl: pipe fd hangup or err event returned"); return false; } *event = true; return true; } // event not ready yet. return true; } if (errno == EINTR) { // poll() was cancelled by signal or inner kernel status. return false; } // Since poll error happened here, treat the error is irrecoverable. ++noEvent; // retry if the deadline does not meet yet. } else if (errno != EINTR) { ALOGE("PipeFenceImpl: poll() error %d", errno); *hangUp = true; mValid = false; return true; return false; } elapsedTsNs = android::elapsedRealtimeNano() - startTsNs; } while (elapsedTsNs < waitTimeNs); // EINTR till the end. // treat this as event not ready yet. ALOGV("PipeFenceImpl: tried %d times NoEvent %d times, spent %lld nanosecs", tryNum, noEvent, (long long)elapsedTsNs); return false; } public: Loading @@ -683,8 +700,7 @@ public: return C2_BAD_STATE; } bool hangUp = false; bool event = false; if (waitEvent(timeoutNs, &hangUp, &event)) { bool event = waitEvent(timeoutNs, &hangUp); if (hangUp) { return C2_BAD_STATE; } Loading @@ -692,9 +708,6 @@ public: return C2_OK; } return C2_TIMED_OUT; } else { return C2_CANCELED; } } virtual bool valid() const { Loading @@ -702,13 +715,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (hangUp) { return false; } } return true; (void)waitEvent(0, &hangUp); return !hangUp; } virtual bool ready() const { Loading @@ -716,13 +724,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (event) { return true; } } return false; bool event = waitEvent(0, &hangUp); return event; } virtual int fd() const { Loading