unsigned int snmp_alarm_register(unsigned int when, unsigned int flags, SNMPAlarmCallback *thecallback, void *clientarg) { struct snmp_alarm **sa_pptr; if (thealarms != NULL) { for(sa_pptr = &thealarms; (*sa_pptr) != NULL; sa_pptr = &((*sa_pptr)->next)); } else { sa_pptr = &thealarms; } *sa_pptr = SNMP_MALLOC_STRUCT(snmp_alarm); if (*sa_pptr == NULL) return 0; (*sa_pptr)->seconds = when; (*sa_pptr)->flags = flags; (*sa_pptr)->clientarg = clientarg; (*sa_pptr)->thecallback = thecallback; (*sa_pptr)->clientreg = regnum++; sa_update_entry(*sa_pptr); DEBUGMSGTL(("snmp_alarm_register","registered alarm %d, secends=%d, flags=%d\n", (*sa_pptr)->clientreg, (*sa_pptr)->seconds, (*sa_pptr)->flags)); if (start_alarms) set_an_alarm(); return (*sa_pptr)->clientreg; }
void run_alarms(void) { int done=0; struct snmp_alarm *sa_ptr; /* loop through everything we have repeatedly looking for the next thing to call until all events are finally in the future again */ DEBUGMSGTL(("snmp_alarm_run_alarms","looking for alarms to run...\n")); while(done == 0) { sa_ptr = sa_find_next(); if (sa_ptr == NULL) return; if (sa_ptr->nextcall <= time(NULL)) { DEBUGMSGTL(("snmp_alarm_run_alarms"," running alarm %d\n", sa_ptr->clientreg)); (*(sa_ptr->thecallback))(sa_ptr->clientreg, sa_ptr->clientarg); DEBUGMSGTL(("snmp_alarm_run_alarms"," ... done\n")); sa_ptr->lastcall = time(NULL); sa_ptr->nextcall = 0; sa_update_entry(sa_ptr); } else { done = 1; } } DEBUGMSGTL(("snmp_alarm_run_alarms","Done.\n")); }
/** * * This function offers finer granularity as to when the callback * * function is called by making use of t->tv_usec value forming the * * "when" aspect of zevent_alarm_register(). * * * * @param t is a timeval structure used to specify when the callback * * function(alarm) will be called. Adds the ability to specify * * microseconds. t.tv_sec and t.tv_usec are assigned * * to zevent_alarm->tv_sec and zevent_alarm->tv_usec respectively internally. * * The zevent_alarm_register function only assigns seconds(it's when * * argument). * * * * @param flags is an unsigned integer that specifies how frequent the callback * * function is called in seconds. Should be SA_REPEAT or NULL. If * * flags is set with SA_REPEAT, then the registered callback function * * will be called every SA_REPEAT seconds. If flags is NULL then the * * function will only be called once and then removed from the * * registered alarm list. * * * * @param cb is a pointer ZEVENTAlarmCallback which is the callback * * function being stored and registered. * * * * @param cd is a void pointer used by the callback function. This * * pointer is assigned to zevent_alarm->clientarg and passed into the * * callback function for the client's specifc needs. * * * * @return Returns a unique unsigned integer(which is also passed as the first * * argument of each callback), which can then be used to remove the * * callback from the list at a later point in the future using the * * zevent_alarm_unregister() function. If memory could not be allocated * * for the zevent_alarm struct 0 is returned. * * * * @see zevent_alarm_register * * @see zevent_alarm_unregister * * @see zevent_alarm_unregister_all * */ unsigned int zevent_alarm_register_hr(struct timeval t, unsigned int flags, ZEVENTAlarmCallback * cb, void *cd) { struct zevent_alarm **s = NULL; for(s = &(thealarms); *s != NULL; s = &((*s)->next)) ; *s = ZEVENT_MALLOC_STRUCT(zevent_alarm); if(*s == NULL) { return 0; } (*s)->t.tv_sec = t.tv_sec; (*s)->t.tv_usec = t.tv_usec; (*s)->flags = flags; (*s)->clientarg = cd; (*s)->thecallback = cb; (*s)->clientreg = regnum++; (*s)->next = NULL; sa_update_entry(*s); printf("registered alarm %d, t = %d.%03d, flags=0x%02x\n", (*s)->clientreg, (int) (*s)->t.tv_sec, (int) ((*s)->t.tv_usec / 1000), (*s)->flags); if(start_alarms) { set_an_alarm(); } return (*s)->clientreg; }
/** * * This function registers function callbacks to occur at a speciifc time * * in the future. * * * * @param when is an unsigned integer specifying when the callback function * * will be called in seconds. * * * * @param flags is an unsigned integer that specifies how frequent the callback * * function is called in seconds. Should be SA_REPEAT or 0. If * * flags is set with SA_REPEAT, then the registered callback function * * will be called every SA_REPEAT seconds. If flags is 0 then the * * function will only be called once and then removed from the * * registered alarm list. * * * * @param thecallback is a pointer ZEVENTAlarmCallback which is the callback * * function being stored and registered. * * * * @param clientarg is a void pointer used by the callback function. This * * pointer is assigned to zevent_alarm->clientarg and passed into the * * callback function for the client's specifc needs. * * * * @return Returns a unique unsigned integer(which is also passed as the first * * argument of each callback), which can then be used to remove the * * callback from the list at a later point in the future using the * * zevent_alarm_unregister() function. If memory could not be allocated * * for the zevent_alarm struct 0 is returned. * * * * @see zevent_alarm_unregister * * @see zevent_alarm_register_hr * * @see zevent_alarm_unregister_all * */ unsigned int zevent_alarm_register(unsigned int when, unsigned int flags, ZEVENTAlarmCallback * thecallback, void *clientarg) { struct zevent_alarm **sa_pptr; if(thealarms != NULL) { for(sa_pptr = &thealarms; (*sa_pptr) != NULL; sa_pptr = &((*sa_pptr)->next)) ; } else { sa_pptr = &thealarms; } *sa_pptr = ZEVENT_MALLOC_STRUCT(zevent_alarm); if(*sa_pptr == NULL) return 0; if(0 == when) { (*sa_pptr)->t.tv_sec = 0; (*sa_pptr)->t.tv_usec = 1; } else { (*sa_pptr)->t.tv_sec = when; (*sa_pptr)->t.tv_usec = 0; } (*sa_pptr)->flags = flags; (*sa_pptr)->clientarg = clientarg; (*sa_pptr)->thecallback = thecallback; (*sa_pptr)->clientreg = regnum++; (*sa_pptr)->next = NULL; sa_update_entry(*sa_pptr); printf("registered alarm %d, t = %d.%03d, flags=0x%02x\n", (*sa_pptr)->clientreg, (int) (*sa_pptr)->t.tv_sec, (int) ((*sa_pptr)->t.tv_usec / 1000), (*sa_pptr)->flags); if(start_alarms){ set_an_alarm(); } return (*sa_pptr)->clientreg; }
void run_alarms(void) { int done = 0; struct zevent_alarm *a = NULL; unsigned int clientreg; struct timeval t_now; /* * * Loop through everything we have repeatedly looking for the next thing to * * call until all events are finally in the future again. * */ while(!done) { if((a = sa_find_next()) == NULL) { return; } gettimeofday(&t_now, NULL); if((a->t_next.tv_sec < t_now.tv_sec) || ((a->t_next.tv_sec == t_now.tv_sec) && (a->t_next.tv_usec < t_now.tv_usec))) { clientreg = a->clientreg; printf("run alarm %d\n", clientreg); (*(a->thecallback)) (clientreg, a->clientarg); printf("alarm %d completed\n", clientreg); if((a = sa_find_specific(clientreg)) != NULL) { a->t_last.tv_sec = t_now.tv_sec; a->t_last.tv_usec = t_now.tv_usec; a->t_next.tv_sec = 0; a->t_next.tv_usec = 0; sa_update_entry(a); } else { printf("alarm %d deleted itself\n", clientreg); } } else { done = 1; } } }