refactor(project): remove unused DataQueue implementation and CCfgFileParser
- Removed DataQueue and CCfgFileParser classes - Deleted related source files and Makefile - Updated .gitignore to exclude new directories - Modified CMakeLists.txt to add library output path - Added new memory comparison assertion macros in c_testcase.h
This commit is contained in:
parent
5ca1a439f3
commit
610a7e4008
|
@ -5,6 +5,7 @@ build
|
|||
################ Executable program ################
|
||||
|
||||
bin/
|
||||
lib/
|
||||
dist/
|
||||
|
||||
################### VSCode config ##################
|
||||
|
|
|
@ -5,6 +5,7 @@ project(external_interface CXX)
|
|||
set(CMAKE_CXX_STANDARD 11)
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# 外部接口模块文档
|
||||
|
||||
本文档主要描述Voix中的用于与遥测机及上位机进行通讯及相关附加功能的模块。
|
||||
这些模块拆分自原host_com.cpp文件。
|
||||
|
||||
## 1. 构建及测试
|
||||
|
||||
使用cmake进行构建:
|
||||
|
||||
```bash
|
||||
cmake . -B build
|
||||
cmake --build build -j6
|
||||
```
|
||||
|
||||
使用cmake及ctest进行测试:
|
||||
|
||||
```bash
|
||||
cmake . -B build
|
||||
cmake --build build -j6 --target test
|
||||
```
|
||||
|
||||
或在构建完成后使用测试脚本:
|
||||
|
||||
```bash
|
||||
./scripts/unittest.py bin/test_*
|
||||
```
|
||||
|
||||
## 2. 模块公开接口
|
||||
|
||||
以下接口由通讯模块公开,可以在VOIX主程序中使用。
|
||||
|
||||
1. `void exint_init(const char* config_path, et_callback_t cb)`:模块初始化函数,此函数会读取配置文件,开启串口并启动模块所需的线程
|
||||
- `config_path`:配置文件路径
|
||||
- `cb`:回调函数,用于进行指令响应和遥测数据请求
|
||||
2. `void (*et_callback_t)(uint32_t type, size_t len, void* data)`:回调函数类型,内部数据为指针类型的数据包仅保证在回调函数中有效。
|
||||
- `type`:数据包类型
|
||||
- `len`:数据包长度,对于字符串类型数据应包含后缀`\0`的长度。
|
||||
- `data`:数据包数据
|
||||
4. 数据包类型(宏定义):
|
||||
- `ET_TYPE_TEXT`:文本,对应`const char*`类型的数据
|
||||
- `ET_TYPE_AUDIO`:音频,对应`short*`类型的数据
|
||||
- `ET_TYPE_COMMAND`:指令码,对应`uint8_t[6]`类型的数据
|
||||
- `ET_TYPE_ALARM`:告警码,对应`AlarmData*`类型的数据
|
||||
- `ET_TYPE_TELEMETRY_REQUEST`:遥测请求,对应`TelemetryRequestData*`类型的数据,需要主程序在数据包内的指针中写入对应的变量数据
|
||||
5. `void exint_send(uint32_t type, size_t len, void* data)`:发送数据包,此函数是非阻塞的
|
||||
- `type`:数据包类型
|
||||
- `len`:数据包长度,对于字符串类型数据应包含后缀`\0`的长度。
|
||||
- `data`:数据包数据
|
||||
6. `void exint_finialize()`:模块销毁函数,调用后模块会终止所有内部线程,释放所有资源。
|
|
@ -154,6 +154,36 @@ extern "C"{
|
|||
test_case_abort(1); \
|
||||
} \
|
||||
} while (0)
|
||||
#define assert_mem_eq(expr1, expr2, size) do { \
|
||||
if (memcmp((expr1), (expr2), (size)) != 0) { \
|
||||
printf("assertion failed: %s == %s\n", #expr1, #expr2); \
|
||||
printf("\t#0: "); \
|
||||
for (int i = 0; i < (size); i++) { \
|
||||
printf("%02X", ((uint8_t*)(expr1))[i]); \
|
||||
} \
|
||||
printf("\n\t#1: "); \
|
||||
for (int i = 0; i < (size); i++) { \
|
||||
printf("%02X", ((uint8_t*)(expr2))[i]); \
|
||||
} \
|
||||
printf("\nfile: \"%s\", line %d, in %s\n", __FILE__, __LINE__, __ASSERT_FUNCTION);\
|
||||
test_case_abort(1); \
|
||||
} \
|
||||
} while (0)
|
||||
#define assert_mem_ne(expr1, expr2, size) do { \
|
||||
if (memcmp((expr1), (expr2), (size)) == 0) { \
|
||||
printf("assertion failed: %s != %s\n", #expr1, #expr2); \
|
||||
printf("\t#0: "); \
|
||||
for (int i = 0; i < (size); i++) { \
|
||||
printf("%02X", ((uint8_t*)(expr1))[i]); \
|
||||
} \
|
||||
printf("\n\t#1: "); \
|
||||
for (int i = 0; i < (size); i++) { \
|
||||
printf("%02X", ((uint8_t*)(expr2))[i]); \
|
||||
} \
|
||||
printf("\nfile: \"%s\", line %d, in %s\n", __FILE__, __LINE__, __ASSERT_FUNCTION);\
|
||||
test_case_abort(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
typedef int (*test_case)();
|
||||
|
|
|
@ -7,7 +7,45 @@
|
|||
#include <condition_variable>
|
||||
#include <stdexcept>
|
||||
|
||||
class QueueException;
|
||||
template <typename T>
|
||||
class DataQueue;
|
||||
|
||||
class QueueException : public std::exception
|
||||
{
|
||||
public:
|
||||
QueueException(void* queue) : queue(queue) {}
|
||||
|
||||
template <typename T>
|
||||
DataQueue<T>* GetQueue() const noexcept
|
||||
{
|
||||
return static_cast<DataQueue<T>*>(queue);
|
||||
}
|
||||
|
||||
private:
|
||||
void* queue;
|
||||
};
|
||||
|
||||
class QueueCleared : public QueueException
|
||||
{
|
||||
public:
|
||||
QueueCleared(void* queue) : QueueException(queue) {}
|
||||
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "queue cleared";
|
||||
}
|
||||
};
|
||||
|
||||
class QueueTimeout : public QueueException
|
||||
{
|
||||
public:
|
||||
QueueTimeout(void* queue) : QueueException(queue) {}
|
||||
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "queue timeout";
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class DataQueue {
|
||||
|
@ -32,7 +70,7 @@ public:
|
|||
{
|
||||
m_Cond.wait(lock);
|
||||
if (epoch != m_CurrEpoch) {
|
||||
throw QueueException(this);
|
||||
throw QueueCleared(this);
|
||||
}
|
||||
}
|
||||
T data = std::move(m_Queue.front());
|
||||
|
@ -51,9 +89,12 @@ public:
|
|||
throw QueueTimeout(this);
|
||||
}
|
||||
if (epoch != m_CurrEpoch) {
|
||||
throw QueueException(this);
|
||||
throw QueueCleared(this);
|
||||
}
|
||||
}
|
||||
T data = std::move(m_Queue.front());
|
||||
m_Queue.pop_front();
|
||||
return data;
|
||||
}
|
||||
|
||||
bool Empty() noexcept
|
||||
|
@ -85,37 +126,4 @@ private:
|
|||
uint8_t m_CurrEpoch;
|
||||
};
|
||||
|
||||
class QueueException : public std::exception
|
||||
{
|
||||
public:
|
||||
QueueException(void* queue) : queue(queue) {}
|
||||
|
||||
template <typename T>
|
||||
DataQueue<T>* GetQueue() const noexcept
|
||||
{
|
||||
return static_cast<DataQueue<T>*>(queue);
|
||||
}
|
||||
|
||||
private:
|
||||
void* queue;
|
||||
};
|
||||
|
||||
class QueueCleared : QueueException
|
||||
{
|
||||
public:
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "queue cleared";
|
||||
}
|
||||
};
|
||||
|
||||
class QueueTimeout : QueueException
|
||||
{
|
||||
public:
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "queue timeout";
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -10,7 +10,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void exint_handle_pack(uint32_t type, size_t len, union PacketData data);
|
||||
void exint_handle_pack(uint32_t type, size_t len, void* data);
|
||||
int exint_init_from_tty(int host_com_tty, int telemetry_com_tty, et_callback_t cb);
|
||||
|
||||
void* telemetry_host_com_thread(void* args);
|
||||
|
|
|
@ -41,20 +41,12 @@ struct TelemetryRequestData {
|
|||
int app_ver_low;
|
||||
};
|
||||
|
||||
union PacketData
|
||||
{
|
||||
int64_t pd_integer;
|
||||
double pd_float;
|
||||
const char* pd_text;
|
||||
void* pd_pointer;
|
||||
};
|
||||
|
||||
typedef void (*et_callback_t)(uint32_t, size_t, union PacketData);
|
||||
typedef void (*et_callback_t)(uint32_t, size_t, void*);
|
||||
|
||||
EXTERN_INTERFACE_PUBLIC
|
||||
int exint_init(const char* config_path, et_callback_t cb);
|
||||
EXTERN_INTERFACE_PUBLIC
|
||||
void exint_send(uint32_t type, size_t len, union PacketData data);
|
||||
void exint_send(uint32_t type, size_t len, void* data);
|
||||
EXTERN_INTERFACE_PUBLIC
|
||||
void exint_finialize();
|
||||
|
||||
|
|
|
@ -1,263 +0,0 @@
|
|||
//bb.cpp
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <cerrno>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "CCfgFileParser.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static inline bool istab(int c) { return (c == '\t'); }
|
||||
|
||||
static inline char *strltrim(char *str) {
|
||||
while (isspace(*str) || istab(*str)) {
|
||||
++str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static inline char *strrtrim(char *str) {
|
||||
int len = strlen(str) - 1;
|
||||
while (isspace(str[len]) || istab(str[len])) {
|
||||
str[len--] = '\0';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
int CCfgFileParser::parseFile(const char *lpszFilename) {
|
||||
using std::string;
|
||||
std::ifstream in1(lpszFilename);
|
||||
|
||||
if (!in1.is_open()) return errno;
|
||||
|
||||
char line[2048];
|
||||
char *pline;
|
||||
bool bInSection = false;
|
||||
SECTION_CONTENT *pSC = NULL;
|
||||
string strSection;
|
||||
std::pair<string, string> pairKeyValue;
|
||||
|
||||
m_error_line = 0;
|
||||
m_content.clear();
|
||||
pSC = &m_content["default"];
|
||||
bInSection = true;
|
||||
string base64str("");
|
||||
string mystr("");
|
||||
while (!in1.eof()) {
|
||||
in1.getline(line, sizeof(line));
|
||||
|
||||
if (line[strlen(line)] != '\n')
|
||||
mystr += line + string("\n");
|
||||
else
|
||||
mystr += line;
|
||||
|
||||
}
|
||||
in1.close();
|
||||
|
||||
stringstream in;
|
||||
in.str(mystr);
|
||||
|
||||
while (!in.eof()) { /*if(base64str.size() > sizeof(line))
|
||||
{
|
||||
printf("error in config parser!\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(line, base64str.c_str(), base64str.size());
|
||||
*/
|
||||
in.getline(line, sizeof(line));
|
||||
pline = line;
|
||||
++m_error_line;
|
||||
pline = strltrim(pline);
|
||||
if (pline[0] == '\0') continue; //white line, skip
|
||||
if (pline[0] == m_chCommentMark) continue; //comment line, skip
|
||||
if (bInSection) {
|
||||
//is new-section begin?
|
||||
if (pline[0] == m_chSectionBMark && extractSection(pline, strSection)) {
|
||||
pSC = &m_content[strSection];
|
||||
}
|
||||
else if (extractKeyValue(pline, pairKeyValue)) {
|
||||
//key-value pair
|
||||
pSC->insert(pairKeyValue);
|
||||
}
|
||||
else {
|
||||
//in.close();
|
||||
return SYNTAX_ERROR;
|
||||
}
|
||||
}
|
||||
else { //NOT in section
|
||||
//is a valid section?
|
||||
if (extractSection(pline, strSection)) {
|
||||
pSC = &m_content[strSection];
|
||||
bInSection = true;
|
||||
}
|
||||
else {
|
||||
//in.close();
|
||||
return SYNTAX_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
// in.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool CCfgFileParser::getValue(const std::string &strSection,
|
||||
const std::string &strKey, const char * &Value) const {
|
||||
FILE_CONTENT::const_iterator it;
|
||||
|
||||
if ((it = m_content.find(strSection)) != m_content.end()) {
|
||||
SECTION_CONTENT::const_iterator p;
|
||||
const SECTION_CONTENT §ion = (*it).second;//m_content[strSection];
|
||||
if ((p = section.find(strKey)) != section.end()) {
|
||||
Value = ((*p).second).c_str();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bShowError)
|
||||
fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCfgFileParser::getValue(const std::string &strKey, const char * &pValue) const {
|
||||
return getValue("default", strKey, pValue);
|
||||
}
|
||||
|
||||
bool CCfgFileParser::getIntValue(const std::string &strSection,
|
||||
const std::string& strKey, long& Value) const {
|
||||
const char* pstr;
|
||||
if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0)
|
||||
{
|
||||
if (strlen(pstr) > 0)
|
||||
{
|
||||
Value = atol(pstr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (m_bShowError)
|
||||
fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCfgFileParser::getIntValue(const std::string &strKey, long &Value) const {
|
||||
return getIntValue("default", strKey, Value);
|
||||
}
|
||||
|
||||
bool CCfgFileParser::getDoubleValue(const std::string &strSection,
|
||||
const std::string &strKey, double &Value) const {
|
||||
const char *pstr;
|
||||
if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0)
|
||||
{
|
||||
Value = atof(pstr);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bShowError)
|
||||
fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CCfgFileParser::getDoubleValue(const std::string &strKey, double &Value) const {
|
||||
return getDoubleValue("default", strKey, Value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Description: Extract section name
|
||||
* Parameters: line[IN]---A string line to be parsed
|
||||
* strSection[OUT]---Section name
|
||||
*
|
||||
* Return Value: if section name is in the line return true,or return false
|
||||
*/
|
||||
bool CCfgFileParser::extractSection(char *line, std::string &strSection) {
|
||||
char *tmp;
|
||||
if (line[0] == m_chSectionBMark) {
|
||||
if ((tmp = strchr(++line, m_chSectionEMark)) != NULL) {
|
||||
*tmp = '\0';
|
||||
strSection = line;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Description: Parse a record line into a std:pair as key and value
|
||||
* Parameters: line[IN]---A string to be parsed
|
||||
* pairKeyValue[OUT]---Parsing result
|
||||
*
|
||||
* Return Value: If parse successfully return true,or return false
|
||||
*/
|
||||
|
||||
bool CCfgFileParser::extractKeyValue(char *line,
|
||||
std::pair<std::string, std::string> &pairKeyValue) {
|
||||
char *tmp;
|
||||
if ((tmp = strchr(line, m_chRecordEMark)) != NULL || (tmp = strchr(line, '\r')) != NULL ||
|
||||
(tmp = strchr(line, '='))) {
|
||||
if (*tmp == '=')
|
||||
tmp = line + strlen(line); // tmp++;
|
||||
*tmp = '\0'; //ignore content after ';'(the RecordEMark)
|
||||
if ((tmp = strchr(line, '=')) != NULL) {
|
||||
*tmp++ = '\0';
|
||||
tmp = strltrim(tmp);
|
||||
tmp = strrtrim(tmp);
|
||||
line = strrtrim(line);
|
||||
|
||||
pairKeyValue.first = line;
|
||||
pairKeyValue.second = tmp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *CCfgFileParser::getErrorString(int err) {
|
||||
static char buf[100];
|
||||
if (err == SYNTAX_ERROR) {
|
||||
sprintf(buf, "configuration file format is invalid at line %d", m_error_line);
|
||||
return buf;
|
||||
}
|
||||
else {
|
||||
return strerror(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCfgFileParser::printContent() {
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
FILE_CONTENT::const_iterator pf;
|
||||
SECTION_CONTENT::const_iterator ps;
|
||||
for (pf = m_content.begin(); pf != m_content.end(); ++pf) {
|
||||
cout << "section:" << (*pf).first << endl;
|
||||
const SECTION_CONTENT &sc = (*pf).second;
|
||||
for (ps = sc.begin(); ps != sc.end(); ++ps) {
|
||||
cout << '\t' << (*ps).first << "=" << (*ps).second << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 在库中定义一个工厂函数 createParser
|
||||
extern "C" __attribute__((visibility("default"))) CCfgFileParser* createParser() {
|
||||
return new CCfgFileParser(); // 在工厂函数中调用构造函数创建对象并返回指针
|
||||
}
|
||||
|
||||
// 在库中定义一个销毁函数 deleteParser
|
||||
|
||||
extern "C" __attribute__((visibility("default"))) void deleteParser(CCfgFileParser* parser) {
|
||||
// 在销毁函数中调用析构函数销毁对象
|
||||
delete parser;
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
#if !defined(AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_)
|
||||
#define AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class __attribute__((visibility("default"))) CCfgFileParser
|
||||
{
|
||||
public:
|
||||
explicit CCfgFileParser(bool base64 = false,
|
||||
char chSectionBMark = '[',
|
||||
char chSectionEMark = ']',
|
||||
char chRecordEMark = ';', //record end-mark
|
||||
char chCommentMark = '#'
|
||||
)
|
||||
:m_base64(base64), m_chSectionBMark(chSectionBMark), m_chSectionEMark(chSectionEMark),
|
||||
m_chRecordEMark(chRecordEMark), m_chCommentMark(chCommentMark), m_bShowError(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CCfgFileParser() {}
|
||||
|
||||
typedef std::map<std::string, std::string> SECTION_CONTENT;
|
||||
typedef std::map<std::string, SECTION_CONTENT > FILE_CONTENT;
|
||||
|
||||
private:
|
||||
bool m_base64;
|
||||
enum{
|
||||
SYNTAX_ERROR = 0x100,
|
||||
};
|
||||
|
||||
public:
|
||||
bool m_bShowError;
|
||||
const char* getErrorString(int err);
|
||||
int parseFile(const char* lpszFilename);
|
||||
int sections() const { return m_content.size(); }
|
||||
|
||||
FILE_CONTENT::const_iterator sectionBegin() const { return m_content.begin(); }
|
||||
FILE_CONTENT::const_iterator sectionEnd() const { return m_content.end(); }
|
||||
|
||||
//return empty-string if no corresponding value presented.
|
||||
bool getValue(const std::string& strSection, const std::string& strKey, const char *&Value) const;
|
||||
bool getValue(const std::string& strKey, const char *&Value) const;
|
||||
bool getIntValue(const std::string& strSection, const std::string& strKey, long &pValue) const;
|
||||
bool getIntValue(const std::string& strKey, long &Value) const;
|
||||
bool getDoubleValue(const std::string& strSection, const std::string& strKey, double &Value) const;
|
||||
bool getDoubleValue(const std::string& strKey, double &Value) const;
|
||||
void printContent();
|
||||
|
||||
protected:
|
||||
bool extractSection(char* line, std::string& strSection);
|
||||
bool extractKeyValue(char* line, std::pair<std::string, std::string>& pairKeyValue);
|
||||
|
||||
private:
|
||||
FILE_CONTENT m_content;
|
||||
|
||||
char m_chSectionBMark;
|
||||
char m_chSectionEMark;
|
||||
char m_chRecordEMark;
|
||||
char m_chCommentMark;
|
||||
int m_error_line;
|
||||
};
|
||||
|
||||
extern "C" __attribute__((visibility("default"))) CCfgFileParser* createParser();
|
||||
|
||||
|
||||
extern "C" __attribute__((visibility("default"))) void deleteParser(CCfgFileParser* parser);
|
||||
|
||||
|
||||
#endif // !defined(AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_)
|
|
@ -1,44 +0,0 @@
|
|||
INCS = log.h CCfgFileParser.h
|
||||
SRCS = CCfgFileParser.cpp log.cpp dataqueue.cpp
|
||||
CXX = g++
|
||||
AR = ar
|
||||
EXEC_SO = libqueuelog.so
|
||||
EXEC_A = libqueuelog.a
|
||||
EXEC_O = libqueuelog.o
|
||||
|
||||
# 输出目录
|
||||
OUTPUT_LIB_DIR = ../../libs/
|
||||
OUTPUT_INCLUDE_DIR=../../includes/
|
||||
|
||||
|
||||
ifdef DEBUG_VERSION
|
||||
CFLAGS := -DMY_DEBUG -fvisibility=hidden -g -Wall -fPIC -shared -std=c++11 -Wl,--as-needed
|
||||
else
|
||||
CFLAGS := -fvisibility=hidden -g3 -O2 -Wall -fPIC -shared -std=c++11 -Wl,--as-needed
|
||||
endif
|
||||
|
||||
LFLAGS1 = -lpthread
|
||||
|
||||
OBJS = $(SRCS:.cpp=.o)
|
||||
|
||||
all: $(EXEC_SO) $(EXEC_A)
|
||||
|
||||
$(EXEC_SO): $(OBJS)
|
||||
$(CXX) -o $(EXEC_SO) $(OBJS) $(CFLAGS) $(LFLAGS1)
|
||||
|
||||
$(EXEC_A): $(OBJS)
|
||||
$(AR) rcs $(EXEC_A) $(OBJS)
|
||||
mkdir -p $(OUTPUT_LIB_DIR)
|
||||
mkdir -p $(OUTPUT_INCLUDE_DIR)
|
||||
mv $(EXEC_A) $(OUTPUT_LIB_DIR)
|
||||
mv $(EXEC_SO) $(OUTPUT_LIB_DIR)
|
||||
cp -u *.h $(OUTPUT_INCLUDE_DIR)
|
||||
find . -name "*.d" -type f -print -exec rm -rf {} \;
|
||||
@echo "Compile successfully! result-->" $(OUTPUT_LIB_DIR)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(EXEC_SO) $(EXEC_A) $(EXEC_O) $(OBJS)
|
|
@ -1,11 +0,0 @@
|
|||
#!/bin/sh
|
||||
#rm -f *.so *.o
|
||||
CUR=$(basename `pwd`)
|
||||
echo $CUR
|
||||
mkdir -p ../../_backup
|
||||
tar --exclude=*.so --exclude=*.a --exclude=*.o --exclude=*.d --exclude=./.vs --exclude=*.git* --exclude=*.swp -czvf ../../_backup/${CUR}-`date +"%Y.%m.%d-%H.%M"`.tar.gz ../${CUR}/*
|
||||
#tar -czvf ../_backup/${CUR}-`date +"%Y.%m.%d-%H.%M"`.tar.gz ../${CUR}
|
||||
curDate=$(date +"%Y.%m.%d %H:%M:%S")
|
||||
echo backup done!@${curDate}
|
||||
|
||||
|
|
@ -1,537 +0,0 @@
|
|||
//#pragma once
|
||||
#include <time.h>
|
||||
#include "dataqueue.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define BLOCK_PADDING_SIZE 64 //bytes
|
||||
#define HEADER_BYTES 16//remain: block-bytes: 8 bytes int64_t + data bytes: 8bytes int64_t
|
||||
#define CHECK_QUEUE_ERR 1
|
||||
#define myMax(x,y) ((x)>(y)?(x):(y))
|
||||
|
||||
typedef void* voidPtr;
|
||||
static char g_strDQCurTime[50] = "";
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
inline char* GetCurTimeStr(char* strBuf, int iBufSize)// g_strDQCurTime
|
||||
{
|
||||
time_t tt;
|
||||
tt = time(NULL);
|
||||
strftime(strBuf, iBufSize, "%Y.%m.%d %H:%M:%S", localtime(&tt));//gener string with format:"YYYY-MM-DD hh:mm:ss"
|
||||
return strBuf;
|
||||
}
|
||||
#define DATA_QUEUE_RETAIN_BLOCK_CNT 4
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
DataQueue::DataQueue(int64_t iSizeInKB, int64_t iMaxBlockSize, bool bUseMutex, int iReadThreadCnt)
|
||||
{
|
||||
m_pDataBuf = NULL;
|
||||
m_bUseMutex = bUseMutex;
|
||||
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_init(&m_BufMutex, NULL);
|
||||
InitQueue(iSizeInKB, iMaxBlockSize, iReadThreadCnt);//KB
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
DataQueue::~DataQueue()
|
||||
{
|
||||
if (m_pDataBuf != NULL)
|
||||
free((void*)m_pDataBuf);
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_destroy(&m_BufMutex);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int DataQueue::InitQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockBytes, int iReadThreadCnt)//KB
|
||||
{
|
||||
if (m_pDataBuf != NULL)
|
||||
free((void*)m_pDataBuf);
|
||||
m_pDataBuf = NULL;
|
||||
m_iMaxBlockByte = iMaxBlockBytes;
|
||||
m_iReservedBlockNum = iReadThreadCnt + DATA_QUEUE_RETAIN_BLOCK_CNT;
|
||||
m_iReservedBufBytes = m_iMaxBlockByte * m_iReservedBlockNum; //4 times of m_iMaxBlockByte
|
||||
int64_t iTotalByes = 0;
|
||||
if (iTotalKB4QueueBuf > 0)
|
||||
{
|
||||
iTotalByes = iTotalKB4QueueBuf * 1024 + 2 * HEADER_BYTES + m_iReservedBufBytes; //KB;
|
||||
m_pDataBuf = (uint8_t*)malloc(iTotalByes); //for safe sake in case of over step the border
|
||||
if (m_pDataBuf == NULL)
|
||||
{
|
||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
||||
GetCurTimeStr(g_strDQCurTime, sizeof(g_strDQCurTime));
|
||||
fprintf(stderr, "***Error: fail to malloc for data queue, mem:%ld @line:%d %s\n", iTotalKB4QueueBuf, __LINE__, g_strDQCurTime);
|
||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
||||
fflush(stderr);
|
||||
exit(4);
|
||||
}
|
||||
}
|
||||
m_iFreeBytes = m_iQueueBufBytes = iTotalByes;
|
||||
ResetDataQueue();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void DataQueue::ResetDataQueue()
|
||||
{
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_lock(&m_BufMutex);
|
||||
m_iBufOutPos = m_iBufInPos = 0;
|
||||
m_iRcvBlocks = 0;
|
||||
m_iRcvBytes = 0;
|
||||
m_iProcBlocks = 0;
|
||||
m_iEmptyTimes = 0;
|
||||
m_iFullTimes = 0;
|
||||
m_iPaddingBlocks = m_iProcPaddingBlocks = 0;
|
||||
m_iFreeBytes = m_iQueueBufBytes;
|
||||
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int64_t DataQueue::GetBufBytes()
|
||||
{//Get buf size
|
||||
int64_t iBytes;
|
||||
iBytes = m_iQueueBufBytes - m_iReservedBufBytes;
|
||||
if (iBytes < 0)
|
||||
iBytes = 0;
|
||||
return iBytes;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int64_t DataQueue::GetQueueFreeBytes()
|
||||
{
|
||||
//int64_t iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : ((m_iBufOutPos - m_iBufInPos) ) );
|
||||
int64_t iFreeBytes;
|
||||
|
||||
iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : ((m_iBufOutPos - m_iBufInPos)));
|
||||
iFreeBytes -= m_iReservedBufBytes;
|
||||
if (iFreeBytes < 0)//iFreeBytes never is 0 because of m_iReservedBufBytes, unless the beginning state where m_iBufOutPos and m_iBufInPos are same
|
||||
iFreeBytes = 0;
|
||||
|
||||
return iFreeBytes;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int64_t DataQueue::GetFreeBytes()
|
||||
{
|
||||
return GetQueueFreeBytes();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
inline bool DataQueue::CanRcv(int iNeedBytes)
|
||||
{
|
||||
bool bCanRcv;
|
||||
m_iMaxBlockByte = iNeedBytes > m_iMaxBlockByte ? iNeedBytes : m_iMaxBlockByte;
|
||||
m_iReservedBufBytes = m_iMaxBlockByte * m_iReservedBlockNum; //4<><34><EFBFBD><EFBFBD>m_iMaxBlockByte
|
||||
|
||||
bCanRcv = (GetQueueFreeBytes() >= iNeedBytes);
|
||||
|
||||
return bCanRcv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool DataQueue::IsFull()
|
||||
{
|
||||
//---- 这种判断方式,可能存在错误,即:期间m_iBufOutPos到尾部,折回到队列开头,变得小于m_iBufInPos
|
||||
//int iFreeBytes = (m_iBufInPos < m_iBufOutPos ? (m_iBufOutPos - m_iBufInPos) : (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)));//
|
||||
bool bFull;
|
||||
int64_t iFreeBytes;
|
||||
iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : ((m_iBufOutPos - m_iBufInPos)));
|
||||
bFull = (iFreeBytes <= m_iReservedBufBytes);
|
||||
// if( bFull )
|
||||
// printf("dataqueue is full, size:%ld free:%ld - %ld < retain:%ld in:%ld out:%ld\n",
|
||||
// m_iQueueBufBytes,iFreeBytes, GetFreeBytes(),m_iReservedBufBytes,m_iBufInPos,m_iBufOutPos );
|
||||
return bFull;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool DataQueue::IsEmpty()
|
||||
{
|
||||
return (m_iBufInPos == m_iBufOutPos);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int64_t DataQueue::EnQueue(void* e, int64_t iDataBytes, void* extradata, int64_t iExtraDataBytes, void* extradata2, int64_t iExtraDataBytes2)
|
||||
{ // >=0 for normal & success,
|
||||
//<0: error
|
||||
int64_t iBlockBytes;
|
||||
void* pWritePos = NULL;
|
||||
int64_t iPadding = 0;
|
||||
if (iDataBytes < 0 || iExtraDataBytes < 0 || iExtraDataBytes2 < 0)
|
||||
{
|
||||
fprintf(stderr, "iDataBytes %ld iExtraDataBytes %ld iExtraDataBytes %ld\n",
|
||||
iDataBytes, iExtraDataBytes, iExtraDataBytes2);
|
||||
fflush(stderr);
|
||||
throw __LINE__;
|
||||
}
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_lock(&m_BufMutex);
|
||||
|
||||
int64_t iTotalDataBytes = iDataBytes + iExtraDataBytes + iExtraDataBytes2;
|
||||
#if CHECK_QUEUE_ERR
|
||||
CheckQueue(__LINE__, 0);
|
||||
#endif
|
||||
|
||||
iBlockBytes = (((iTotalDataBytes + 7) >> 3) << 3)//8<>ı<EFBFBD><C4B1><EFBFBD>
|
||||
+ HEADER_BYTES
|
||||
+ BLOCK_PADDING_SIZE;// 32
|
||||
|
||||
if (!CanRcv(iBlockBytes))
|
||||
{
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
return QUEUE_IS_FULL;
|
||||
}
|
||||
|
||||
if (m_iBufInPos >= m_iBufOutPos)
|
||||
{
|
||||
if (m_iBufInPos + iBlockBytes > m_iQueueBufBytes)
|
||||
{//create a padding block
|
||||
*((int64_t*)(m_pDataBuf + m_iBufInPos)) = m_iQueueBufBytes - m_iBufInPos; //m_iQueueBufBytes: the next block is at the begining of the buf
|
||||
*((int64_t*)(m_pDataBuf + m_iBufInPos + sizeof(int64_t))) = 0;
|
||||
//m_iRcvBlocks++;
|
||||
//printf("+iBlockBytes:%d, iDataByte:%d\n", m_iQueueBufBytes - m_iBufInPos, 0);
|
||||
m_iPaddingBlocks++;
|
||||
iPadding++;
|
||||
m_iBufInPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if CHECK_QUEUE_ERR
|
||||
CheckQueue(__LINE__, iBlockBytes);
|
||||
#endif
|
||||
|
||||
pWritePos = m_pDataBuf + m_iBufInPos;
|
||||
*((int64_t*)pWritePos) = iBlockBytes;
|
||||
*((int64_t*)(pWritePos + sizeof(int64_t))) = iTotalDataBytes;
|
||||
|
||||
memcpy(pWritePos + HEADER_BYTES, e, iDataBytes);
|
||||
|
||||
if (extradata && iExtraDataBytes > 0)
|
||||
memcpy(pWritePos + HEADER_BYTES + iDataBytes, extradata, iExtraDataBytes);//iExtraDataBytes
|
||||
|
||||
if (extradata2 && iExtraDataBytes2 > 0)
|
||||
memcpy(pWritePos + HEADER_BYTES + iDataBytes + iExtraDataBytes, extradata2, iExtraDataBytes2);//iExtraDataBytes
|
||||
|
||||
m_iRcvBlocks++;
|
||||
m_iRcvBytes += iTotalDataBytes;
|
||||
m_iBufInPos = (m_iBufInPos + iBlockBytes) % m_iQueueBufBytes;
|
||||
|
||||
//#ifdef MY_DEBUG
|
||||
// printf("+iBlockBytes:%d, iDataByte:%d\n", iBlockBytes, iDataBytes);
|
||||
//#endif
|
||||
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
|
||||
return iTotalDataBytes;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifdef ARM_VERSION //NO_PORN_FUNC
|
||||
#define THERE_ARE_CONCURRENT_DEQUEUE_OP 1
|
||||
#else
|
||||
#define THERE_ARE_CONCURRENT_DEQUEUE_OP 1
|
||||
#endif
|
||||
|
||||
int64_t DataQueue::DeQueue(void** e)
|
||||
{//return value: Bytes, >0 if sucess, =0 no data, < 0 error. No data copy, only return the pointer of data area
|
||||
void* p;
|
||||
int iBlockBytes, iDataBytes;
|
||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
||||
if (m_bUseMutex)
|
||||
{
|
||||
pthread_mutex_lock(&m_BufMutex);
|
||||
#if CHECK_QUEUE_ERR
|
||||
CheckQueue(__LINE__, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEmpty())
|
||||
{
|
||||
//#ifdef MY_DEBUG
|
||||
// m_iEmptyTimes++;
|
||||
// if ( m_iEmptyTimes <5 || ( m_iEmptyTimes % 50 == 0) )
|
||||
// {
|
||||
// printf("***Block Queue IsEmpty %1dth: m_iBufInPos=%lu, m_iBufOutPos=%lu, m_iQueueBufBytes=%lu, m_iReservedBufBytes=%lu\n",
|
||||
// m_iEmptyTimes, m_iBufInPos, m_iBufOutPos, m_iQueueBufBytes, m_iReservedBufBytes); //<2F>ճ<EFBFBD>4<EFBFBD><34>
|
||||
// fflush(stdout);
|
||||
// }
|
||||
//#endif
|
||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
#endif
|
||||
return EMPTY_QUEUE_NO_DATA;
|
||||
}
|
||||
|
||||
p = m_pDataBuf + m_iBufOutPos;
|
||||
iBlockBytes = *((int64_t*)p);
|
||||
iDataBytes = *((int64_t*)(p + sizeof(int64_t)));
|
||||
//int iDataBytes = *((int*)(p + sizeof(int)));
|
||||
m_iBufOutPos = (m_iBufOutPos + iBlockBytes) % m_iQueueBufBytes;
|
||||
//#ifdef MY_DEBUG
|
||||
// printf("-iBlockBytes:%d, iDataByte:%d\n", iBlockBytes, iDataBytes);
|
||||
//#endif
|
||||
|
||||
if (iDataBytes > 0)//not pading block
|
||||
{
|
||||
m_iProcBlocks++;
|
||||
*e = (void*)(p + HEADER_BYTES);
|
||||
|
||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
#endif
|
||||
return iDataBytes;
|
||||
}
|
||||
else//padding block
|
||||
{
|
||||
m_iProcPaddingBlocks++;
|
||||
if (IsEmpty())
|
||||
{
|
||||
//printf("CSegmentPool IsEmpty\n");
|
||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
#endif
|
||||
|
||||
return EMPTY_QUEUE_NO_DATA;
|
||||
}
|
||||
p = m_pDataBuf + m_iBufOutPos;
|
||||
iBlockBytes = *((int64_t*)p);
|
||||
iDataBytes = *((int64_t*)(p + sizeof(int64_t)));
|
||||
//#ifdef MY_DEBUG
|
||||
// printf("-iBlockBytes:%d, iDataByte:%d\n", iBlockBytes, iDataBytes);
|
||||
//#endif
|
||||
m_iBufOutPos = (m_iBufOutPos + iBlockBytes) % m_iQueueBufBytes;
|
||||
|
||||
#if CHECK_QUEUE_ERR
|
||||
if (m_bUseMutex)
|
||||
CheckQueue(__LINE__, 0);
|
||||
#endif
|
||||
|
||||
if (iDataBytes > 0)//not pading block
|
||||
{
|
||||
m_iProcBlocks++;
|
||||
*e = (void*)(p + HEADER_BYTES);
|
||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
#endif
|
||||
return iDataBytes;
|
||||
}
|
||||
else
|
||||
{//pading block
|
||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
#endif
|
||||
m_iProcPaddingBlocks++;
|
||||
char strMsg[200];
|
||||
GetCurTimeStr(g_strDQCurTime, sizeof(g_strDQCurTime));
|
||||
sprintf(strMsg, "***Error in DeQueue: 2 successive padding block!@line %d %s\n", __LINE__, g_strDQCurTime);
|
||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
||||
fprintf(stderr, "%s", strMsg);
|
||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
||||
fflush(stderr);
|
||||
exit(0);
|
||||
return EMPTY_QUEUE_NO_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
||||
if (m_bUseMutex)
|
||||
pthread_mutex_unlock(&m_BufMutex);
|
||||
#endif
|
||||
char strMsg[200];
|
||||
GetCurTimeStr(g_strDQCurTime, sizeof(g_strDQCurTime));
|
||||
sprintf(strMsg, "***Error in DeQueue: @line %d %s\n", __LINE__, g_strDQCurTime);
|
||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
||||
fprintf(stderr, "%s", strMsg);
|
||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
||||
fflush(stderr);
|
||||
exit(0);
|
||||
return EMPTY_QUEUE_NO_DATA;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void DataQueue::OutPutStatus(char* strBuf, int iBufLen)
|
||||
{
|
||||
int iLen = iBufLen, iStrLen;
|
||||
char* p = strBuf;
|
||||
snprintf(p, iLen, "m_iBufOutPos = % ld, m_iBufInPos = % ld, m_iFreeBytes = % ld, m_iQueueBufBytes = % ld, m_iRcvBlocks = % ld, m_iRcvBytes = % ld\n",
|
||||
m_iBufOutPos, m_iBufInPos, m_iFreeBytes, m_iQueueBufBytes, m_iRcvBlocks, m_iRcvBytes);
|
||||
iStrLen = strlen(p);
|
||||
p += iStrLen;
|
||||
iLen -= iStrLen;
|
||||
|
||||
snprintf(p, iLen, "\m_iProcBlocks=%ld, m_iPaddingBlocks=%ld, m_iProcPaddingBlocks=%ld, m_iMaxBlockByte=%ld, m_iReservedBufBytes=%ld, m_iReservedBlockNum=%ld,m_iEmptyTimes=%ld, m_iFullTimes=%ld\n",
|
||||
m_iProcBlocks, m_iPaddingBlocks, m_iProcPaddingBlocks, m_iMaxBlockByte, m_iReservedBufBytes, m_iReservedBlockNum, m_iEmptyTimes, m_iFullTimes);
|
||||
iStrLen = strlen(p);
|
||||
p += iStrLen;
|
||||
iLen -= iStrLen;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool DataQueue::CheckQueue(int iLineNo, int iNeedBytes)
|
||||
{
|
||||
int64_t iFreeBytes;
|
||||
int iErr = 0;
|
||||
//int iFreeBytes = (m_iBufInPos < m_iBufOutPos ? (m_iBufOutPos - m_iBufInPos) : (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) );//
|
||||
|
||||
iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : (m_iBufOutPos - m_iBufInPos));
|
||||
if (m_iBufOutPos < 0)
|
||||
iErr |= 0x1;
|
||||
if (m_iBufInPos < 0)
|
||||
iErr |= 0x2;
|
||||
if (iFreeBytes < (m_iReservedBlockNum - 2) * m_iMaxBlockByte)
|
||||
iErr |= 0x4;
|
||||
if (iFreeBytes < iNeedBytes)
|
||||
iErr |= 0x8;
|
||||
|
||||
if (m_bUseMutex && (m_iProcBlocks == m_iRcvBlocks)
|
||||
&& (m_iPaddingBlocks == m_iProcPaddingBlocks)
|
||||
&& (m_iBufOutPos != m_iBufInPos))
|
||||
iErr |= 0x10;
|
||||
if (iErr)
|
||||
{
|
||||
char strMsg[1000];
|
||||
char strInfo[1000];
|
||||
OutPutStatus(strMsg, sizeof(strMsg));
|
||||
snprintf(strInfo, sizeof(strInfo), "******QueueError %d @line %d, iFreeBytes=%ld , iNeedBytes=%d:\n%s \n",
|
||||
iErr, iLineNo, iFreeBytes, iNeedBytes, strMsg);
|
||||
|
||||
FILE* fp = fopen("err.log", "a+");
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp, "%s\n", strInfo);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
||||
fprintf(stderr, "%s\n", strInfo);
|
||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
||||
fflush(stderr);
|
||||
//throw __LINE__;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenDataQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockBytes, int iReadThreadCnt)
|
||||
{
|
||||
//DataQueue* p = new DataQueue(iTotalKB4QueueBuf, iMaxBlockBytes, bConcurrent);//bUseMutex = bConcurrent
|
||||
DataQueue* p = new DataQueue(iTotalKB4QueueBuf, iMaxBlockBytes, true);//bUseMutex = true
|
||||
return (void*)p;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" bool __attribute__((visibility("default"))) GetDataQueueInfo(void* pQueue, int64_t iSize[5])
|
||||
{//return the total data blocks, and set the buf with info string
|
||||
int64_t iFreeBytes, iBufBytes;
|
||||
DataQueue* p = (DataQueue*)pQueue;
|
||||
if (!pQueue)
|
||||
return false;
|
||||
iSize[0] = p->GetBufBytes();
|
||||
iSize[1] = p->GetFreeBytes();
|
||||
iSize[2] = p->GetTotalRcvBlockCnt();
|
||||
iSize[3] = p->GetProcBlockCnt();
|
||||
iSize[4] = p->GetBlockCnt();
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
#define LOG_QUEUE_INFO 0
|
||||
extern "C" int64_t __attribute__((visibility("default"))) EnDataQueue(void* pQueue, void* e, int64_t iDataBytes, void* extradata1, int64_t iExtraDataBytes1, void* extradata2, int64_t iExtraDataBytes2)
|
||||
{// int DataQueue::EnQueue(void* e, int64_t iDataBytes, void* extradata1, int64_t iExtraDataBytes1, void* extradata2, int64_t iExtraDataBytes2)
|
||||
int64_t iRet =0;
|
||||
if (pQueue)
|
||||
{
|
||||
#if LOG_QUEUE_INFO
|
||||
char strBuf[500];
|
||||
char strBuf2[500];
|
||||
FILE* fp = NULL;
|
||||
|
||||
snprintf(strBuf, sizeof(strBuf), "queue%p.log", pQueue);
|
||||
fp = fopen(strBuf, "a+");
|
||||
if (fp)
|
||||
{
|
||||
snprintf(strBuf, sizeof(strBuf), "EnQueue1: iDataBytes=%ld, extradata1=%ld, extradata2=%ld\n",
|
||||
iDataBytes, iExtraDataBytes1, iExtraDataBytes2);
|
||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
||||
fprintf(fp, "%s%s", strBuf, strBuf2);
|
||||
}
|
||||
#endif
|
||||
iRet = ((DataQueue*)pQueue)->EnQueue(e, iDataBytes, extradata1, iExtraDataBytes1, extradata2, iExtraDataBytes2);
|
||||
#if LOG_QUEUE_INFO
|
||||
if (fp)
|
||||
{
|
||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
||||
fprintf(fp, "EnQueue2: iRet=%ld\n%s\n\n", iRet, strBuf2);
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
extern "C" int64_t __attribute__((visibility("default"))) DeDataQueue(void* pQueue, void** e)
|
||||
{
|
||||
int64_t iRet = 0;
|
||||
|
||||
if (pQueue)
|
||||
{
|
||||
#if LOG_QUEUE_INFO
|
||||
char strBuf[500];
|
||||
char strBuf2[500];
|
||||
FILE* fp = NULL;
|
||||
|
||||
snprintf(strBuf, sizeof(strBuf), "queue%p.log", pQueue);
|
||||
fp = fopen(strBuf, "a+");
|
||||
if (fp)
|
||||
{
|
||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
||||
fprintf(fp, "DeQueue1: %s\n", strBuf2);
|
||||
}
|
||||
#endif
|
||||
|
||||
iRet = ((DataQueue*)pQueue)->DeQueue(e);
|
||||
|
||||
#if LOG_QUEUE_INFO
|
||||
if (fp)
|
||||
{
|
||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
||||
fprintf(fp, "DeQueue2: iRet=%ld\n%s\n\n", iRet, strBuf2);
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
extern "C" bool __attribute__((visibility("default"))) DataQueueIsFull(void* pQueue)
|
||||
{
|
||||
return ((DataQueue*)pQueue)->IsFull();
|
||||
}
|
||||
extern "C" void __attribute__((visibility("default"))) ResetDataQueue(void* pQueue)
|
||||
{//delete all data in the queue, and reset all counters to 0
|
||||
((DataQueue*)pQueue)->ResetDataQueue();
|
||||
}
|
||||
|
||||
|
||||
extern "C" void __attribute__((visibility("default"))) CloseDataQueue(void*& pQueue)
|
||||
{
|
||||
if (pQueue)
|
||||
delete (DataQueue*)pQueue;
|
||||
pQueue = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
//#pragma once
|
||||
#ifndef __HIT_DATAQUEUE_H
|
||||
#define __HIT_DATAQUEUE_H
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
#define MAX_BLOCK_BYTES (1024*1024*2)
|
||||
#define QUEUE_IS_FULL (-1)
|
||||
#define EMPTY_QUEUE_NO_DATA (0)
|
||||
|
||||
class DataQueue
|
||||
{
|
||||
public:
|
||||
DataQueue(int64_t iSizeInKB = 0, int64_t iMaxBlockSize = MAX_BLOCK_BYTES, bool bUseMutex = true, int iReadThreadCnt=1);
|
||||
~DataQueue();
|
||||
|
||||
//private:
|
||||
void* m_pDataBuf; //[DATA_BUF_LEN]
|
||||
int64_t m_iBufOutPos;
|
||||
int64_t m_iBufInPos;
|
||||
int64_t m_iFreeBytes;
|
||||
int64_t m_iQueueBufBytes;
|
||||
int64_t m_iRcvBlocks;//total count
|
||||
int64_t m_iRcvBytes;//total Bytes
|
||||
int64_t m_iProcBlocks;
|
||||
int64_t m_iPaddingBlocks;//padding block cnt in enqueue
|
||||
int64_t m_iProcPaddingBlocks;//processed padding block cnt in dequeue
|
||||
|
||||
int64_t m_iMaxBlockByte;
|
||||
int64_t m_iReservedBufBytes;
|
||||
int64_t m_iReservedBlockNum;
|
||||
int64_t m_iEmptyTimes;
|
||||
int64_t m_iFullTimes;
|
||||
bool m_bUseMutex;
|
||||
pthread_mutex_t m_BufMutex;//pthread_mutex_init(&m_BufMutex, NULL);
|
||||
|
||||
bool IsEmpty(); //
|
||||
bool IsFull();
|
||||
inline bool CanRcv(int iNeedBytes);
|
||||
|
||||
public:
|
||||
|
||||
int64_t EnQueue(void* pdata, int64_t iDataBytes = 0, void* extradata = NULL, int64_t iExtraDataBytes = 0, void* extradata2 = NULL, int64_t iExtraDataBytes2 = 0);
|
||||
int64_t DeQueue(void** pdata);//return value: Bytes, >0 if sucess, =0 no data, < 0 error. No data copy, only return the pointer of data area
|
||||
|
||||
uint64_t GetBlockCnt() {
|
||||
return m_iRcvBlocks - m_iProcBlocks;
|
||||
};
|
||||
int64_t GetProcBlockCnt() {
|
||||
return m_iProcBlocks;
|
||||
};
|
||||
int64_t GetTotalRcvBlockCnt() {
|
||||
return m_iRcvBlocks;
|
||||
};
|
||||
int64_t GetFreeBytes();
|
||||
int64_t GetBufBytes();
|
||||
inline int64_t GetQueueFreeBytes();
|
||||
|
||||
|
||||
int InitQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockKB = MAX_BLOCK_BYTES, int iReadThreadCnt = 1);//KB
|
||||
bool CheckQueue(int iLineNo, int iNeedBytes);
|
||||
void OutPutStatus(char* strBuf, int iLen);
|
||||
void ResetDataQueue();
|
||||
};
|
||||
|
||||
#define LOG_QUEUE_INFO 0
|
||||
typedef void* voidPtr;
|
||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenDataQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockBytes, int iReadThreadCnt);
|
||||
extern "C" bool __attribute__((visibility("default"))) GetDataQueueInfo(void* pQueue, int64_t iSize[5]);
|
||||
extern "C" int64_t __attribute__((visibility("default"))) EnDataQueue(void* pQueue, void* e, int64_t iDataBytes, void* extradata1, int64_t iExtraDataBytes1, void* extradata2, int64_t iExtraDataBytes2);
|
||||
extern "C" int64_t __attribute__((visibility("default"))) DeDataQueue(void* pQueue, void** e);
|
||||
extern "C" bool __attribute__((visibility("default"))) DataQueueIsFull(void* pQueue);
|
||||
extern "C" void __attribute__((visibility("default"))) ResetDataQueue(void* pQueue);
|
||||
extern "C" void __attribute__((visibility("default"))) CloseDataQueue(void*& pQueue);
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
#include "log.h"
|
||||
|
||||
namespace QUEUE_LOG_COFIG
|
||||
{
|
||||
void* WriteLogThread(void* param)
|
||||
{
|
||||
CLogFile* pLog = (CLogFile*)(param);
|
||||
pLog->writeQueue2File();//
|
||||
}
|
||||
}
|
||||
|
||||
using namespace QUEUE_LOG_COFIG;
|
||||
typedef void* voidPtr;
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenLogFile(const char* strPath, const char* strFileName, bool bLogByDay)
|
||||
{
|
||||
//CLogFile* p = new CLogFile(strPath, strFileName, bLogByDay, 1);//use queue
|
||||
CLogFile* p = new CLogFile(strPath, strFileName, false, 1);//use queue 2021.11.09
|
||||
return (voidPtr)p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
extern "C" int __attribute__((visibility("default"))) WriteLog(void* pLogFile, const char* fmt, ...)
|
||||
{
|
||||
if (!pLogFile)
|
||||
return -1;
|
||||
|
||||
char strInfo[INFO_BUF_LEN];
|
||||
va_list arglist;
|
||||
va_start(arglist, fmt);
|
||||
vsprintf(strInfo, fmt, arglist);
|
||||
va_end(arglist);
|
||||
((CLogFile*)pLogFile)->append_one_item(0, strInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
extern "C" void __attribute__((visibility("default"))) CloseLog(void* pLogFile)
|
||||
{
|
||||
((CLogFile*)pLogFile)->close_log_file();
|
||||
return;
|
||||
}
|
|
@ -1,287 +0,0 @@
|
|||
#ifndef __HIT_LOG_HEADER
|
||||
#define __HIT_LOG_HEADER
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include "dataqueue.h"
|
||||
#define INFO_BUF_LEN 4096//2048
|
||||
|
||||
typedef void* voidPtr;
|
||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenLogFile(const char* strPath, const char* strFileName, bool bLogByDay);
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
extern "C" int __attribute__((visibility("default"))) WriteLog(void* pLogFile, const char* fmt, ...);
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
extern "C" void __attribute__((visibility("default"))) CloseLog(void* pLogFile);
|
||||
|
||||
namespace QUEUE_LOG_COFIG
|
||||
{
|
||||
static uint64_t g_iLogFileMaxSize = 2L * 1024 * 1024 * 1024;
|
||||
static uint64_t g_iCheckLogInterval = 20;//20s
|
||||
|
||||
inline int checkdir(const char* sPathName)
|
||||
{
|
||||
char DirName[256];
|
||||
strcpy(DirName, sPathName);
|
||||
int i, len = strlen(DirName);
|
||||
if (DirName[len - 1] != '/')
|
||||
strcat(DirName, "/");
|
||||
|
||||
len = strlen(DirName);
|
||||
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if (DirName[i] == '/')
|
||||
{
|
||||
DirName[i] = 0;
|
||||
if (access(DirName, 0) != 0)
|
||||
{
|
||||
if (mkdir(DirName, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1)
|
||||
{
|
||||
perror(" mkdir error");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
DirName[i] = '/';
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
** log class, it is not thread safe.
|
||||
*/
|
||||
void* WriteLogThread(void* param);
|
||||
|
||||
struct InfoItem
|
||||
{
|
||||
struct tm t;
|
||||
bool bLogTime;
|
||||
char strInfo[INFO_BUF_LEN];
|
||||
int GetLen() { return (uint64_t)(&strInfo[0]) - (uint64_t)(this) + strlen(strInfo) + 1; }
|
||||
};
|
||||
|
||||
class CLogFile
|
||||
{
|
||||
private:
|
||||
char* log_filename;
|
||||
char* log_dirpath;
|
||||
char* log_fullpath_filename;
|
||||
int m_bRecordByDay;
|
||||
int current_day;
|
||||
FILE* file_handle;
|
||||
DataQueue m_InfoQueue; //
|
||||
bool m_bExit;
|
||||
bool m_bUseQueue;
|
||||
bool m_bWriteFinish;
|
||||
pthread_t m_pWriteThreadHandle;
|
||||
private:
|
||||
void set_log_fullpath_filename(struct tm* t)
|
||||
{
|
||||
if (log_fullpath_filename == NULL)
|
||||
log_fullpath_filename = (char*)calloc(strlen(log_dirpath) + 1 + 8 + 1 + strlen(log_filename) + 1 + 10, sizeof(char));
|
||||
if (m_bRecordByDay)
|
||||
{
|
||||
current_day = t->tm_mday;
|
||||
sprintf(log_fullpath_filename, "%s%02d%02d%02d/", log_dirpath, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
|
||||
}
|
||||
else
|
||||
sprintf(log_fullpath_filename, "%s", log_dirpath);
|
||||
|
||||
checkdir(log_fullpath_filename);
|
||||
strcat(log_fullpath_filename, log_filename);
|
||||
}
|
||||
void open_log_file()
|
||||
{
|
||||
file_handle = fopen(log_fullpath_filename, "a");
|
||||
if (file_handle == NULL)
|
||||
{//2019.07.18------------------
|
||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
||||
fprintf(stderr, "***Fatal error: can't open file: %s", log_fullpath_filename);
|
||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
struct tm* get_time()
|
||||
{
|
||||
time_t clock;
|
||||
time(&clock);
|
||||
struct tm* t = localtime(&clock);
|
||||
return t;
|
||||
}
|
||||
void print_time()
|
||||
{
|
||||
struct tm* t = get_time();
|
||||
fprintf(file_handle, "%4d-%02d-%02d %02d:%02d:%02d\n",
|
||||
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
}
|
||||
public:
|
||||
FILE* GetFileHande() { return file_handle; }
|
||||
CLogFile(const char* dir, const char* name, int byDay, bool bUseQueue = false)
|
||||
{
|
||||
m_bRecordByDay = byDay;
|
||||
m_bUseQueue = bUseQueue;
|
||||
file_handle = NULL;
|
||||
m_bWriteFinish = true;
|
||||
m_bExit = false;
|
||||
|
||||
log_dirpath = (char*)calloc(strlen(dir) + 10, sizeof(char));
|
||||
log_filename = (char*)calloc(strlen(name) + 10, sizeof(char));
|
||||
|
||||
strcpy(log_dirpath, dir);
|
||||
int i, len = strlen(log_dirpath);
|
||||
if (log_dirpath[len - 1] != '/')
|
||||
strcat(log_dirpath, "/");
|
||||
|
||||
strcpy(log_filename, name);
|
||||
log_fullpath_filename = NULL;
|
||||
struct tm* t = get_time();
|
||||
set_log_fullpath_filename(t);
|
||||
|
||||
open_log_file();
|
||||
if (bUseQueue)
|
||||
{
|
||||
m_InfoQueue.InitQueue(32 * 1024, 8 * 2048);
|
||||
pthread_create(&m_pWriteThreadHandle, NULL, WriteLogThread, this);
|
||||
}
|
||||
}
|
||||
~CLogFile()
|
||||
{
|
||||
m_bExit = true;
|
||||
pthread_join(m_pWriteThreadHandle, NULL);
|
||||
close_log_file();
|
||||
free(log_filename);
|
||||
free(log_dirpath);
|
||||
free(log_fullpath_filename);
|
||||
}
|
||||
void append_one_item(int print_time_flag, const char* fmt, ...)
|
||||
{//append the new info into the queue
|
||||
char fmtbuf[INFO_BUF_LEN];
|
||||
va_list arglist;
|
||||
if (m_bExit) return;
|
||||
|
||||
InfoItem tmpInfoItem;
|
||||
|
||||
va_start(arglist, fmt);
|
||||
vsprintf(fmtbuf, fmt, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
snprintf(tmpInfoItem.strInfo, sizeof(tmpInfoItem.strInfo), fmtbuf);
|
||||
tmpInfoItem.t = *get_time();
|
||||
tmpInfoItem.bLogTime = print_time_flag;
|
||||
|
||||
if (m_bUseQueue)
|
||||
m_InfoQueue.EnQueue((void*)(&tmpInfoItem), tmpInfoItem.GetLen());
|
||||
else
|
||||
{
|
||||
writeItem2File(&tmpInfoItem);
|
||||
}
|
||||
}
|
||||
void checksize(uint64_t iSize)
|
||||
{
|
||||
uint64_t iFileBytes = ftell(file_handle);
|
||||
|
||||
if (iFileBytes > iSize)
|
||||
{
|
||||
char strBackupName[500];
|
||||
char strCurTime[20];
|
||||
time_t tt;
|
||||
tt = time(NULL);
|
||||
strftime(strCurTime, sizeof(strCurTime), "%Y.%m.%d-%H.%M.%S", localtime(&tt));//产生“YYYY-MM-DD hh:mm:ss”格式的字符串。
|
||||
sprintf(strBackupName, "%s-bak%s", log_fullpath_filename, strCurTime);
|
||||
|
||||
close_log_file();
|
||||
rename(log_fullpath_filename, strBackupName);//把原文件重命名为新的文件名
|
||||
open_log_file();
|
||||
}
|
||||
};
|
||||
|
||||
void writeItem2File(InfoItem* pInfoItem)
|
||||
{
|
||||
if (file_handle == NULL)
|
||||
{//2019.07.18
|
||||
return;
|
||||
}
|
||||
int iBytes;
|
||||
if ((m_bRecordByDay) && (pInfoItem->t.tm_mday != current_day))
|
||||
{//change_to_new_day
|
||||
close_log_file();
|
||||
current_day = pInfoItem->t.tm_mday;
|
||||
set_log_fullpath_filename(&(pInfoItem->t));
|
||||
open_log_file();
|
||||
char strCmd[300];
|
||||
sprintf(strCmd, "find %s -type d -mtime +30 -exec rm -rf {} \\;", log_dirpath);
|
||||
system(strCmd);
|
||||
}
|
||||
|
||||
if (pInfoItem->bLogTime)
|
||||
{
|
||||
iBytes = fprintf(file_handle, "%s %4d.%02d.%02d %02d:%02d:%02d\n",
|
||||
pInfoItem->strInfo,
|
||||
pInfoItem->t.tm_year + 1900, pInfoItem->t.tm_mon + 1, pInfoItem->t.tm_mday,
|
||||
pInfoItem->t.tm_hour, pInfoItem->t.tm_min, pInfoItem->t.tm_sec);
|
||||
}
|
||||
else
|
||||
iBytes = fprintf(file_handle, "%s", pInfoItem->strInfo);
|
||||
|
||||
if (iBytes < 0)
|
||||
fprintf(stderr, "***writing \"%s\" to log failed! errno:%d, %s\n", pInfoItem->strInfo, errno, strerror(errno));
|
||||
else
|
||||
fflush(file_handle);
|
||||
}
|
||||
void writeQueue2File()
|
||||
{
|
||||
unsigned int iWiteItems = 0;
|
||||
InfoItem* pInfoItem;
|
||||
struct tm* t;
|
||||
m_bWriteFinish = false;
|
||||
unsigned n = 0;
|
||||
int iBytes;
|
||||
while (!m_bExit)
|
||||
{
|
||||
iBytes = m_InfoQueue.DeQueue((void**)(&pInfoItem));
|
||||
if (iBytes <= 0)
|
||||
{
|
||||
sleep(1);//10ms
|
||||
continue;
|
||||
}
|
||||
writeItem2File(pInfoItem);
|
||||
if ((++n % g_iCheckLogInterval == 0) && (!m_bRecordByDay))
|
||||
checksize(g_iLogFileMaxSize);// 2L * 1024 * 1024 * 1024);//不超过2GB
|
||||
}
|
||||
t = get_time();
|
||||
fprintf(file_handle, "...finish and exit! @%4d.%02d.%02d %02d:%02d:%02d\n\n",
|
||||
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
fflush(file_handle);
|
||||
m_bWriteFinish = true;
|
||||
}
|
||||
|
||||
void close_log_file()
|
||||
{
|
||||
if (file_handle != NULL)
|
||||
{
|
||||
fflush(file_handle);
|
||||
fclose(file_handle);
|
||||
file_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_expired_logs()
|
||||
{
|
||||
}
|
||||
};
|
||||
//void * WriteLogThread(void* param)
|
||||
//{
|
||||
// CLogFile *pLog = (CLogFile*)(param);
|
||||
// pLog->writeQueue2File();//
|
||||
//}
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
if echo "$@" | grep -iq r; then
|
||||
Param1="RELEASE_VERSION=yes"
|
||||
else
|
||||
Param1="DEBUG_VERSION=yes"
|
||||
fi
|
||||
|
||||
make clean
|
||||
clear
|
||||
if echo "$@" | grep -iq e; then
|
||||
#------ compile for euler -------------------
|
||||
make -j 4 $Param1 CXX=arm-ztkp_openeuler-linux-gnueabi-g++ AR=arm-ztkp_openeuler-linux-gnueabi-ar OUTPUT_LIB_DIR=../../libs-euler/
|
||||
else
|
||||
#------- compile for arm32 ------------------
|
||||
make -j 4 $Param1 CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar OUTPUT_LIB_DIR=../../libs-arm32/
|
||||
fi
|
||||
|
2
mak
2
mak
|
@ -19,5 +19,5 @@ fi
|
|||
|
||||
mkdir -p ${BUILD_PREFIX} && cd ${BUILD_PREFIX}
|
||||
rm -f CMakeCache.txt
|
||||
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} -DEXECUTABLE_OUTPUT_PATH=../../bin/${BUILD_PREFIX} ../..
|
||||
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} -DEXECUTABLE_OUTPUT_PATH=../../bin/${BUILD_PREFIX} -DLIBRARY_OUTPUT_PATH=../../lib/${BUILD_PREFIX} ../..
|
||||
cmake --build . -j 4 --
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
mkdir -p dist
|
||||
|
||||
zip -r "dist/exint-build-$(date +%Y%m%d-%H%M%S).zip" bin/ lib/ config/\
|
||||
scripts/ README.md
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
mkdir -p dist
|
||||
|
||||
tar -czvf "dist/exint-$(date +%Y%m%d-%H%M%S).tar.gz" src/ include/ tests/ config/\
|
||||
scripts/ toolchains/ tools/ README.md CMakeLists.txt mak .gitignore
|
|
@ -389,7 +389,7 @@ if __name__ == "__main__":
|
|||
for p in namespace.path:
|
||||
if '*' in p:
|
||||
paths.extend(glob(p, recursive=True))
|
||||
else:
|
||||
elif os.path.isfile(p):
|
||||
paths.append(p)
|
||||
for p in paths:
|
||||
f = CTestCaseFile(p)
|
||||
|
|
|
@ -60,9 +60,8 @@ int exint_init_from_tty(int host_com_tty, int telemetry_com_tty, et_callback_t c
|
|||
return 0;
|
||||
}
|
||||
|
||||
void exint_send(uint32_t type, size_t len, union PacketData data) {
|
||||
void exint_send(uint32_t type, size_t len, void* data) {
|
||||
const char* event_name;
|
||||
void* data_pointer = data.pd_pointer;
|
||||
switch (type) {
|
||||
case ET_TYPE_COMMAND:
|
||||
event_name = "send_command";
|
||||
|
@ -73,7 +72,7 @@ void exint_send(uint32_t type, size_t len, union PacketData data) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
exint_event(event_name, len, data_pointer);
|
||||
exint_event(event_name, len, data);
|
||||
}
|
||||
|
||||
void exint_finialize() {
|
||||
|
@ -83,6 +82,6 @@ void exint_finialize() {
|
|||
pthread_cancel(telemetry_thread);
|
||||
}
|
||||
|
||||
void exint_handle_pack(uint32_t type, size_t len, union PacketData data) {
|
||||
void exint_handle_pack(uint32_t type, size_t len, void* data) {
|
||||
et_callback(type, len, data);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ volatile bool g_bNeedReboot = false;
|
|||
volatile int32_t g_iMS2Reboot = 1000;
|
||||
|
||||
void get_telemetry_data(TelemetryRequestData* data) {
|
||||
exint_handle_pack(ET_TYPE_TELEMETRY_REQUEST, sizeof(TelemetryRequestData), { .pd_pointer = data });
|
||||
exint_handle_pack(ET_TYPE_TELEMETRY_REQUEST, sizeof(TelemetryRequestData), data);
|
||||
}
|
||||
|
||||
/* create a msg data for upper host telemetry*/
|
||||
|
@ -438,7 +438,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
|||
else
|
||||
//-------END 2024.10.23 noted by zgb
|
||||
*/
|
||||
exint_handle_pack(ET_TYPE_COMMAND, 6, {.pd_pointer = frame->payload});
|
||||
exint_handle_pack(ET_TYPE_COMMAND, 6, frame->payload);
|
||||
break;
|
||||
}
|
||||
case COM_FRAME_TYPE_SPEECH_INJECTED:
|
||||
|
@ -454,7 +454,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
|||
COM_FRAME_ADDRESS_VOIX,
|
||||
COM_FRAME_TYPE_SPEECH_INJECTED,
|
||||
payload, 6, true);
|
||||
exint_handle_pack(ET_TYPE_TEXT, 6, {.pd_pointer = f_data->payload});
|
||||
exint_handle_pack(ET_TYPE_TEXT, 6, f_data->payload);
|
||||
if (ComFrame_Send(tty_id, f_data, true)) {
|
||||
PrintFilePos(); fprintf(stderr, "send telemetry data frame error: %s\n", strerror(errno));
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
|||
PrintFilePos(); fprintf(stderr, " com frame interval %d\n", iIntervalTime);
|
||||
tLastTime = tCurTime;
|
||||
|
||||
exint_handle_pack(ET_TYPE_AUDIO, ComFrame_PAYLOAD_LENGTH(frame), {.pd_pointer = frame->payload});
|
||||
exint_handle_pack(ET_TYPE_AUDIO, ComFrame_PAYLOAD_LENGTH(frame), frame->payload);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
|||
if(!alarm)
|
||||
continue;
|
||||
|
||||
exint_handle_pack(ET_TYPE_TEXT, sizeof(alarm), {.pd_pointer = alarm});
|
||||
exint_handle_pack(ET_TYPE_TEXT, sizeof(alarm), alarm);
|
||||
|
||||
uint8_t payload[6] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
|
||||
ComFrame* f_data = ComFrame_New(
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <sstream>
|
||||
#include <atomic>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include "c_testcase.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define TEST_CASE_STATUS_PASSED 0
|
||||
|
@ -20,6 +24,8 @@ using namespace std;
|
|||
|
||||
#define MAX_TESTCASE 64
|
||||
|
||||
#define DEFAULT_TTY_COL_SIZE 80
|
||||
|
||||
struct TestCase {
|
||||
const char* name;
|
||||
test_case func;
|
||||
|
@ -34,6 +40,7 @@ static context_func teardown = NULL;
|
|||
|
||||
static atomic_bool testcase_running;
|
||||
static jmp_buf testcase_env;
|
||||
static std::thread::id testcase_thread_id;
|
||||
static int testcase_exit_code = 0;
|
||||
|
||||
int _add_test_case(const char* name, test_case func) {
|
||||
|
@ -62,18 +69,36 @@ int _set_teardown(context_func func) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) test_case_abort(int exit_code) {
|
||||
if (!testcase_running.load(std::memory_order_acquire)) {
|
||||
[[noreturn]] void test_case_abort(int exit_code) {
|
||||
auto tid = std::this_thread::get_id();
|
||||
if (!testcase_running.load(std::memory_order_acquire) || tid != testcase_thread_id) {
|
||||
exit(exit_code);
|
||||
}
|
||||
testcase_exit_code = exit_code;
|
||||
longjmp(testcase_env, 1);
|
||||
}
|
||||
|
||||
static __inline int get_tty_col(int fd) {
|
||||
static inline int get_tty_col(int fd) {
|
||||
#ifdef _WIN32
|
||||
// Windows
|
||||
HANDLE hConsole = (HANDLE)_get_osfhandle(fd);
|
||||
if (hConsole == INVALID_HANDLE_VALUE) {
|
||||
return DEFAULT_TTY_COL_SIZE; // 错误处理
|
||||
}
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) {
|
||||
return DEFAULT_TTY_COL_SIZE; // 错误处理
|
||||
}
|
||||
return csbi.srWindow.Right - csbi.srWindow.Left + 1; // 计算列数
|
||||
#else
|
||||
// POSIX (Linux, macOS, etc.)
|
||||
struct winsize size;
|
||||
ioctl(fd, TIOCGWINSZ,&size);
|
||||
return size.ws_col;
|
||||
if (ioctl(fd, TIOCGWINSZ, &size) == -1) {
|
||||
return DEFAULT_TTY_COL_SIZE; // 错误处理
|
||||
}
|
||||
return size.ws_col; // 返回列数
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void print_separator(char lc) {
|
||||
|
@ -140,6 +165,7 @@ static int run_test_case_func(test_case func) {
|
|||
if (setjmp(testcase_env)) {
|
||||
return testcase_exit_code;
|
||||
}
|
||||
testcase_thread_id = std::this_thread::get_id();
|
||||
int ret = func();
|
||||
running = true;
|
||||
if (!testcase_running.compare_exchange_strong(running, false, std::memory_order_acq_rel)) {
|
||||
|
|
|
@ -9,16 +9,16 @@
|
|||
#include "c_testcase.h"
|
||||
|
||||
static int g_telemetry_request_count = 0;
|
||||
static DataQueue<std::tuple<uint32_t, size_t, PacketData>> g_data_queue;
|
||||
static DataQueue<std::tuple<uint32_t, size_t, void*>> g_data_queue;
|
||||
static int host_com_master_id;
|
||||
static int telemetry_com_master_id;
|
||||
|
||||
void exint_data_callback(uint32_t type, size_t size, PacketData data) {
|
||||
void exint_data_callback(uint32_t type, size_t size, void* data) {
|
||||
if (type == ET_TYPE_TELEMETRY_REQUEST) {
|
||||
g_telemetry_request_count++;
|
||||
memset(data.pd_pointer, 0, size);
|
||||
((TelemetryRequestData*)data.pd_pointer)->app_ver_high = 1;
|
||||
((TelemetryRequestData*)data.pd_pointer)->app_ver_low = 2;
|
||||
memset(data, 0, size);
|
||||
((TelemetryRequestData*)data)->app_ver_high = 1;
|
||||
((TelemetryRequestData*)data)->app_ver_low = 2;
|
||||
} else {
|
||||
g_data_queue.Push(std::make_tuple(type, size, data));
|
||||
}
|
||||
|
@ -80,6 +80,21 @@ TEST_CASE(test_host_telemetry) {
|
|||
END_TEST;
|
||||
}
|
||||
|
||||
TEST_CASE(test_callback) {
|
||||
uint8_t command[] = { 0x00, 0x01, 0x02, 0x03, 0xAA, 0xAA};
|
||||
auto command_msg = ComFrame_New(COM_FRAME_ADDRESS_VOIX, COM_FRAME_TYPE_COMMAND, command, sizeof(command), true);
|
||||
assert(!ComFrame_Send(host_com_master_id, command_msg, true));
|
||||
|
||||
uint32_t tp;
|
||||
size_t len;
|
||||
void* pack;
|
||||
std::tie(tp, len, pack) = g_data_queue.Pop(std::chrono::milliseconds(1000));
|
||||
assert_eq(tp, ET_TYPE_COMMAND);
|
||||
assert_eq(len, sizeof(command));
|
||||
assert_mem_eq(command, pack, len);
|
||||
END_TEST;
|
||||
}
|
||||
|
||||
TEST_CASE(test_send_command) {
|
||||
ComFrame* command_frame = NULL;
|
||||
bool timeout_flag = true;
|
||||
|
@ -89,8 +104,9 @@ TEST_CASE(test_send_command) {
|
|||
command_frame = ComFrame_ReceiveEx(host_com_master_id, NULL, 100, &offset, &cached_size, &timeout_flag, true);
|
||||
}).detach();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
char command_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
|
||||
exint_send(ET_TYPE_COMMAND, 6, { .pd_pointer = command_data });
|
||||
exint_send(ET_TYPE_COMMAND, 6, command_data );
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
@ -102,7 +118,6 @@ TEST_CASE(test_send_command) {
|
|||
assert(command_frame);
|
||||
assert_eq(ComFrame_TYPE(command_frame), COM_FRAME_TYPE_REQUEST);
|
||||
assert_eq(ComFrame_PAYLOAD_LENGTH(command_frame), 6);
|
||||
assert_eq(ComFrame_PAYLOAD(command_frame)[0], 0x00);
|
||||
assert_eq(ComFrame_PAYLOAD(command_frame)[5], 0x05);
|
||||
assert_mem_eq(ComFrame_PAYLOAD(command_frame), command_data, 6);
|
||||
END_TEST;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ TEST_CASE(test_clear) {
|
|||
}
|
||||
throw std::runtime_error("QueueException not thrown");
|
||||
});
|
||||
usleep(100);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
q.Clear();
|
||||
t.join();
|
||||
END_TEST;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
|
||||
set(CMAKE_C_COMPILER arm-none-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-none-linux-gnueabihf-g++)
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
###################################################################################
|
||||
project(libgo)
|
||||
|
||||
enable_language(C ASM)
|
||||
|
||||
if (CMAKE_BUILD_TYPE)
|
||||
else()
|
||||
set(CMAKE_BUILD_TYPE RELEASE)
|
||||
#set(CMAKE_BUILD_TYPE DEBUG)
|
||||
endif()
|
||||
|
||||
message("------------ Options -------------")
|
||||
message(" CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
||||
message(" CMAKE_COMMAND: ${CMAKE_COMMAND}")
|
||||
|
||||
option(ENABLE_DEBUGGER "enable debugger" OFF)
|
||||
if (ENABLE_DEBUGGER)
|
||||
set(ENABLE_DEBUGGER 1)
|
||||
message (" enable_debugger: yes")
|
||||
else()
|
||||
set(ENABLE_DEBUGGER 0)
|
||||
message (" enable_debugger: no")
|
||||
endif()
|
||||
|
||||
option(DISABLE_HOOK "disable hook" OFF)
|
||||
if (DISABLE_HOOK)
|
||||
set(ENABLE_HOOK 0)
|
||||
message (" enable_hook: no")
|
||||
else()
|
||||
set(ENABLE_HOOK 1)
|
||||
message (" enable_hook: yes")
|
||||
endif()
|
||||
|
||||
if (BUILD_DYNAMIC)
|
||||
message (" build dynamic lib: yes")
|
||||
else()
|
||||
message (" build dynamic lib: no")
|
||||
endif()
|
||||
|
||||
message("-------------- Env ---------------")
|
||||
message(" CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
|
||||
message(" CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
|
||||
message("----------------------------------")
|
||||
|
||||
configure_file(${PROJECT_SOURCE_DIR}/libgo/common/cmake_config.h.in ${PROJECT_SOURCE_DIR}/libgo/common/cmake_config.h)
|
||||
message("----------------------------------")
|
||||
|
||||
if (UNIX)
|
||||
set(CMAKE_CXX_FLAGS "-std=c++17 -fPIC -Wall ${CMAKE_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -DNDEBUG")
|
||||
|
||||
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS S)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
message(STATUS "> CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
|
||||
set(ASM_DIR "${PROJECT_SOURCE_DIR}/third_party/boost.context/libs/context/src/asm/")
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm")
|
||||
set(jump_asm_file "${ASM_DIR}jump_arm_aapcs_elf_gas.S")
|
||||
set(make_asm_file "${ASM_DIR}make_arm_aapcs_elf_gas.S")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
set(jump_asm_file "${ASM_DIR}jump_arm64_aapcs_elf_gas.S")
|
||||
set(make_asm_file "${ASM_DIR}make_arm64_aapcs_elf_gas.S")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
set(jump_asm_file "${ASM_DIR}jump_x86_64_sysv_elf_gas.S")
|
||||
set(make_asm_file "${ASM_DIR}make_x86_64_sysv_elf_gas.S")
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") # macOS
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||
set(jump_asm_file "${ASM_DIR}jump_arm64_aapcs_macho_gas.S")
|
||||
set(make_asm_file "${ASM_DIR}make_arm64_aapcs_macho_gas.S")
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86")
|
||||
set(jump_asm_file "${ASM_DIR}jump_i386_ms_pe_gas.asm")
|
||||
set(make_asm_file "${ASM_DIR}make_i386_ms_pe_gas.asm")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
set(jump_asm_file "${ASM_DIR}jump_x86_64_ms_pe_gas.asm")
|
||||
set(make_asm_file "${ASM_DIR}make_x86_64_ms_pe_gas.asm")
|
||||
endif()
|
||||
endif()
|
||||
if (NOT jump_asm_file OR NOT make_asm_file)
|
||||
message(FATAL_ERROR "--> select asm source file failed")
|
||||
return()
|
||||
endif()
|
||||
file(COPY ${jump_asm_file} DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
||||
file(COPY ${make_asm_file} DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
||||
else()
|
||||
message("--> select asm source file, please wait about 5 seconds ...")
|
||||
execute_process(COMMAND "${PROJECT_SOURCE_DIR}/third_party/select_asm.sh" "${PROJECT_SOURCE_DIR}" "jump" OUTPUT_VARIABLE jump_asm_file)
|
||||
execute_process(COMMAND "${PROJECT_SOURCE_DIR}/third_party/select_asm.sh" "${PROJECT_SOURCE_DIR}" "make" OUTPUT_VARIABLE make_asm_file)
|
||||
endif()
|
||||
|
||||
# 输出选择的汇编文件路径
|
||||
message(STATUS "Jump ASM File: ${jump_asm_file}")
|
||||
message(STATUS "Make ASM File: ${make_asm_file}")
|
||||
elseif (WIN32)
|
||||
# windows platform
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd /EHsc")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /EHsc")
|
||||
|
||||
#set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm)
|
||||
#file(COPY ${PROJECT_SOURCE_DIR}/third_party/boost.context/libs/context/src/asm/make_x86_64_ms_pe_masm.asm DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
||||
#file(COPY ${PROJECT_SOURCE_DIR}/third_party/boost.context/libs/context/src/asm/jump_x86_64_ms_pe_masm.asm DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
||||
endif()
|
||||
|
||||
message("------------ Cxx flags -------------")
|
||||
message(" CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}: ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
|
||||
message("------------------------------------")
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR})
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/common CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/context CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/task CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/scheduler CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/sync CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/timer CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/cls CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/defer CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/pool CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/debug CO_SRC_LIST)
|
||||
|
||||
if (NOT DISABLE_HOOK)
|
||||
if (UNIX)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/netio/unix CO_SRC_LIST)
|
||||
elseif (WIN32)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/libgo/netio/windows)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/netio/windows CO_SRC_LIST)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/context/fiber CO_SRC_LIST)
|
||||
list(APPEND CO_SRC_LIST ${PROJECT_SOURCE_DIR}/libgo/netio/windows/xhook/xhook.cpp)
|
||||
endif()
|
||||
else()
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/netio/disable_hook CO_SRC_LIST)
|
||||
endif()
|
||||
|
||||
set(TARGET "libgo")
|
||||
set(STATIC_T "libgo_static")
|
||||
set(STATIC_HOOK "static_hook")
|
||||
|
||||
list(APPEND CO_SRC_LIST ${jump_asm_file})
|
||||
list(APPEND CO_SRC_LIST ${make_asm_file})
|
||||
add_library("${STATIC_T}" STATIC ${CO_SRC_LIST})
|
||||
set_target_properties("${STATIC_T}" PROPERTIES OUTPUT_NAME "${TARGET}")
|
||||
|
||||
if (UNIX)
|
||||
install(TARGETS ${STATIC_T} LIBRARY DESTINATION "lib" ARCHIVE DESTINATION "lib")
|
||||
install(DIRECTORY ${PROJECT_SOURCE_DIR}/libgo/ DESTINATION "include/libgo" FILES_MATCHING PATTERN "*.h")
|
||||
#PATTERN "windows" EXCLUDE
|
||||
|
||||
add_library("${STATIC_HOOK}" STATIC "${PROJECT_SOURCE_DIR}/libgo/netio/unix/static_hook/static_hook.cpp")
|
||||
|
||||
if (BUILD_DYNAMIC)
|
||||
set(SHARED_T "libgo_dynamic")
|
||||
add_library("${SHARED_T}" SHARED ${CO_SRC_LIST})
|
||||
set_target_properties("${SHARED_T}" PROPERTIES OUTPUT_NAME "${TARGET}")
|
||||
target_link_libraries("${SHARED_T}" ${LINK_LIBS} -ldl)
|
||||
install(TARGETS ${SHARED_T} LIBRARY DESTINATION "lib" ARCHIVE DESTINATION "lib")
|
||||
endif()
|
||||
|
||||
add_custom_target(debug
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=DEBUG ${CMAKE_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Switch CMAKE_BUILD_TYPE to Debug"
|
||||
)
|
||||
|
||||
add_custom_target(release
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=RELEASE ${CMAKE_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Switch CMAKE_BUILD_TYPE to Release"
|
||||
)
|
||||
|
||||
set(PROFILE_FLAGS "-pg ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
|
||||
|
||||
#message("PROFILE_FLAGS: ${PROFILE_FLAGS}")
|
||||
add_custom_target(profile
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=PROFILE -DCMAKE_CXX_FLAGS_PROFILE=\\'${PROFILE_FLAGS}\\' ${CMAKE_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Switch CMAKE_BUILD_TYPE to PROFILE"
|
||||
)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND rm ${CMAKE_INSTALL_PREFIX}/lib/liblibgo.a ${CMAKE_INSTALL_PREFIX}/lib/liblibgo.so ${CMAKE_INSTALL_PREFIX}/lib/liblibgo_main.a -f
|
||||
COMMAND rm ${CMAKE_INSTALL_PREFIX}/include/libgo -rf
|
||||
)
|
||||
|
||||
elseif (WIN32)
|
||||
set_target_properties("${STATIC_T}" PROPERTIES COMPILE_FLAGS "/wd4819 /wd4267")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (BOOST_ROOT)
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/test/gtest_unit)
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/tutorial)
|
||||
endif()
|
||||
endif()
|
Loading…
Reference in New Issue