From f7a18ec4494b9c5c9ef3fd440bbf68ffc6425e18 Mon Sep 17 00:00:00 2001 From: yy1717 <fctom1215@outlook.com> Date: 星期四, 08 十二月 2022 15:40:56 +0800 Subject: [PATCH] 智慧驾培首次提交 --- lib/src/main/cpp/common/apptimer.cpp | 382 ++++++++++++++++++++++++++++++++---------------------- 1 files changed, 228 insertions(+), 154 deletions(-) diff --git a/lib/src/main/cpp/common/apptimer.cpp b/lib/src/main/cpp/common/apptimer.cpp index b37cd86..bcfe799 100644 --- a/lib/src/main/cpp/common/apptimer.cpp +++ b/lib/src/main/cpp/common/apptimer.cpp @@ -1,188 +1,262 @@ -//POSIX.1b Timer -#include <jni.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> -#include <sys/time.h> -#include <pthread.h> -#include <errno.h> -#include <time.h> -#include "../jni_log.h" +// +// Created by YY on 2021/3/16. +// + #include "apptimer.h" +#include "../jni_log.h" -#define MAX_TIMER 32 +#include <cstdint> +#include <functional> +#include <chrono> +#include <mutex> +#include <condition_variable> +#include <list> +#include <thread> +#include <map> +#include <string> +#include <sstream> +#include <iomanip> -static struct { - timer_t timerId; +#define DEBUG(fmt, args...) LOGD("<apptimer> <%s>: " fmt, __func__, ##args) - void (*func)(union sigval sig); +std::mutex mtx; - int value; - uint8_t *user_data; -} AppTimer[MAX_TIMER]; +std::map<void(*)(apptimer_var_t), CTimer *> TimerList; -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static void RemoveTimerList(const CTimer *p); -static int createTimer(timer_t *timerId, void (*func)(union sigval sig), - int value, - uint8_t *usr_data, int usr_data_length, - uint8_t **usr_data_ptr) { - struct sigevent sev; - pthread_attr_t attr; +CTimer::CTimer() { + flag = 0; + var.var_ptr = nullptr; + var.var1 = var.var2 = var.var_length = 0; + pthread = nullptr; +} - // Register printMsg to SIGALRM - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached +CTimer::~CTimer() { + if (pthread != nullptr) { + delete pthread; + } + if (var.var_ptr != nullptr) { + delete var.var_ptr; + } +} - memset(&sev, 0, sizeof(sev)); +bool CTimer::_updateStatus(CTimer *timer) { + if (timer->flag == 0) { + return false; + } else { + return true; //cancel + } +} - sev.sigev_notify = SIGEV_THREAD; - sev.sigev_notify_function = func; - sev.sigev_notify_attributes = &attr; +void CTimer::_do_task_func(uint32_t msec, CTimer *timer, std::function<void(apptimer_var_t)> callback) { + std::unique_lock<std::mutex> lk(timer->cv_mtx); - if (usr_data != NULL && usr_data_length != 0) { - if ((sev.sigev_value.sival_ptr = malloc(usr_data_length)) != NULL) { - *usr_data_ptr = (uint8_t *) sev.sigev_value.sival_ptr; - memcpy(sev.sigev_value.sival_ptr, usr_data, usr_data_length); //Copy usr data - sev.sigev_value.sival_int = usr_data_length; - } else { - return -1; + auto now = std::chrono::steady_clock::now(); + + if (timer->cv.wait_until(lk, now + std::chrono::milliseconds(msec), std::bind(_updateStatus, timer)) == false) { + RemoveTimerList(timer); // 浠庡垪琛ㄤ腑鍒犻櫎绱㈠紩 + + if (timer->flag == 0) { + callback(timer->var); } } else { - sev.sigev_value.sival_int = value; +// LOGD("Cancel %d", static_cast<int>(timer->flag)); + RemoveTimerList(timer); } - /* create timer */ - if (timer_create(CLOCK_REALTIME, &sev, timerId) == -1) { - return -1; + //delete timer; + lk.unlock(); + std::thread(clear, timer).detach(); +} + +void CTimer::copy(int value1, int value2, const void *data, int length) +{ + this->var.var1 = value1; + this->var.var2 = value2; + this->var.var_length = length; + if (length > 0 && data != nullptr) { + this->var.var_ptr = new uint8_t[length]; + memcpy(this->var.var_ptr, data, length); + } else { + this->var.var_ptr = nullptr; } -// LOGD("timer_create\n"); - return 0; } -static int setTimer(timer_t timerId, int timeMSec) { - struct itimerspec its; - - /* Start the timer */ - its.it_value.tv_sec = timeMSec / 1000; - its.it_value.tv_nsec = (timeMSec % 1000) * 1000000; - - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - - if (timer_settime(timerId, 0, &its, NULL) == -1) { - return -1; +void CTimer::clear(CTimer *timer) +{ + if (timer != nullptr) { + delete timer; } -// LOGD("timer_settime\n"); - return 0; } -void AppTimer_Init(void) { - memset(AppTimer, 0, sizeof(AppTimer)); - pthread_mutex_init(&mutex, NULL); +bool CTimer::start(uint32_t msec, std::function<void(apptimer_var_t)> callback) { + if (pthread == nullptr) { + try { + pthread = new std::thread(_do_task_func, msec, this, callback); + pthread->detach(); + } catch (std::exception &ex) { + DEBUG("%s", ex.what()); + return false; + } +// this->callbackThread = std::thread(_do_task_func, msec, this, callback); +// this->callbackThread.detach(); + } + return true; } -void AppTimer_add(void (*func)(union sigval), int timeMS) { - int i; -// LOGD("AppTimer_add\n"); - pthread_mutex_lock(&mutex); - for (i = 0; i < MAX_TIMER; i++) { - if (AppTimer[i].func == NULL) { - if (createTimer(&(AppTimer[i].timerId), func, 0, NULL, 0, &(AppTimer[i].user_data)) == 0) { - AppTimer[i].func = func; +void CTimer::stop() { + std::unique_lock<std::mutex> lk(this->cv_mtx); + this->flag = 1; + this->cv.notify_one(); +} - if (setTimer(AppTimer[i].timerId, timeMS) != - 0) { //Set timer fail, delele it - timer_delete(AppTimer[i].timerId); - if (AppTimer[i].user_data != NULL) { - free(AppTimer[i].user_data); - AppTimer[i].user_data = NULL; - } - AppTimer[i].func = NULL; - } - } +void AppTimer_init(void) +{ + TimerList.clear(); +} + +void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec) +{ + CTimer *cTimer = new CTimer(); + cTimer->copy(0, 0, nullptr, 0); + + std::lock_guard<std::mutex> lock(mtx); + TimerList.insert(std::pair<void (*)(apptimer_var_t), CTimer *>(cb, cTimer)); + + if (cTimer->start(msec, cb) == false) { + auto it = TimerList.find(cb); + if (it != TimerList.end()) { + CTimer *ptr = it->second; + TimerList.erase(it); + } + delete cTimer; + } +} + +void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, int value1, int value2) +{ + CTimer *cTimer = new CTimer(); + cTimer->copy(value1, value2, nullptr, 0); + + std::lock_guard<std::mutex> lock(mtx); + TimerList.insert(std::pair<void (*)(apptimer_var_t), CTimer *>(cb, cTimer)); + + if (cTimer->start(msec, cb) == false) { + LOGD("寤虹珛澶辫触"); + auto it = TimerList.find(cb); + if (it != TimerList.end()) { + CTimer *ptr = it->second; + TimerList.erase(it); + } + delete cTimer; + } +} + +void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, void *data, int lenght) +{ + CTimer *cTimer = new CTimer(); + cTimer->copy(0, 0, data, lenght); + + std::lock_guard<std::mutex> lock(mtx); + TimerList.insert(std::pair<void (*)(apptimer_var_t), CTimer *>(cb, cTimer)); + + if (cTimer->start(msec, cb) == false) { + auto it = TimerList.find(cb); + if (it != TimerList.end()) { + CTimer *ptr = it->second; + TimerList.erase(it); + } + delete cTimer; + } +} + +void AppTimer_delete(void(*cb)(apptimer_var_t)) +{ + std::lock_guard<std::mutex> lock(mtx); + + auto it = TimerList.find(cb); + if (it != TimerList.end()) { + CTimer *ptr = it->second; + TimerList.erase(it); + ptr->stop(); + } +} + +static void RemoveTimerList(const CTimer *p) +{ + std::lock_guard<std::mutex> lock(mtx); + + for (auto it = TimerList.begin(); it != TimerList.end(); ++it) { + CTimer *ptr = it->second; + if (ptr == p) { + TimerList.erase(it); break; } } - pthread_mutex_unlock(&mutex); -} - -void AppTimer_add(void (*func)(union sigval), int timeMS, uint8_t *data, int length) { - int i; -// LOGD("AppTimer_add\n"); - pthread_mutex_lock(&mutex); - for (i = 0; i < MAX_TIMER; i++) { - if (AppTimer[i].func == NULL) { - if (createTimer(&(AppTimer[i].timerId), func, 0, data, length, &(AppTimer[i].user_data)) == 0) { - AppTimer[i].func = func; - - if (setTimer(AppTimer[i].timerId, timeMS) != - 0) { //Set timer fail, delele it - timer_delete(AppTimer[i].timerId); - if (AppTimer[i].user_data != NULL) { - free(AppTimer[i].user_data); - AppTimer[i].user_data = NULL; - } - AppTimer[i].func = NULL; - } - } - break; - } - } - pthread_mutex_unlock(&mutex); -} - -void AppTimer_add(void (*func)(union sigval), int timeMS, int value) { - int i; -// LOGD("AppTimer_add\n"); - pthread_mutex_lock(&mutex); - for (i = 0; i < MAX_TIMER; i++) { - if (AppTimer[i].func == NULL) { - if (createTimer(&(AppTimer[i].timerId), func, value, NULL, 0, &(AppTimer[i].user_data)) == 0) { - AppTimer[i].func = func; - - if (setTimer(AppTimer[i].timerId, timeMS) != - 0) { //Set timer fail, delele it - timer_delete(AppTimer[i].timerId); - if (AppTimer[i].user_data != NULL) { - free(AppTimer[i].user_data); - AppTimer[i].user_data = NULL; - } - AppTimer[i].func = NULL; - } - } - break; - } - } - pthread_mutex_unlock(&mutex); -} - -void AppTimer_delete(void (*func)(union sigval)) { - int i; -// LOGD("AppTimer_delete\n"); - pthread_mutex_lock(&mutex); - for (i = 0; i < MAX_TIMER; i++) { - if (AppTimer[i].func == func) { - timer_delete(AppTimer[i].timerId); - if (AppTimer[i].user_data != NULL) { - free(AppTimer[i].user_data); - AppTimer[i].user_data = NULL; - } - AppTimer[i].func = NULL; - } - } - pthread_mutex_unlock(&mutex); } uint32_t AppTimer_GetTickCount(void) { - struct timespec ts; + std::chrono::milliseconds as = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()); - clock_gettime(CLOCK_MONOTONIC, &ts); + return as.count(); +} - return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000); +uint32_t AppTimer_GetGmtTickCount(void) +{ + std::chrono::seconds as = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()); + + return as.count(); +} + +std::string FormatTime(const char *fmt) +{ + auto now = std::chrono::system_clock::now(); + auto timet = std::chrono::system_clock::to_time_t(now); + auto localTime = *std::localtime(&timet); + + std::stringstream ss; + std::string str; + ss << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S"); + str = ss.str(); + return str; +} + +std::time_t MktimeString(const char *str, const char *fmt) +{ + struct std::tm dt; + std::istringstream ss(str); + + ss >> std::get_time(&dt, fmt); + + std::stringstream out; + out << std::put_time(&dt, "%Y-%m-%d %H:%M:%S"); +// DEBUG("%s, %ld", out.str().c_str(), std::mktime(&dt)); + + time_t utc = std::mktime(&dt); + + return utc; +} + +time_t TimeStamp(int year, int mon, int day, int hour, int min, int sec) +{ + // YYHHDDhhmmss(GMT+8) + struct tm test_tm; + + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv,&tz); + + memset(&test_tm, 0, sizeof(test_tm)); + + test_tm.tm_year = year - 1900; + test_tm.tm_mon = mon - 1; + test_tm.tm_mday = day; + test_tm.tm_hour = hour; + test_tm.tm_min = min; + test_tm.tm_sec = sec; + + return mktime(&test_tm) - tz.tz_minuteswest*60; } -- Gitblit v1.8.0