156 lines
4.7 KiB
C++
156 lines
4.7 KiB
C++
/*
|
|
* Copyright (C) 2014-2019 Amlogic, Inc. All rights reserved.
|
|
*
|
|
* All information contained herein is Amlogic confidential.
|
|
*
|
|
* This software is provided to you pursuant to Software License Agreement
|
|
* (SLA) with Amlogic Inc ("Amlogic"). This software may be used
|
|
* only in accordance with the terms of this agreement.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification is strictly prohibited without prior written permission from
|
|
* Amlogic.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef YOCTO_EVENTTRACKER_H
|
|
#define YOCTO_EVENTTRACKER_H
|
|
#include <utils/Looper.h>
|
|
|
|
#include <condition_variable>
|
|
#include <functional>
|
|
#include <thread>
|
|
|
|
#include "SubtitleLog.h"
|
|
|
|
using OnThreadStart = std::function<void()>;
|
|
|
|
class EventsTracker {
|
|
public:
|
|
enum Event {
|
|
EVENT_INPUT = android::Looper::EVENT_INPUT,
|
|
EVENT_OUTPUT = android::Looper::EVENT_OUTPUT,
|
|
EVENT_ERROR = android::Looper::EVENT_ERROR,
|
|
EVENT_HANGUP = android::Looper::EVENT_HANGUP,
|
|
};
|
|
|
|
enum HandleRet {
|
|
RET_REMOVE = 0,
|
|
RET_CONTINUE = 1,
|
|
};
|
|
|
|
EventsTracker(android::Looper_callbackFunc callback, const char *name = nullptr,
|
|
OnThreadStart onThreadStartPtr = nullptr) {
|
|
mExited = false;
|
|
|
|
mThread = std::make_shared<std::thread>(
|
|
[=](android::sp<android::Looper> *looper) {
|
|
if (onThreadStartPtr != nullptr) {
|
|
onThreadStartPtr();
|
|
}
|
|
|
|
{
|
|
std::lock_guard<std::mutex> _l(_mutex);
|
|
*looper = android::Looper::prepare(0);
|
|
SUBTITLE_LOGI("EventsTracker, Looper created: %p", (*looper).get());
|
|
_cond.notify_all();
|
|
}
|
|
|
|
while (!mRequestExit) {
|
|
(*looper)->pollOnce(2000);
|
|
}
|
|
SUBTITLE_LOGI("EventsTracker: %s EXIT!!!", name);
|
|
|
|
{
|
|
std::unique_lock<std::mutex> _l(_mutex_exit);
|
|
mExited = true;
|
|
_cond_exit.notify_all();
|
|
}
|
|
},
|
|
&mLooper);
|
|
|
|
{
|
|
std::unique_lock<std::mutex> _l(_mutex);
|
|
SUBTITLE_LOGI("EventsTracker, Waiting for mLooper create");
|
|
_cond.wait(_l, [&]() -> bool { return mLooper != nullptr; });
|
|
SUBTITLE_LOGI("EventsTracker, Looper created: %p", mLooper.get());
|
|
}
|
|
|
|
mCallback = callback;
|
|
}
|
|
|
|
~EventsTracker() {
|
|
mCallback = nullptr;
|
|
requestExit();
|
|
}
|
|
|
|
void requestExit() {
|
|
if (mRequestExit || mLooper == nullptr) return;
|
|
|
|
mRequestExit = true;
|
|
wake();
|
|
}
|
|
|
|
void wake() {
|
|
if (mLooper->isPolling()) {
|
|
mLooper->wake();
|
|
}
|
|
}
|
|
|
|
int addFd(int fd, int events, void *data) {
|
|
return mLooper->addFd(fd, android::Looper::POLL_CALLBACK, events, mCallback, data);
|
|
}
|
|
|
|
int removeFd(int fd) { return mLooper->removeFd(fd); }
|
|
|
|
void join() {
|
|
// if (mThread != nullptr && mThread->joinable()) {
|
|
// mThread->join();
|
|
// }
|
|
|
|
if (mThread != nullptr) {
|
|
std::unique_lock<std::mutex> _l(_mutex_exit);
|
|
|
|
if (!mExited) {
|
|
SUBTITLE_LOGI("Waiting for exit...");
|
|
_cond_exit.wait(_l);
|
|
SUBTITLE_LOGI("Exit thread...");
|
|
mExited = true;
|
|
}
|
|
|
|
if (mThread->joinable()) {
|
|
mThread->join();
|
|
SUBTITLE_LOGI("join thread...");
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
android::sp<android::Looper> mLooper = nullptr;
|
|
android::Looper_callbackFunc mCallback = nullptr;
|
|
|
|
volatile bool mRequestExit = false;
|
|
|
|
std::mutex _mutex;
|
|
std::condition_variable _cond;
|
|
|
|
bool mExited = false;
|
|
std::mutex _mutex_exit;
|
|
std::condition_variable _cond_exit;
|
|
|
|
std::shared_ptr<std::thread> mThread;
|
|
};
|
|
|
|
#endif // YOCTO_EVENTTRACKER_H
|