extern int MODCOUNT;
extern char LOG_FILE[MAXBUF];
int openSockfd[MAXSOCKS];
+int yield_depth;
sockaddr_in client,server;
socklen_t length;
sockaddr_in sock_us; // our port number
socklen_t uslen; // length of our port number
+ if (yield_depth > 3)
+ return;
+
+ yield_depth++;
+
/* time() seems to be a pretty expensive syscall, so avoid calling it too much.
* Once per loop iteration is pleanty.
*/
if (((TIME % 5) == 0) && (!expire_run))
{
expire_lines();
- FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME));
+ if (process_module_sockets)
+ {
+ /* Fix by brain - the addition of DoOneIteration means that this
+ * can end up getting called recursively in the following pattern:
+ *
+ * m_spanningtree DoPingChecks
+ * (server pings out and is squit)
+ * (squit causes call to DoOneIteration)
+ * DoOneIteration enters here
+ * calls DoBackground timer
+ * enters m_spanningtree DoPingChecks... see step 1.
+ *
+ * This should do the job and fix the bug.
+ */
+ FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME));
+ }
TickMissedTimers(TIME);
expire_run = true;
+ yield_depth--;
return;
}
else if ((TIME % 5) == 1)
WriteOpers("*** \002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %d secs.",abs(OLDTIME-TIME));
DoBackgroundUserStuff(TIME);
}
-
+
/* Process timeouts on module sockets each time around
* the loop. There shouldnt be many module sockets, at
* most, 20 or so, so this won't be much of a performance
* servers... so its nice and easy, just one call.
*/
if (!(numberactive = SE->Wait(activefds)))
+ {
+ yield_depth--;
return;
+ }
/**
* Now process each of the fd's. For users, we have a fast
case X_ESTAB_MODULE:
if (!process_module_sockets)
- return;
+ break;
/* Process module-owned sockets.
* Modules are encouraged to inherit their sockets from
break;
}
}
+ yield_depth--;
}
int InspIRCd::Run()
/* main loop, this never returns */
expire_run = false;
+ yield_depth = 0;
while (true)
{