mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-06-30 10:26:37 +02:00
* EventAdd() changed the order of parameters and expects every_msec now
which specifies the time in milliseconds rather than seconds. This allows for additional precision, or at least multiple calls per second. The minimum allowed every_msec value is 100 at this time. The prototype is now: EventAdd(Module *module, char *name, vFP event, void *data, long every_msec, int count);
This commit is contained in:
@@ -286,6 +286,12 @@ It is therefore best to wait until beta1. You have been warned ;).
|
||||
in sendto_server(), then be sure to use %lld and cast the timestamp
|
||||
to 'long long' so that it is compatible with both *NIX and Windows.
|
||||
Example: sendnotice(sptr, "Timestamp is %lld", (long long)ts);
|
||||
* EventAdd() changed the order of parameters and expects every_msec now
|
||||
which specifies the time in milliseconds rather than seconds. This
|
||||
allows for additional precision, or at least multiple calls per second.
|
||||
The minimum allowed every_msec value is 100 at this time.
|
||||
The prototype is now: EventAdd(Module *module, char *name,
|
||||
vFP event, void *data, long every_msec, int count);
|
||||
* New HOOKTYPE_IS_HANDSHAKE_FINISHED. If a module returns 0 there, then
|
||||
the register_user() function will not be called and the user will
|
||||
not come online (yet). This is used by CAP and some other stuff.
|
||||
|
||||
@@ -934,3 +934,4 @@ extern void _add_name_list(NameList **list, char *name);
|
||||
extern void _del_name_list(NameList **list, char *name);
|
||||
extern NameList *find_name_list(NameList *list, char *name);
|
||||
extern NameList *find_name_list_match(NameList *list, char *name);
|
||||
extern int minimum_msec_since_last_run(struct timeval *tv_old, long minimum);
|
||||
|
||||
+21
-19
@@ -606,16 +606,17 @@ struct Module
|
||||
#define MOD_OPT_GLOBAL 0x0008 /* Module is required to be loaded globally (i.e. across the entire network) */
|
||||
#define MOD_Dep(name, container,module) {#name, (vFP *) &container, module}
|
||||
|
||||
/* Event structs */
|
||||
/** Event structs */
|
||||
struct Event {
|
||||
Event *prev, *next;
|
||||
char *name;
|
||||
time_t every;
|
||||
long howmany;
|
||||
vFP event;
|
||||
void *data;
|
||||
time_t last;
|
||||
Module *owner;
|
||||
Event *prev; /**< Previous event (linked list) */
|
||||
Event *next; /**< Next event (linked list) */
|
||||
char *name; /**< Name of the event */
|
||||
long every_msec; /**< How often we should run this event */
|
||||
long count; /**< How many times this event should run (0 = infinite) */
|
||||
vFP event; /**< Actual function to call */
|
||||
void *data; /**< The data to pass in the function call */
|
||||
struct timeval last_run; /**< Last time this event ran */
|
||||
Module *owner; /**< To which module this event belongs */
|
||||
};
|
||||
|
||||
#define EMOD_EVERY 0x0001
|
||||
@@ -624,10 +625,11 @@ struct Event {
|
||||
#define EMOD_EVENT 0x0008
|
||||
#define EMOD_DATA 0x0010
|
||||
|
||||
/** event struct information, for EventMod() only - see Event for documentation */
|
||||
struct EventInfo {
|
||||
int flags;
|
||||
long howmany;
|
||||
time_t every;
|
||||
long count;
|
||||
time_t every_msec;
|
||||
char *name;
|
||||
vFP event;
|
||||
void *data;
|
||||
@@ -639,14 +641,14 @@ extern MODVAR Hooktype Hooktypes[MAXCUSTOMHOOKS];
|
||||
extern MODVAR Callback *Callbacks[MAXCALLBACKS], *RCallbacks[MAXCALLBACKS];
|
||||
extern MODVAR ClientCapability *clicaps;
|
||||
|
||||
extern Event *EventAdd(Module *, char *name, long every, long howmany, vFP event, void *data);
|
||||
extern Event *EventDel(Event *event);
|
||||
extern Event *EventMarkDel(Event *event);
|
||||
extern Event *EventFind(char *name);
|
||||
extern int EventMod(Event *event, EventInfo *mods);
|
||||
extern void DoEvents(void);
|
||||
extern void EventStatus(Client *sptr);
|
||||
extern void SetupEvents(void);
|
||||
extern Event *EventAdd(Module *module, char *name, vFP event, void *data, long every_msec, int count);
|
||||
extern Event *EventDel(Event *event);
|
||||
extern Event *EventMarkDel(Event *event);
|
||||
extern Event *EventFind(char *name);
|
||||
extern int EventMod(Event *event, EventInfo *mods);
|
||||
extern void DoEvents(void);
|
||||
extern void EventStatus(Client *sptr);
|
||||
extern void SetupEvents(void);
|
||||
|
||||
|
||||
extern void Module_Init(void);
|
||||
|
||||
+45
-41
@@ -29,23 +29,46 @@ MODVAR Event *events = NULL;
|
||||
|
||||
extern EVENT(unrealdns_removeoldrecords);
|
||||
|
||||
Event *EventAdd(Module *module, char *name, long every, long howmany,
|
||||
vFP event, void *data)
|
||||
/** Add an event, a function that will run at regular intervals.
|
||||
* @param module Module that this event belongs to
|
||||
* @param name Name of the event
|
||||
* @param event The EVENT(function) to be called
|
||||
* @param data The data to be passed to the function (or just NULL)
|
||||
* @param every_msec Every <this> milliseconds the event will be called, but see notes.
|
||||
* @param count After how many times we should stop calling this even (0 = infinite times)
|
||||
* @returns an Event struct
|
||||
* @notes UnrealIRCd will try to call the event every 'every_msec' milliseconds.
|
||||
* However, in case of low traffic the minimum time is at least SOCKETLOOP_MAX_DELAY
|
||||
* which is 250ms at the time of writing. Also, we reject any value below 100 msecs.
|
||||
* The actual calling time will not be quicker than the specified every_msec but
|
||||
* can be later, in case of high load, in very extreme cases even up to 1000 or 2000
|
||||
* msec later but that would be very unusual. Just saying, it's not a guarantee..
|
||||
*/
|
||||
Event *EventAdd(Module *module, char *name, vFP event, void *data, long every_msec, int count)
|
||||
{
|
||||
Event *newevent;
|
||||
if (!name || (every < 0) || (howmany < 0) || !event)
|
||||
if (!name || (every_msec < 0) || (count < 0) || !event)
|
||||
{
|
||||
if (module)
|
||||
module->errorcode = MODERR_INVALID;
|
||||
return NULL;
|
||||
}
|
||||
if (every_msec < 100)
|
||||
{
|
||||
ircd_log(LOG_ERROR, "[BUG] EventAdd() from module %s with suspiciously low every_msec value (%ld). "
|
||||
"Note that it is in milliseconds now (1000 = 1 second)!",
|
||||
module ? module->header->name : "???",
|
||||
every_msec);
|
||||
every_msec = 100;
|
||||
}
|
||||
newevent = safe_alloc(sizeof(Event));
|
||||
safe_strdup(newevent->name, name);
|
||||
newevent->howmany = howmany;
|
||||
newevent->every = every;
|
||||
newevent->count = count;
|
||||
newevent->every_msec = every_msec;
|
||||
newevent->event = event;
|
||||
newevent->data = data;
|
||||
newevent->last = TStime();
|
||||
newevent->last_run.tv_sec = timeofday_tv.tv_sec;
|
||||
newevent->last_run.tv_usec = timeofday_tv.tv_usec;
|
||||
newevent->owner = module;
|
||||
AddListItem(newevent,events);
|
||||
if (module)
|
||||
@@ -62,7 +85,7 @@ Event *EventAdd(Module *module, char *name, long every, long howmany,
|
||||
|
||||
Event *EventMarkDel(Event *event)
|
||||
{
|
||||
event->howmany = -1;
|
||||
event->count = -1;
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -116,9 +139,9 @@ int EventMod(Event *event, EventInfo *mods)
|
||||
}
|
||||
|
||||
if (mods->flags & EMOD_EVERY)
|
||||
event->every = mods->every;
|
||||
event->every_msec = mods->every_msec;
|
||||
if (mods->flags & EMOD_HOWMANY)
|
||||
event->howmany = mods->howmany;
|
||||
event->count = mods->count;
|
||||
if (mods->flags & EMOD_NAME)
|
||||
safe_strdup(event->name, mods->name);
|
||||
if (mods->flags & EMOD_EVENT)
|
||||
@@ -137,16 +160,15 @@ void DoEvents(void)
|
||||
|
||||
for (eventptr = events; eventptr; eventptr = eventptr->next)
|
||||
{
|
||||
if (eventptr->howmany == -1)
|
||||
if (eventptr->count == -1)
|
||||
goto freeit;
|
||||
if ((eventptr->every == 0) || ((TStime() - eventptr->last) >= eventptr->every))
|
||||
if ((eventptr->every_msec == 0) || minimum_msec_since_last_run(&eventptr->last_run, eventptr->every_msec))
|
||||
{
|
||||
eventptr->last = TStime();
|
||||
(*eventptr->event)(eventptr->data);
|
||||
if (eventptr->howmany > 0)
|
||||
if (eventptr->count > 0)
|
||||
{
|
||||
eventptr->howmany--;
|
||||
if (eventptr->howmany == 0)
|
||||
eventptr->count--;
|
||||
if (eventptr->count == 0)
|
||||
{
|
||||
freeit:
|
||||
temp.next = EventDel(eventptr);
|
||||
@@ -158,33 +180,15 @@ freeit:
|
||||
}
|
||||
}
|
||||
|
||||
void EventStatus(Client *sptr)
|
||||
{
|
||||
Event *eventptr;
|
||||
time_t now = TStime();
|
||||
|
||||
if (!events)
|
||||
{
|
||||
sendnotice(sptr, "*** No events");
|
||||
return;
|
||||
}
|
||||
for (eventptr = events; eventptr; eventptr = eventptr->next)
|
||||
{
|
||||
sendnotice(sptr, "*** Event %s: e/%lld h/%lld n/%lld l/%lld",
|
||||
eventptr->name, (long long)eventptr->every, (long long)eventptr->howmany,
|
||||
(long long)(now - eventptr->last), (long long)((eventptr->last + eventptr->every) - now));
|
||||
}
|
||||
}
|
||||
|
||||
void SetupEvents(void)
|
||||
{
|
||||
/* Start events */
|
||||
EventAdd(NULL, "tunefile", 300, 0, save_tunefile, NULL);
|
||||
EventAdd(NULL, "garbage", GARBAGE_COLLECT_EVERY, 0, garbage_collect, NULL);
|
||||
EventAdd(NULL, "loop", 0, 0, loop_event, NULL);
|
||||
EventAdd(NULL, "unrealdns_removeoldrecords", 15, 0, unrealdns_removeoldrecords, NULL);
|
||||
EventAdd(NULL, "check_pings", 1, 0, check_pings, NULL);
|
||||
EventAdd(NULL, "check_deadsockets", 1, 0, check_deadsockets, NULL);
|
||||
EventAdd(NULL, "check_unknowns", 1, 0, check_unknowns, NULL);
|
||||
EventAdd(NULL, "try_connections", 2, 0, try_connections, NULL);
|
||||
EventAdd(NULL, "tunefile", save_tunefile, NULL, 300*1000, 0);
|
||||
EventAdd(NULL, "garbage", garbage_collect, NULL, GARBAGE_COLLECT_EVERY*1000, 0);
|
||||
EventAdd(NULL, "loop", loop_event, NULL, 1000, 0);
|
||||
EventAdd(NULL, "unrealdns_removeoldrecords", unrealdns_removeoldrecords, NULL, 15000, 0);
|
||||
EventAdd(NULL, "check_pings", check_pings, NULL, 1000, 0);
|
||||
EventAdd(NULL, "check_deadsockets", check_deadsockets, NULL, 1000, 0);
|
||||
EventAdd(NULL, "check_unknowns", check_unknowns, NULL, 1000, 0);
|
||||
EventAdd(NULL, "try_connections", try_connections, NULL, 2000, 0);
|
||||
}
|
||||
|
||||
+4
-4
@@ -2584,16 +2584,16 @@ int config_run()
|
||||
long v;
|
||||
eInfo.flags = EMOD_EVERY;
|
||||
if (!THROTTLING_PERIOD)
|
||||
v = 120;
|
||||
v = 120000;
|
||||
else
|
||||
{
|
||||
v = THROTTLING_PERIOD/2;
|
||||
if (v > 5)
|
||||
v = 5; /* accuracy, please */
|
||||
v = 5000; /* accuracy, please */
|
||||
if (v < 1)
|
||||
v = 1; /* duh */
|
||||
v = 1000; /* duh */
|
||||
}
|
||||
eInfo.every = v;
|
||||
eInfo.every_msec = v;
|
||||
EventMod(EventFind("bucketcleaning"), &eInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ void init_resolver(int firsttime)
|
||||
}
|
||||
|
||||
ares_set_socket_callback(resolver_channel, unrealdns_sock_create_cb, NULL);
|
||||
unrealdns_timeout_hdl = EventAdd(NULL, "unrealdns_timeout", 0, 0, unrealdns_timeout, NULL);
|
||||
unrealdns_timeout_hdl = EventAdd(NULL, "unrealdns_timeout", unrealdns_timeout, NULL, 500, 0);
|
||||
}
|
||||
|
||||
void reinit_resolver(Client *sptr)
|
||||
|
||||
+3
-3
@@ -898,11 +898,11 @@ void init_throttling()
|
||||
{
|
||||
v = THROTTLING_PERIOD/2;
|
||||
if (v > 5)
|
||||
v = 5; /* accuracy, please */
|
||||
v = 5000; /* run at least every 5s */
|
||||
if (v < 1)
|
||||
v = 1; /* duh */
|
||||
v = 1000; /* run at max once every 1s */
|
||||
}
|
||||
EventAdd(NULL, "bucketcleaning", v, 0, e_clean_out_throttling_buckets, NULL);
|
||||
EventAdd(NULL, "bucketcleaning", e_clean_out_throttling_buckets, NULL, v, 0);
|
||||
}
|
||||
|
||||
uint64_t hash_throttling(char *ip)
|
||||
|
||||
+6
-5
@@ -735,11 +735,10 @@ void fix_timers(void)
|
||||
/* Reset all event timers */
|
||||
for (e = events; e; e = e->next)
|
||||
{
|
||||
if (e->last > TStime())
|
||||
if (e->last_run.tv_sec > TStime())
|
||||
{
|
||||
Debug((DEBUG_DEBUG, "fix_timers(): %s: e->last %ld -> %ld",
|
||||
e->name, e->last, TStime()-1));
|
||||
e->last = TStime()-1;
|
||||
e->last_run.tv_sec = TStime()-1;
|
||||
e->last_run.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -947,7 +946,9 @@ int InitUnrealIRCd(int argc, char *argv[])
|
||||
struct rlimit corelim;
|
||||
#endif
|
||||
|
||||
timeofday = time(NULL);
|
||||
gettimeofday(&timeofday_tv, NULL);
|
||||
timeofday = timeofday_tv.tv_sec;
|
||||
|
||||
safe_strdup(configfile, CONFIGFILE);
|
||||
|
||||
init_random(); /* needs to be done very early!! */
|
||||
|
||||
+1
-1
@@ -1449,7 +1449,7 @@ void special_delayed_unloading(void)
|
||||
{
|
||||
config_warn("Delaying module unloading of '%s' a few seconds...", m->header->name);
|
||||
m->flags |= MODFLAG_DELAYED;
|
||||
EventAdd(NULL, "e_unload_module_delayed", 5, 1, e_unload_module_delayed, m->header->name);
|
||||
EventAdd(NULL, "e_unload_module_delayed", e_unload_module_delayed, m->header->name, 5000, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ MOD_INIT()
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
EventAdd(modinfo->handle, "modef_event", 10, 0, modef_event, NULL);
|
||||
EventAdd(modinfo->handle, "modef_event", modef_event, NULL, 10000, 0);
|
||||
floodprot_rehash_complete();
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ MOD_INIT()
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
EventAdd(modinfo->handle, "history_clean", HISTORY_TIMER_EVERY, 0, history_clean, NULL);
|
||||
EventAdd(modinfo->handle, "history_clean", history_clean, NULL, HISTORY_TIMER_EVERY*1000, 0);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ MOD_INIT()
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
EventAdd(modinfo->handle, "channeldb_write_channeldb", CHANNELDB_SAVE_EVERY, 0, write_channeldb_evt, NULL);
|
||||
EventAdd(modinfo->handle, "channeldb_write_channeldb", write_channeldb_evt, NULL, CHANNELDB_SAVE_EVERY*1000, 0);
|
||||
if (ModuleGetError(modinfo->handle) != MODERR_NOERROR)
|
||||
{
|
||||
config_error("A critical error occurred when loading module %s: %s", MOD_HEADER.name, ModuleGetErrorStr(modinfo->handle));
|
||||
|
||||
@@ -111,7 +111,7 @@ MOD_INIT()
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
EventAdd(modinfo->handle, "connthrottle_evt", 1, 0, connthrottle_evt, NULL);
|
||||
EventAdd(modinfo->handle, "connthrottle_evt", connthrottle_evt, NULL, 1000, 0);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ ExtbanInfo extban;
|
||||
return MOD_FAILED;
|
||||
}
|
||||
|
||||
EventAdd(modinfo->handle, "timedban_timeout", TIMEDBAN_TIMER, 0, timedban_timeout, NULL);
|
||||
EventAdd(modinfo->handle, "timedban_timeout", timedban_timeout, NULL, TIMEDBAN_TIMER*1000, 0);
|
||||
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ MOD_INIT()
|
||||
{
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
ModuleSetOptions(modinfo->handle, MOD_OPT_PERM, 1); /* needed? or not? */
|
||||
EventAdd(NULL, "check_ident_timeout", 1, 0, check_ident_timeout, NULL);
|
||||
EventAdd(NULL, "check_ident_timeout", check_ident_timeout, NULL, 1000, 0);
|
||||
HookAdd(modinfo->handle, HOOKTYPE_IDENT_LOOKUP, 0, ident_lookup_connect);
|
||||
|
||||
return MOD_SUCCESS;
|
||||
|
||||
@@ -100,7 +100,7 @@ MOD_INIT()
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
EventAdd(ModInfo->handle, "jointhrottle_cleanup_structs", 60, 0, jointhrottle_cleanup_structs, NULL);
|
||||
EventAdd(ModInfo->handle, "jointhrottle_cleanup_structs", jointhrottle_cleanup_structs, NULL, 60000, 0);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ MOD_LOAD()
|
||||
cap.parameter = link_security_capability_parameter;
|
||||
ClientCapabilityAdd(modinfo->handle, &cap, NULL);
|
||||
|
||||
EventAdd(modinfo->handle, "checklinksec", 2, 0, checklinksec, NULL);
|
||||
EventAdd(modinfo->handle, "checklinksec", checklinksec, NULL, 2000, 0);
|
||||
checklinksec(NULL);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ MOD_INIT()
|
||||
}
|
||||
|
||||
CommandAdd(modinfo->handle, MSG_LIST, cmd_list, MAXPARA, M_USER);
|
||||
EventAdd(modinfo->handle, "send_queued_list_data", 1, 0, send_queued_list_data, NULL);
|
||||
EventAdd(modinfo->handle, "send_queued_list_data", send_queued_list_data, NULL, 1500, 0);
|
||||
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -175,9 +175,9 @@ MOD_LOAD()
|
||||
load_db();
|
||||
if (reputation_starttime == 0)
|
||||
reputation_starttime = TStime();
|
||||
EventAdd(ModInf.handle, "delete_old_records", DELETE_OLD_EVERY, 0, delete_old_records, NULL);
|
||||
EventAdd(ModInf.handle, "add_scores", BUMP_SCORE_EVERY, 0, add_scores, NULL);
|
||||
EventAdd(ModInf.handle, "save_db", SAVE_DB_EVERY, 0, save_db_evt, NULL);
|
||||
EventAdd(ModInf.handle, "delete_old_records", delete_old_records, NULL, DELETE_OLD_EVERY*1000, 0);
|
||||
EventAdd(ModInf.handle, "add_scores", add_scores, NULL, BUMP_SCORE_EVERY*1000, 0);
|
||||
EventAdd(ModInf.handle, "save_db", save_db_evt, NULL, SAVE_DB_EVERY*1000, 0);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -195,7 +195,7 @@ MOD_INIT()
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
EventAdd(modinfo->handle, "tklexpire", 5, 0, tkl_check_expire, NULL);
|
||||
EventAdd(modinfo->handle, "tklexpire", tkl_check_expire, NULL, 5000, 0);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ MOD_INIT()
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
EventAdd(modinfo->handle, "tkldb_write_tkldb", TKL_DB_SAVE_EVERY, 0, write_tkldb_evt, NULL);
|
||||
EventAdd(modinfo->handle, "tkldb_write_tkldb", write_tkldb_evt, NULL, TKL_DB_SAVE_EVERY*1000, 0);
|
||||
if (ModuleGetError(modinfo->handle) != MODERR_NOERROR)
|
||||
{
|
||||
config_error("A critical error occurred when loading module %s: %s", MOD_HEADER.name, ModuleGetErrorStr(modinfo->handle));
|
||||
|
||||
@@ -371,7 +371,7 @@ void url_init(void)
|
||||
multihandle = curl_multi_init();
|
||||
|
||||
curl_multi_setopt(multihandle, CURLMOPT_SOCKETFUNCTION, url_socket_cb);
|
||||
curl_socket_timeout_hdl = EventAdd(NULL, "curl_socket_timeout", 1, 0, curl_socket_timeout, NULL);
|
||||
curl_socket_timeout_hdl = EventAdd(NULL, "curl_socket_timeout", curl_socket_timeout, NULL, 500, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user