#include "common.h"
#include "CIniFile.h"
#include "CRecordCfg.h"
#include "CFileFactory.h"
#include "CCtrlThread.h"
#include "CThread.h"
#include "CDeleteThread.h"
#include "CSendFileinfoThread.h"
#include "CConfigExt.h"
#include "CUtil.h"
#include "CStringExt.h"
//=================================================
//éæ(æ¬å°)å
¨å±åé
//=================================================
//åè¿ç¨ID
static int g_nPID = 0;
//éåºæ å¿
static char g_cExitFalg = '\0';
//æ¯å¦å°è§£æåçé
ç½®è¾åºå°æ件
static int g_nGenerateCfg = -1;
//æ¥å¿çº§å«
static int g_nLogModId = 0;
//å¤çè¾å
¥åæ°ãæ示ç¨æ³
static int doParams(int argc, char* argv[]);
static int usage();
static void displayAppInfo();
//åè¿ç¨
static void InitLog();
static void SetLogConfig(CConfigExt* pConf);
static void* CheckStatusThread(void* Arg);
static int mainFun(int argc, char** argv);
//å¯å¨è§é¢è½¬ç æå¡
//static void StartTransmitService();
//è°è¯ç¨ï¼å¨åçå´©æºæ¶æåå æ ä¿¡æ¯
#define DEBUG_BT
static void Debug_Printf_FrameInfos();
static void dump_debug(int signo);
//=================================================
//å
¨å±å¯¹è±¡
//=================================================
CCtrlThread* g_pCtrlThread = NULL;
CRecordCfg* g_pRecordCfg = NULL;
CConfigExt* g_pConfigExt = NULL;
//=================================================
//主ç¨åºå®ç°
//=================================================
int main(int argc, char** argv)
{
g_cExitFalg = '\0';
int ret = doParams(argc, argv);
if (ret <= 0)
{
if (ret < 0)
{
usage();
}
return 0;
}
if ((g_nPID = fork()) == 0)/*executed by child process*/
{
mainFun(argc, argv);
}
else/*executed by parent process*/
{
pthread_attr_t attr;
pthread_t Thrd;
struct sched_param SchedParam;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
sched_getparam(0, &SchedParam);
SchedParam.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr, &SchedParam);
int s = pthread_create(&Thrd, &attr, CheckStatusThread, NULL);
if (s != 0)
{
printf("pthread_create() failed. %s\n", strerror(errno));
}
}
//TEST_CMMB();
//wait until the user entered 'q' to exit the main process(and the child process).
while (g_cExitFalg != 'q')
{
scanf("%c", &g_cExitFalg);
sleep(1);
}
kill(g_nPID, SIGKILL);
return 0;
}
int mainFun(int argc, char** argv)
{
displayAppInfo();
//è°è¯ä¿¡æ¯
#ifdef DEBUG_BT
Debug_Printf_FrameInfos();
#endif
//åå§åæ¥å¿æ¨¡å
InitLog();
LOG(LOG_TYPE_NOTICE, "[Thread:0x%x] mainFun Start.", pthread_self());
//读åå
é¨é
ç½®
g_pConfigExt = new CConfigExt(CUtil::GetAppPath() + CONF_FILE_EXT);
if (g_pConfigExt != NULL)
{
if (g_pConfigExt->Parse())
{
g_pConfigExt->Dump();
//éæ°è®¾ç½®æ¥å¿çº§å«
SetLogConfig(g_pConfigExt);
CUtil::SetLocalPort(g_pConfigExt->m_nLocalPort);
}
else//å
é¨é
ç½®æ件解æ失败ï¼éç¨é»è®¤é
ç½®
{
// delete g_pConfigExt;
// g_pConfigExt = NULL;
//
// LOG(LOG_TYPE_FATAL, "é
ç½®æ件解æ失败ï¼ç¨åºéåº.");
// exit(EXIT_FAILURE);
}
}
//åå§åæ°æ®åºç¯å¢
CMysqlDatabase::InitLibrary();
//æ§å¶çº¿ç¨:æ§å¶ææ线ç¨çè¿è¡ãåæ¢
g_pCtrlThread = new CCtrlThread();
CThread * pThread = new CThread(g_pCtrlThread);
g_pCtrlThread->m_pThread = pThread;
//åéæ件信æ¯çº¿ç¨
CSendFileinfoThread * pSendFileInfoThread = new CSendFileinfoThread();
CThread * pThreadSendFileInfo = new CThread(pSendFileInfoThread);
pSendFileInfoThread->m_pThread = pThreadSendFileInfo;
g_pCtrlThread->m_pSendinfoThread = pSendFileInfoThread;
//读åé
ç½®æ件
CObjectFactory* pFac = new CFileFactory(CUtil::GetAppPath() + CONF_FILE);
if (pFac == NULL)
{
LOG(LOG_TYPE_ERROR, "pFac = NULL.");
exit(EXIT_FAILURE);
}
//å
¨å±é
置对象
g_pRecordCfg = new CRecordCfg(pFac);
if (!g_pRecordCfg->ParseObjects())
{
LOG(LOG_TYPE_FATAL, "é
ç½®æ件解æ失败ï¼ç¨åºéåº.");
delete g_pRecordCfg;
delete pFac;
delete g_pCtrlThread;
exit(EXIT_FAILURE);
}
//åå§åæ°æ®åºé¾æ¥
CMysqlInfo* pMysqlInfo = g_pRecordCfg->m_pGlobal->m_pMysqlInfo;
if (pMysqlInfo != NULL)
{
CMysqlDatabase* pDb = CMysqlDatabase::GetInstance();
pDb->Init(pMysqlInfo);
}
//æé RecordMdoule对象
if (!g_pRecordCfg->NewChannelModules())
{
LOG(LOG_TYPE_FATAL, "GetChannelModules() failed.");
delete g_pRecordCfg;
delete pFac;
delete g_pCtrlThread;
exit(EXIT_FAILURE);
}
//æ£æ¥ééæ°
if (g_pRecordCfg->m_pRecordModules.size() <= 0)
{
LOG(LOG_TYPE_ERROR, "No Valid RecordModule");
//ç¨åºç©ºè·,ææåè½çº¿ç¨(è·åé
置线ç¨ï¼å é¤çº¿ç¨)继ç»è¿è¡
// delete g_pRecordCfg;
// delete pFac;
// exit(EXIT_FAILURE);
}
//æ¥ç对象æ°æ®
g_pRecordCfg->DumpObjects(g_nGenerateCfg);
//å é¤æ件线ç¨
CDeleteThread * pDeleteThread = new CDeleteThread(g_pRecordCfg);
CThread * pThreadDelete = new CThread(pDeleteThread);
pDeleteThread->m_pThread = pThreadDelete;
g_pCtrlThread->m_pDeleteThread = pDeleteThread;
//é
ç½®æ´æ°çº¿ç¨
CConfigThread* pConfigThread = new CConfigThread;
CThread * pThreadConfig = new CThread(pConfigThread);
pConfigThread->m_pThread = pThreadConfig;
g_pCtrlThread->m_pConfigThread = pConfigThread;
CSnmpThread* pSnmpThread = new CSnmpThread;
CThread* pThreadSnmp = new CThread(pSnmpThread);
pSnmpThread->m_pThread = pThreadSnmp;
g_pCtrlThread->m_pSnmpThread = pSnmpThread;
//å¯å¨ææ线ç¨
g_pCtrlThread->setRecordCfg(g_pRecordCfg);
pThread->start();
SNMP_NOTIFY("Record Started!");
//主线ç¨:DO NOTHING
while (1)
{
sleep(1000);
}
CMysqlDatabase::DeInitLibrary();
return 0;
}
void displayAppInfo()
{
printf("**********************************************************\n");
printf("å½å¶ç¨åº,çæææ.\n");
printf("*********** *********** ***********\n");
printf("*********** *********** ***********\n");
printf("** ** ** \n");
printf("** ** ** \n");
printf("*********** ** ** \n");
printf("*********** ** ** \n");
printf("** ** ** \n");
printf("** ** ** \n");
printf("** *********** ** \n");
printf("** *********** ** \n\n");
printf("CopyRight ©2011ï¼2012, All rights reserved.\n");
printf("ShangHai Figure-IT, Inc.\n");
printf("**********************************************************\n");
printf("ç¨åºçæ¬:\t%s\n", strVession.c_str());
printf("ç¼è¯æ¥æ:\t%s %s\n", __DATE__, __TIME__);
printf("gccçæ¬:\t%s\n", __VERSION__);
printf("è¿è¡å¹³å°:\t%s\n", strPlatform.c_str());
printf("å¯ç¨æ¨¡å:\n");
for(unsigned int i=0; i<(sizeof(strEnableModules)/sizeof(strEnableModules[0])); i+=2)
{
printf("%s\t%s\n", strEnableModules[i].c_str(), strEnableModules[i+1].c_str());
}
printf("ç¦ç¨æ¨¡å:\n");
for(unsigned int i=0; i<(sizeof(strDisableModules)/sizeof(strDisableModules[0])); i+=2)
{
printf("%s\t%s\n", strDisableModules[i].c_str(), strDisableModules[i+1].c_str());
}
printf("\n");
}
int usage()
{
printf("usage: \e[1mRecord\e[0m [\e[4moption\e[0m]\n");
printf("\e[34m[\e[4m-version\e[0m\e[34m]:\e[0m\tprint the version and exit.\n");
printf("\e[34m[\e[4m-help\e[0m\e[34m]:\e[0m\tprint this usage and exit.\n");
printf("\e[34m[\e[4m-gen\e[0m\e[34m]:\e[0m\tgenerate the parsed configure to a file named 'config.sys.gen'.\n");
return 0;
}
void pr_exit(int status)
{
if (WIFEXITED(status))
{
printf("normal termination, exit status =%d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("abnormal termination, killed by signal number = %d%s\n", WTERMSIG(status),
#ifdef WCOREDUMP
WCOREDUMP(status) ? "(core file generated)\n" : "(No core file generated)\n");
#else
"WCOREDUMP not defined.\n");
#endif
}
else if (WIFSTOPPED(status))
{
printf("child stopped, signal number = %d\n", WSTOPSIG(status));
}
}
void* CheckStatusThread(void* Arg)
{
printf("[Thread] CheckStatusThread Start.\n");
int nStatus = 0;
while (g_cExitFalg != 'q')
{
int n = waitpid(g_nPID, &nStatus, 0);
//continue;
if (n <= 0)
{
if (errno == ECHILD)
{
}
}
else
{
pr_exit(nStatus);
printf("********************************************************\n");
printf("NOTIFITION: programme exited!function will restart now!\n");
printf("********************************************************\n");
if ((g_nPID = fork()) == 0)
{
mainFun(0, NULL);
}
}
}
return NULL;
}
int doParams(int argc, char* argv[])
{
int ret = 1;
if (argc > 1)
{
int i = 1;
for (; i < argc; i++)
{
if ((strcasecmp(argv[i], "-version") == 0) || (strcasecmp(argv[i], "-v") == 0))
{
displayAppInfo();
ret = 0;
}
else if ((strcasecmp(argv[i], "-help") == 0) || (strcasecmp(argv[i], "-h") == 0))
{
usage();
ret = 0;
}
else if ((strcasecmp(argv[i], "-gen") || (strcasecmp(argv[i], "-g") == 0)))
{
g_nGenerateCfg = 1;
}
else
{
ret = -1;
}
}
}
return ret;
}
void InitLog()
{
g_nLogModId = CFitLog::Instance()->registerMod("Record");
CFitLog::Instance()->setModPriority(g_nLogModId, LOG_TYPE_NOTICE);
CFitLog::Instance()->enableStdout();
CFitLog::Instance()->enableRollingFileOutput(CUtil::GetAppPath() + "Record.log", 50 * 1024 * 1024, 3);
//CFitLog::Instance()->enableMemOutput();
}
void SetLogConfig(CConfigExt* pConf)
{
if(pConf == NULL)
{
return;
}
string strLevel = pConf->m_strLogLevel;
if (strLevel == "LOG_DEBUG")
{
CFitLog::Instance()->setModPriority(g_nLogModId, LOG_TYPE_DEBUG);
}
else if (strLevel == "LOG_INFO")
{
CFitLog::Instance()->setModPriority(g_nLogModId, LOG_TYPE_INFO);
}
else if (strLevel == "LOG_NOTICE")
{
CFitLog::Instance()->setModPriority(g_nLogModId, LOG_TYPE_NOTICE);
}
else if (strLevel == "LOG_WARN")
{
CFitLog::Instance()->setModPriority(g_nLogModId, LOG_TYPE_WARN);
}
else if (strLevel == "LOG_ERROR")
{
CFitLog::Instance()->setModPriority(g_nLogModId, LOG_TYPE_ERROR);
}
else if (strLevel == "LOG_FATAL")
{
CFitLog::Instance()->setModPriority(g_nLogModId, LOG_TYPE_FATAL);
}
else
{
printf("Invalid log level:'%s'\n", strLevel.c_str());
}
if(pConf->m_nEnableLogSocket != 0)
{
CFitLog::Instance()->enableNetworkOutput("Record", LOG_NET_IP, LOG_NET_PORT, pConf->m_strLogSocketAddr);
}
}
void dump_debug(int signo)
{
void *array[30] = {0};
size_t size;
char **strings = NULL;
size_t i;
string strFile = CUtil::GetAppPath() + "signal.log";
FILE* pf = fopen(strFile.c_str(), "w");//æ¯æ¬¡æ¸
空,é²æ¢ç¨åºä¸æéå¯å¯¼è´signal.logæ件è¿å¤§
size = backtrace (array, 30);
strings = backtrace_symbols (array, size);
if(strings != NULL)
{
fprintf (stderr,"[%s] get SIGSEGV[%d] signel.\n", CDateTime::GetCurrentTime().c_str(), signo);
fprintf (stderr,"[%s] Obtained %zd stack frames.\n", CDateTime::GetCurrentTime().c_str(), size);
if(pf != NULL)
{
fprintf (pf, "[%s] get SIGSEGV[%d] signel.\n", CDateTime::GetCurrentTime().c_str(), signo);
fprintf (pf, "[%s] Obtained %zd stack frames.\n", CDateTime::GetCurrentTime().c_str(), size);
fflush(pf);
}
for (i = 0; i < size; i++)
{
fprintf (stderr,"[%s] %s\n", CDateTime::GetCurrentTime().c_str(), strings[i]);
fflush(stderr);
if(pf != NULL)
{
fprintf (pf,"[%s] %s\n", CDateTime::GetCurrentTime().c_str(), strings[i]);
fflush(pf);
}
}
}
if(pf != NULL)
{
fclose(pf);
pf = NULL;
}
free (strings);
exit(0);
}
void Debug_Printf_FrameInfos()
{
signal(SIGSEGV, dump_debug);
signal(SIGABRT, dump_debug);
}