//将定时器按时间插入对应位置 static int insertTimer(int id) { clist* list_t = list_begin(&g_listTimerWork); st_timer* timer_t = (st_timer*)list_t; st_timer* TimerVal = &g_timerArray[id]; //插入到头部 if (list_empty(&g_listTimerWork)) { list_push_front(&g_listTimerWork, &TimerVal->list); return 1; } //插入到中间 while(list_end(&g_listTimerWork) != list_t/* && !list_empty(list_t)*/) { timer_t = (st_timer*)list_t; if(cmptime(&timer_t->tv, &TimerVal->tv)) { list_insert(list_t, &TimerVal->list); return 2; } list_t = list_t->next; } //插入到尾部 list_push_back(&g_listTimerWork, &TimerVal->list); return 3; }
static void rcmptime(struct stat *st, struct subcmd *sbcmds, char **env) { DIR *d; DIRENTRY *dp; char *cp; char *optarget; int len; debugmsg(DM_CALL, "rcmptime(%x) start", st); if ((d = opendir((char *) target)) == NULL) { error("%s: open directory failed: %s", target, SYSERR); return; } optarget = ptarget; len = ptarget - target; while ((dp = readdir(d)) != NULL) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; if (len + 1 + (int)strlen(dp->d_name) >= BUFSIZ - 1) { error("%s/%s: Name too long\n", target, dp->d_name); continue; } ptarget = optarget; *ptarget++ = '/'; cp = dp->d_name; while ((*ptarget++ = *cp++) != '\0') ; ptarget--; cmptime(target, sbcmds, env); } (void) closedir((DIR *) d); ptarget = optarget; *ptarget = '\0'; }
/* * Process commands for comparing files to time stamp files. */ static void dodcolon(struct cmd *cmd, char **filev) { struct subcmd *sc; struct namelist *f; char *cp, **cpp; struct stat stb; struct namelist *files = cmd->c_files; struct subcmd *sbcmds = cmd->c_cmds; char *env, *stamp = cmd->c_name; debugmsg(DM_CALL, "dodcolon()"); if (files == NULL) { error("No files to be updated for target \"%s\"", cmd->c_label); return; } if (stat(stamp, &stb) < 0) { error("%s: stat failed: %s", stamp, SYSERR); return; } debugmsg(DM_MISC, "%s: mtime %d\n", stamp, stb.st_mtime); env = NULL; for (sc = sbcmds; sc != NULL; sc = sc->sc_next) { if (sc->sc_type == CMDSPECIAL) { env = (char *) xmalloc(sizeof(E_FILES) + 3); (void) snprintf(env, sizeof(E_FILES) + 3, "%s='", E_FILES); break; } } subcmds = sbcmds; filelist = files; lastmod = stb.st_mtime; if (!nflag && !IS_ON(options, DO_VERIFY)) /* * Set atime and mtime to current time */ (void) setfiletime(stamp, (time_t) 0, (time_t) 0); for (f = files; f != NULL; f = f->n_next) { if (filev) { for (cpp = filev; *cpp; cpp++) if (strcmp(f->n_name, *cpp) == 0) goto found; continue; } found: ptarget = NULL; cmptime(f->n_name, sbcmds, &env); } for (sc = sbcmds; sc != NULL; sc = sc->sc_next) { if (sc->sc_type == NOTIFY) notify(NULL, sc->sc_args, (time_t)lastmod); else if (sc->sc_type == CMDSPECIAL && env) { size_t len = strlen(env); if (env[len - 1] == ':') env[--len] = CNULL; len += 2 + strlen(sc->sc_name) + 1; env = xrealloc(env, len); (void) strlcat(env, "';", len); (void) strlcat(env, sc->sc_name, len); message(MT_CHANGE, "cmdspecial \"%s\"", env); if (!nflag && IS_OFF(options, DO_VERIFY)) runcommand(env); (void) free(env); env = NULL; /* so cmdspecial is only called once */ } } if (!nflag && !IS_ON(options, DO_VERIFY) && (cp = getnotifyfile())) (void) unlink(cp); }
//定时器执行任务的循环线程 static void* thread_timer(void* p) { struct timespec tn; S_TIMER_MSG_BUF buf; const UCHAR sizeSend = sizeof(buf.id); buf.type = MSG_TYPE_FOR_TIMER; while (1) { sem_wait(&g_sem); if (list_end(&g_listTimerWork) == list_begin(&g_listTimerWork)) { sem_post(&g_sem); sem_wait(&g_sem_new); continue; } st_timer* timer_t = (st_timer*)list_begin(&g_listTimerWork); struct timeval tv={0, 0}; gettimeofday (&tv , NULL); if (timer_t->state == 0) { list_pop_front(&g_listTimerWork); list_push_back(&g_listTimerFree, &timer_t->list); printf_debug3("KillTimer id=%d\n", timer_t->id); sem_post(&g_sem); continue; } if(cmptime(&tv, &timer_t->tv)) { timer_t->tv.tv_usec = (timer_t->tv.tv_usec + timer_t->interval.tv_usec); timer_t->tv.tv_sec = (timer_t->tv.tv_sec + timer_t->interval.tv_sec) + timer_t->tv.tv_usec / 1000000; timer_t->tv.tv_usec %= 1000000; list_pop_front(&g_listTimerWork); if (timer_t->func != NULL) { pFuncTimer func = (pFuncTimer)timer_t->func; insertTimer(timer_t->id); sem_post(&g_sem); func(timer_t->parameter); }else if (timer_t->msgid >= 0) { buf.id = timer_t->id; msgsnd(timer_t->msgid, &buf, sizeSend, 0); if (timer_t->times > 0) { timer_t->times--; if (timer_t->times <= 0) { timer_t->state = 0; list_push_back(&g_listTimerFree, &timer_t->list); printf_debug3("KillTimer id=%d\n", timer_t->id); sem_post(&g_sem); continue; } } insertTimer(timer_t->id); sem_post(&g_sem); }else { timer_t->state = 0; list_push_back(&g_listTimerFree, &timer_t->list); sem_post(&g_sem); LOG_WRITE_POS(LOG_ERR, "id=%d, msgid=%d, func=%x\n", timer_t->id, timer_t->msgid, timer_t->func); } }else { printf_debug3("Head time: %ld, %ld\r\n", timer_t->tv.tv_sec, timer_t->tv.tv_usec); printf_debug3("Cur time: %ld, %ld\r\n", tv.tv_sec, tv.tv_usec); sem_post(&g_sem); tn.tv_sec = timer_t->tv.tv_sec;//timer_t->tv.tv_sec - tv.tv_sec; tn.tv_nsec = timer_t->tv.tv_usec * 1000;//(timer_t->tv.tv_usec - tv.tv_usec) * 1000; sem_timedwait(&g_sem_new, &tn); } } return NULL; };