PV1_MakeProject/Framework/HeartDaemon/heart_daemon.c

198 lines
4.6 KiB
C

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include "log.h"
#include "libuv_dbus.h"
typedef struct
{
MODULE_NAME modName;
uint32_t hTm[MODULE_MAX];
int isDaemonWork[MODULE_MAX];
int isConnected[MODULE_MAX];
OnDaemonMsg pOnHeartLostCb;
} HEART_DAEMON, *PHEART_DAEMON;
uint32_t g_hblTout = HEART_LOST_DELAY; ///< nano second: heart lost timeout, default 1s
static uv_loop_t *g_DeamonLoop;
static uv_idle_t g_uvDeamonIdle;
static HEART_DAEMON g_heartDaemon;
static unsigned int g_Cnt = 0;
static int timerExpire(uint32_t tm, uint32_t tExp)
{
uint32_t now = LIBUV_CURRENT_TIME_MS();
int64_t diff = now - tm;
if(tm == 0 || tExp == 0)
{
return 0;
}
if(diff > tExp * 1000)
{
return 0;
}
else if(diff >= tExp)
{
return 1;
}
return (0);
}
static void RunPingSvr(void)
{
int ret = 0;
unsigned int tm = LIBUV_CURRENT_TIME_MS();
PING_MSG pMsg;
struct timeval tv;
gettimeofday(&tv, NULL);
pMsg.PING = (double)tm / 1000;
pMsg.tmSec = tv.tv_sec;
pMsg.tmMSec = tv.tv_usec;
ret = DBusJsonBoardcastCommand(NULL, 0xFFFFFFFF, CMD_MISC_PING, JSON_ENGINE_PING, &pMsg, FALSE);
if(ret != 0)
{
LOG_EX(LOG_Error, "DBus boardcast message error: %d\n", ret);
}
}
void HeartDaemonHblCheck(void)
{
if(g_heartDaemon.modName != MODULE_CONTROLLER)
{
if(g_heartDaemon.isDaemonWork[MODULE_CONTROLLER] && timerExpire(g_heartDaemon.hTm[MODULE_CONTROLLER], g_hblTout))
{
g_heartDaemon.pOnHeartLostCb(MODULE_CONTROLLER, TRUE);
g_heartDaemon.hTm[MODULE_CONTROLLER] = 0;
g_heartDaemon.isConnected[MODULE_CONTROLLER] = FALSE;
}
}
else
{
int i;
for(i = 0; i < MODULE_MAX; i++)
{
if(g_heartDaemon.isDaemonWork[i]
&& i != MODULE_CONTROLLER
&& timerExpire(g_heartDaemon.hTm[i], g_hblTout))
{
g_heartDaemon.pOnHeartLostCb(i, TRUE);
g_heartDaemon.hTm[i] = 0;
g_heartDaemon.isConnected[i] = FALSE;
}
}
}
}
void HeartDaemonUpgrade(int iWatcher)
{
if(iWatcher >= MODULE_MAX)
{
return;
}
if(g_heartDaemon.hTm[iWatcher] == 0)
{
if(g_heartDaemon.modName == MODULE_CONTROLLER)
{
g_heartDaemon.pOnHeartLostCb(iWatcher, FALSE);
}
else if(iWatcher == MODULE_CONTROLLER)
{
g_heartDaemon.pOnHeartLostCb(iWatcher, FALSE);
}
g_heartDaemon.isConnected[iWatcher] = TRUE;
RunPingSvr();
}
g_heartDaemon.hTm[iWatcher] = LIBUV_CURRENT_TIME_MS();
}
static int __isSendPingOnTime(void)
{
static unsigned int tmPre = 0;
unsigned int tm = LIBUV_CURRENT_TIME_MS();
unsigned int tmOut = HEART_SEND_DELAY;
if(g_heartDaemon.modName != MODULE_CONTROLLER
&& g_heartDaemon.isConnected[MODULE_CONTROLLER] == FALSE)
{
tmOut = 5000;
}
if(tmPre != 0 && tm - tmPre < tmOut)
{
return (FALSE);
}
tmPre = tm;
return (TRUE);
}
static void __uvIdleCb(uv_idle_t* phuvIdle)
{
if(DBusLibuvGetRuntime()->onHblCb
&& __isSendPingOnTime())
{
RunPingSvr();
}
HeartDaemonHblCheck();
sleep(1);
}
static void __uvThreadDaemon(void *pParams)
{
g_DeamonLoop = uv_loop_new();
uv_idle_init(g_DeamonLoop, &g_uvDeamonIdle);
uv_idle_start(&g_uvDeamonIdle, __uvIdleCb);
uv_run(g_DeamonLoop, UV_RUN_DEFAULT);
pthread_detach(pthread_self());
}
void HeartDaemonInit(MODULE_NAME mod, int msHblTout, OnDaemonMsg cb)
{
uv_thread_t uvDaemonThread;
int i;
memset(&g_heartDaemon, 0, sizeof(HEART_DAEMON));
if(msHblTout > 0)
{
g_hblTout = msHblTout;
}
g_heartDaemon.modName = mod;
for(i = 0; i < MODULE_MAX; i++)
{
if(mod == MODULE_CONTROLLER)
{
g_heartDaemon.isDaemonWork[i] = (g_pModInfoTable[i].modName != MODULE_CONTROLLER) ? TRUE : FALSE;
}
else
{
g_heartDaemon.isDaemonWork[i] = (g_pModInfoTable[i].modName == MODULE_CONTROLLER) ? TRUE : FALSE;
}
g_heartDaemon.isConnected[i] = FALSE;
}
g_heartDaemon.pOnHeartLostCb = cb;
uv_thread_create(&uvDaemonThread, __uvThreadDaemon, NULL);
}