#include #include #include #include #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); }