198 lines
4.6 KiB
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);
|
|
}
|