static gboolean rspamd_symbols_cache_check_deps (struct rspamd_task *task,
struct symbols_cache *cache,
struct cache_item *item,
- struct cache_savepoint *checkpoint);
+ struct cache_savepoint *checkpoint,
+ guint recursion);
static void rspamd_symbols_cache_enable_symbol (struct rspamd_task *task,
struct symbols_cache *cache, const gchar *symbol);
static void rspamd_symbols_cache_disable_all_symbols (struct rspamd_task *task,
if (!isset (checkpoint->processed_bits, it->id * 2)) {
if (!rspamd_symbols_cache_check_deps (task, cache, it,
- checkpoint)) {
+ checkpoint, 0)) {
remain ++;
break;
}
rspamd_symbols_cache_check_deps (struct rspamd_task *task,
struct symbols_cache *cache,
struct cache_item *item,
- struct cache_savepoint *checkpoint)
+ struct cache_savepoint *checkpoint,
+ guint recursion)
{
struct cache_dependency *dep;
guint i;
gboolean ret = TRUE;
gdouble pr = rspamd_random_double_fast ();
+ static const guint max_recursion = 20;
+
+ if (recursion > max_recursion) {
+ msg_err_task ("cyclic dependencies: maximum check level %ud exceed when "
+ "checking dependencies for %s", max_recursion, item->symbol);
+
+ return TRUE;
+ }
if (item->deps != NULL && item->deps->len > 0) {
for (i = 0; i < item->deps->len; i ++) {
/* Not started */
if (!rspamd_symbols_cache_check_deps (task, cache,
dep->item,
- checkpoint)) {
+ checkpoint,
+ recursion + 1)) {
g_ptr_array_add (checkpoint->waitq, item);
ret = FALSE;
msg_debug_task ("delayed dependency %d for symbol %d",
if (!isset (checkpoint->processed_bits, item->id * 2)) {
if (!rspamd_symbols_cache_check_deps (task, cache, item,
- checkpoint)) {
+ checkpoint, 0)) {
msg_debug_task ("blocked execution of %d unless deps are "
"resolved",
item->id);
if (!isset (checkpoint->processed_bits, item->id * 2)) {
if (!rspamd_symbols_cache_check_deps (task, cache, item,
- checkpoint)) {
+ checkpoint, 0)) {
break;
}