You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

symcache_c.cxx 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. /*
  2. * Copyright 2023 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "symcache_internal.hxx"
  17. #include "symcache_periodic.hxx"
  18. #include "symcache_item.hxx"
  19. #include "symcache_runtime.hxx"
  20. /**
  21. * C API for symcache
  22. */
  23. #define C_API_SYMCACHE(ptr) (reinterpret_cast<rspamd::symcache::symcache *>(ptr))
  24. #define C_API_SYMCACHE_RUNTIME(ptr) (reinterpret_cast<rspamd::symcache::symcache_runtime *>(ptr))
  25. #define C_API_SYMCACHE_ITEM(ptr) (reinterpret_cast<rspamd::symcache::cache_item *>(ptr))
  26. #define C_API_SYMCACHE_DYN_ITEM(ptr) (reinterpret_cast<rspamd::symcache::cache_dynamic_item *>(ptr))
  27. void rspamd_symcache_destroy(struct rspamd_symcache *cache)
  28. {
  29. auto *real_cache = C_API_SYMCACHE(cache);
  30. delete real_cache;
  31. }
  32. struct rspamd_symcache *
  33. rspamd_symcache_new(struct rspamd_config *cfg)
  34. {
  35. auto *ncache = new rspamd::symcache::symcache(cfg);
  36. return (struct rspamd_symcache *) ncache;
  37. }
  38. gboolean
  39. rspamd_symcache_init(struct rspamd_symcache *cache)
  40. {
  41. auto *real_cache = C_API_SYMCACHE(cache);
  42. return real_cache->init();
  43. }
  44. void rspamd_symcache_save(struct rspamd_symcache *cache)
  45. {
  46. auto *real_cache = C_API_SYMCACHE(cache);
  47. real_cache->save_items();
  48. }
  49. gint rspamd_symcache_add_symbol(struct rspamd_symcache *cache,
  50. const gchar *name,
  51. gint priority,
  52. symbol_func_t func,
  53. gpointer user_data,
  54. int type,
  55. gint parent)
  56. {
  57. auto *real_cache = C_API_SYMCACHE(cache);
  58. /* Legacy stuff */
  59. if (name == nullptr) {
  60. name = "";
  61. }
  62. if (parent == -1) {
  63. return real_cache->add_symbol_with_callback(name, priority, func, user_data, type);
  64. }
  65. else {
  66. return real_cache->add_virtual_symbol(name, parent, type);
  67. }
  68. }
  69. bool rspamd_symcache_add_symbol_augmentation(struct rspamd_symcache *cache,
  70. int sym_id,
  71. const char *augmentation,
  72. const char *value)
  73. {
  74. auto *real_cache = C_API_SYMCACHE(cache);
  75. auto log_tag = [&]() { return real_cache->log_tag(); };
  76. if (augmentation == nullptr) {
  77. msg_err_cache("null augmentation is not allowed for item %d", sym_id);
  78. return false;
  79. }
  80. auto *item = real_cache->get_item_by_id_mut(sym_id, false);
  81. if (item == nullptr) {
  82. msg_err_cache("item %d is not found", sym_id);
  83. return false;
  84. }
  85. /* Handle empty or absent strings equally */
  86. if (value == nullptr || value[0] == '\0') {
  87. return item->add_augmentation(*real_cache, augmentation, std::nullopt);
  88. }
  89. return item->add_augmentation(*real_cache, augmentation, value);
  90. }
  91. void rspamd_symcache_set_peak_callback(struct rspamd_symcache *cache, gint cbref)
  92. {
  93. auto *real_cache = C_API_SYMCACHE(cache);
  94. real_cache->set_peak_cb(cbref);
  95. }
  96. gboolean
  97. rspamd_symcache_add_condition_delayed(struct rspamd_symcache *cache,
  98. const gchar *sym, lua_State *L, gint cbref)
  99. {
  100. auto *real_cache = C_API_SYMCACHE(cache);
  101. real_cache->add_delayed_condition(sym, cbref);
  102. return TRUE;
  103. }
  104. gint rspamd_symcache_find_symbol(struct rspamd_symcache *cache,
  105. const gchar *name)
  106. {
  107. auto *real_cache = C_API_SYMCACHE(cache);
  108. /* Legacy stuff but used */
  109. if (name == nullptr) {
  110. return -1;
  111. }
  112. auto sym_maybe = real_cache->get_item_by_name(name, false);
  113. if (sym_maybe != nullptr) {
  114. return sym_maybe->id;
  115. }
  116. return -1;
  117. }
  118. gboolean
  119. rspamd_symcache_stat_symbol(struct rspamd_symcache *cache,
  120. const gchar *name,
  121. gdouble *frequency,
  122. gdouble *freq_stddev,
  123. gdouble *tm,
  124. guint *nhits)
  125. {
  126. auto *real_cache = C_API_SYMCACHE(cache);
  127. auto sym_maybe = real_cache->get_item_by_name(name, false);
  128. if (sym_maybe != nullptr) {
  129. *frequency = sym_maybe->st->avg_frequency;
  130. *freq_stddev = sqrt(sym_maybe->st->stddev_frequency);
  131. *tm = sym_maybe->st->time_counter.mean;
  132. if (nhits) {
  133. *nhits = sym_maybe->st->hits;
  134. }
  135. return TRUE;
  136. }
  137. return FALSE;
  138. }
  139. guint rspamd_symcache_stats_symbols_count(struct rspamd_symcache *cache)
  140. {
  141. auto *real_cache = C_API_SYMCACHE(cache);
  142. return real_cache->get_stats_symbols_count();
  143. }
  144. uint64_t
  145. rspamd_symcache_get_cksum(struct rspamd_symcache *cache)
  146. {
  147. auto *real_cache = C_API_SYMCACHE(cache);
  148. return real_cache->get_cksum();
  149. }
  150. gboolean
  151. rspamd_symcache_validate(struct rspamd_symcache *cache,
  152. struct rspamd_config *cfg,
  153. gboolean strict)
  154. {
  155. auto *real_cache = C_API_SYMCACHE(cache);
  156. return real_cache->validate(strict);
  157. }
  158. ucl_object_t *
  159. rspamd_symcache_counters(struct rspamd_symcache *cache)
  160. {
  161. auto *real_cache = C_API_SYMCACHE(cache);
  162. return real_cache->counters();
  163. }
  164. void *
  165. rspamd_symcache_start_refresh(struct rspamd_symcache *cache,
  166. struct ev_loop *ev_base, struct rspamd_worker *w)
  167. {
  168. auto *real_cache = C_API_SYMCACHE(cache);
  169. return new rspamd::symcache::cache_refresh_cbdata{real_cache, ev_base, w};
  170. }
  171. void rspamd_symcache_inc_frequency(struct rspamd_symcache *cache, struct rspamd_symcache_item *item,
  172. const char *sym_name)
  173. {
  174. auto *real_item = C_API_SYMCACHE_ITEM(item);
  175. auto *real_cache = C_API_SYMCACHE(cache);
  176. if (real_item) {
  177. real_item->inc_frequency(sym_name, *real_cache);
  178. }
  179. }
  180. void rspamd_symcache_add_delayed_dependency(struct rspamd_symcache *cache,
  181. const gchar *from, const gchar *to)
  182. {
  183. auto *real_cache = C_API_SYMCACHE(cache);
  184. real_cache->add_delayed_dependency(from, to);
  185. }
  186. const gchar *
  187. rspamd_symcache_get_parent(struct rspamd_symcache *cache,
  188. const gchar *symbol)
  189. {
  190. auto *real_cache = C_API_SYMCACHE(cache);
  191. auto *sym = real_cache->get_item_by_name(symbol, false);
  192. if (sym && sym->is_virtual()) {
  193. auto *parent = sym->get_parent(*real_cache);
  194. if (parent) {
  195. return parent->get_name().c_str();
  196. }
  197. }
  198. return nullptr;
  199. }
  200. const gchar *
  201. rspamd_symcache_item_name(struct rspamd_symcache_item *item)
  202. {
  203. auto *real_item = C_API_SYMCACHE_ITEM(item);
  204. if (real_item == nullptr) {
  205. return nullptr;
  206. }
  207. return real_item->get_name().c_str();
  208. }
  209. gint rspamd_symcache_item_flags(struct rspamd_symcache_item *item)
  210. {
  211. auto *real_item = C_API_SYMCACHE_ITEM(item);
  212. if (real_item == nullptr) {
  213. return 0;
  214. }
  215. return real_item->get_flags();
  216. }
  217. const gchar *
  218. rspamd_symcache_dyn_item_name(struct rspamd_task *task,
  219. struct rspamd_symcache_dynamic_item *dyn_item)
  220. {
  221. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  222. auto *real_dyn_item = C_API_SYMCACHE_DYN_ITEM(dyn_item);
  223. if (cache_runtime == nullptr || real_dyn_item == nullptr) {
  224. return nullptr;
  225. }
  226. auto static_item = cache_runtime->get_item_by_dynamic_item(real_dyn_item);
  227. return static_item->get_name().c_str();
  228. }
  229. gint rspamd_symcache_item_flags(struct rspamd_task *task,
  230. struct rspamd_symcache_dynamic_item *dyn_item)
  231. {
  232. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  233. auto *real_dyn_item = C_API_SYMCACHE_DYN_ITEM(dyn_item);
  234. if (cache_runtime == nullptr || real_dyn_item == nullptr) {
  235. return 0;
  236. }
  237. auto static_item = cache_runtime->get_item_by_dynamic_item(real_dyn_item);
  238. return static_item->get_flags();
  239. }
  240. guint rspamd_symcache_get_symbol_flags(struct rspamd_symcache *cache,
  241. const gchar *symbol)
  242. {
  243. auto *real_cache = C_API_SYMCACHE(cache);
  244. auto *sym = real_cache->get_item_by_name(symbol, false);
  245. if (sym) {
  246. return sym->get_flags();
  247. }
  248. return 0;
  249. }
  250. const struct rspamd_symcache_item_stat *
  251. rspamd_symcache_item_stat(struct rspamd_symcache_item *item)
  252. {
  253. auto *real_item = C_API_SYMCACHE_ITEM(item);
  254. return real_item->st;
  255. }
  256. void rspamd_symcache_get_symbol_details(struct rspamd_symcache *cache,
  257. const gchar *symbol,
  258. ucl_object_t *this_sym_ucl)
  259. {
  260. auto *real_cache = C_API_SYMCACHE(cache);
  261. auto *sym = real_cache->get_item_by_name(symbol, false);
  262. if (sym) {
  263. ucl_object_insert_key(this_sym_ucl,
  264. ucl_object_fromstring(sym->get_type_str()),
  265. "type", strlen("type"), false);
  266. }
  267. }
  268. void rspamd_symcache_foreach(struct rspamd_symcache *cache,
  269. void (*func)(struct rspamd_symcache_item *item, gpointer /* userdata */),
  270. gpointer ud)
  271. {
  272. auto *real_cache = C_API_SYMCACHE(cache);
  273. real_cache->symbols_foreach([&](const rspamd::symcache::cache_item *item) {
  274. func((struct rspamd_symcache_item *) item, ud);
  275. });
  276. }
  277. void rspamd_symcache_process_settings_elt(struct rspamd_symcache *cache,
  278. struct rspamd_config_settings_elt *elt)
  279. {
  280. auto *real_cache = C_API_SYMCACHE(cache);
  281. real_cache->process_settings_elt(elt);
  282. }
  283. bool rspamd_symcache_set_allowed_settings_ids(struct rspamd_symcache *cache,
  284. const gchar *symbol,
  285. const uint32_t *ids,
  286. guint nids)
  287. {
  288. auto *real_cache = C_API_SYMCACHE(cache);
  289. auto *item = real_cache->get_item_by_name_mut(symbol, false);
  290. if (item == nullptr) {
  291. return false;
  292. }
  293. item->allowed_ids.set_ids(ids, nids);
  294. return true;
  295. }
  296. bool rspamd_symcache_set_forbidden_settings_ids(struct rspamd_symcache *cache,
  297. const gchar *symbol,
  298. const uint32_t *ids,
  299. guint nids)
  300. {
  301. auto *real_cache = C_API_SYMCACHE(cache);
  302. auto *item = real_cache->get_item_by_name_mut(symbol, false);
  303. if (item == nullptr) {
  304. return false;
  305. }
  306. item->forbidden_ids.set_ids(ids, nids);
  307. return true;
  308. }
  309. const uint32_t *
  310. rspamd_symcache_get_allowed_settings_ids(struct rspamd_symcache *cache,
  311. const gchar *symbol,
  312. guint *nids)
  313. {
  314. auto *real_cache = C_API_SYMCACHE(cache);
  315. const auto *item = real_cache->get_item_by_name(symbol, false);
  316. return item->allowed_ids.get_ids(*nids);
  317. }
  318. const uint32_t *
  319. rspamd_symcache_get_forbidden_settings_ids(struct rspamd_symcache *cache,
  320. const gchar *symbol,
  321. guint *nids)
  322. {
  323. auto *real_cache = C_API_SYMCACHE(cache);
  324. const auto *item = real_cache->get_item_by_name(symbol, false);
  325. return item->forbidden_ids.get_ids(*nids);
  326. }
  327. void rspamd_symcache_disable_all_symbols(struct rspamd_task *task,
  328. struct rspamd_symcache *_cache,
  329. guint skip_mask)
  330. {
  331. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  332. cache_runtime->disable_all_symbols(skip_mask);
  333. }
  334. gboolean
  335. rspamd_symcache_disable_symbol(struct rspamd_task *task,
  336. struct rspamd_symcache *cache,
  337. const gchar *symbol)
  338. {
  339. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  340. auto *real_cache = C_API_SYMCACHE(cache);
  341. if (cache_runtime == nullptr) {
  342. return FALSE;
  343. }
  344. return cache_runtime->disable_symbol(task, *real_cache, symbol);
  345. }
  346. gboolean
  347. rspamd_symcache_enable_symbol(struct rspamd_task *task,
  348. struct rspamd_symcache *cache,
  349. const gchar *symbol)
  350. {
  351. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  352. auto *real_cache = C_API_SYMCACHE(cache);
  353. if (cache_runtime == nullptr) {
  354. return FALSE;
  355. }
  356. return cache_runtime->enable_symbol(task, *real_cache, symbol);
  357. }
  358. void rspamd_symcache_disable_symbol_static(struct rspamd_symcache *cache,
  359. const gchar *symbol)
  360. {
  361. auto *real_cache = C_API_SYMCACHE(cache);
  362. real_cache->disable_symbol_delayed(symbol);
  363. }
  364. void rspamd_symcache_enable_symbol_static(struct rspamd_symcache *cache,
  365. const gchar *symbol)
  366. {
  367. auto *real_cache = C_API_SYMCACHE(cache);
  368. real_cache->enable_symbol_delayed(symbol);
  369. }
  370. /* A real structure to match C results without extra copying */
  371. struct rspamd_symcache_real_timeout_result {
  372. struct rspamd_symcache_timeout_result c_api_result;
  373. std::vector<std::pair<double, const rspamd::symcache::cache_item *>> elts;
  374. };
  375. struct rspamd_symcache_timeout_result *
  376. rspamd_symcache_get_max_timeout(struct rspamd_symcache *cache)
  377. {
  378. auto *real_cache = C_API_SYMCACHE(cache);
  379. auto *res = new rspamd_symcache_real_timeout_result;
  380. res->c_api_result.max_timeout = real_cache->get_max_timeout(res->elts);
  381. res->c_api_result.items = reinterpret_cast<struct rspamd_symcache_timeout_item *>(res->elts.data());
  382. res->c_api_result.nitems = res->elts.size();
  383. return &res->c_api_result;
  384. }
  385. void rspamd_symcache_timeout_result_free(struct rspamd_symcache_timeout_result *res)
  386. {
  387. auto *real_result = reinterpret_cast<rspamd_symcache_real_timeout_result *>(res);
  388. delete real_result;
  389. }
  390. gboolean
  391. rspamd_symcache_is_checked(struct rspamd_task *task,
  392. struct rspamd_symcache *cache,
  393. const gchar *symbol)
  394. {
  395. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  396. auto *real_cache = C_API_SYMCACHE(cache);
  397. if (cache_runtime == nullptr) {
  398. return FALSE;
  399. }
  400. return cache_runtime->is_symbol_checked(*real_cache, symbol);
  401. }
  402. gboolean
  403. rspamd_symcache_process_settings(struct rspamd_task *task,
  404. struct rspamd_symcache *cache)
  405. {
  406. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  407. auto *real_cache = C_API_SYMCACHE(cache);
  408. if (cache_runtime == nullptr) {
  409. return FALSE;
  410. }
  411. return cache_runtime->process_settings(task, *real_cache);
  412. }
  413. gboolean
  414. rspamd_symcache_is_item_allowed(struct rspamd_task *task,
  415. struct rspamd_symcache_item *item,
  416. gboolean exec_only)
  417. {
  418. auto *real_item = C_API_SYMCACHE_ITEM(item);
  419. if (real_item == nullptr) {
  420. return TRUE;
  421. }
  422. return real_item->is_allowed(task, exec_only);
  423. }
  424. gboolean
  425. rspamd_symcache_is_symbol_enabled(struct rspamd_task *task,
  426. struct rspamd_symcache *cache,
  427. const gchar *symbol)
  428. {
  429. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  430. auto *real_cache = C_API_SYMCACHE(cache);
  431. if (!cache_runtime) {
  432. return TRUE;
  433. }
  434. return cache_runtime->is_symbol_enabled(task, *real_cache, symbol);
  435. }
  436. struct rspamd_symcache_dynamic_item *
  437. rspamd_symcache_get_cur_item(struct rspamd_task *task)
  438. {
  439. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  440. if (!cache_runtime) {
  441. return nullptr;
  442. }
  443. return (struct rspamd_symcache_dynamic_item *) cache_runtime->get_cur_item();
  444. }
  445. struct rspamd_symcache_dynamic_item *
  446. rspamd_symcache_set_cur_item(struct rspamd_task *task, struct rspamd_symcache_dynamic_item *item)
  447. {
  448. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  449. auto *real_dyn_item = C_API_SYMCACHE_DYN_ITEM(item);
  450. if (!cache_runtime || !real_dyn_item) {
  451. return nullptr;
  452. }
  453. return (struct rspamd_symcache_dynamic_item *) cache_runtime->set_cur_item(real_dyn_item);
  454. }
  455. void rspamd_symcache_enable_profile(struct rspamd_task *task)
  456. {
  457. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  458. if (!cache_runtime) {
  459. return;
  460. }
  461. cache_runtime->set_profile_mode(true);
  462. }
  463. guint rspamd_symcache_item_async_inc_full(struct rspamd_task *task,
  464. struct rspamd_symcache_dynamic_item *item,
  465. const gchar *subsystem,
  466. const gchar *loc)
  467. {
  468. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  469. auto *real_dyn_item = C_API_SYMCACHE_DYN_ITEM(item);
  470. auto *static_item = cache_runtime->get_item_by_dynamic_item(real_dyn_item);
  471. msg_debug_cache_task("increase async events counter for %s(%d) = %d + 1; "
  472. "subsystem %s (%s)",
  473. static_item->symbol.c_str(), static_item->id,
  474. real_dyn_item->async_events, subsystem, loc);
  475. return ++real_dyn_item->async_events;
  476. }
  477. guint rspamd_symcache_item_async_dec_full(struct rspamd_task *task,
  478. struct rspamd_symcache_dynamic_item *item,
  479. const gchar *subsystem,
  480. const gchar *loc)
  481. {
  482. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  483. auto *real_dyn_item = C_API_SYMCACHE_DYN_ITEM(item);
  484. auto *static_item = cache_runtime->get_item_by_dynamic_item(real_dyn_item);
  485. msg_debug_cache_task("decrease async events counter for %s(%d) = %d - 1; "
  486. "subsystem %s (%s)",
  487. static_item->symbol.c_str(), static_item->id,
  488. real_dyn_item->async_events, subsystem, loc);
  489. if (G_UNLIKELY(real_dyn_item->async_events == 0)) {
  490. msg_err_cache_task("INTERNAL ERROR: trying decrease async events counter for %s(%d) that is already zero; "
  491. "subsystem %s (%s)",
  492. static_item->symbol.c_str(), static_item->id,
  493. real_dyn_item->async_events, subsystem, loc);
  494. g_abort();
  495. g_assert_not_reached();
  496. }
  497. return --real_dyn_item->async_events;
  498. }
  499. gboolean
  500. rspamd_symcache_item_async_dec_check_full(struct rspamd_task *task,
  501. struct rspamd_symcache_dynamic_item *item,
  502. const gchar *subsystem,
  503. const gchar *loc)
  504. {
  505. if (rspamd_symcache_item_async_dec_full(task, item, subsystem, loc) == 0) {
  506. rspamd_symcache_finalize_item(task, item);
  507. return TRUE;
  508. }
  509. return FALSE;
  510. }
  511. struct rspamd_abstract_callback_data *
  512. rspamd_symcache_get_cbdata(struct rspamd_symcache *cache,
  513. const gchar *symbol)
  514. {
  515. auto *real_cache = C_API_SYMCACHE(cache);
  516. auto *item = real_cache->get_item_by_name(symbol, true);
  517. if (item) {
  518. return (struct rspamd_abstract_callback_data *) item->get_cbdata();
  519. }
  520. return nullptr;
  521. }
  522. void rspamd_symcache_composites_foreach(struct rspamd_task *task,
  523. struct rspamd_symcache *cache,
  524. GHFunc func,
  525. gpointer fd)
  526. {
  527. auto *real_cache = C_API_SYMCACHE(cache);
  528. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  529. real_cache->composites_foreach([&](const auto *item) {
  530. auto *dyn_item = cache_runtime->get_dynamic_item(item->id);
  531. if (dyn_item && !dyn_item->started) {
  532. auto *old_item = cache_runtime->set_cur_item(dyn_item);
  533. func((void *) item->get_name().c_str(), item->get_cbdata(), fd);
  534. dyn_item->finished = true;
  535. cache_runtime->set_cur_item(old_item);
  536. }
  537. });
  538. cache_runtime->set_cur_item(nullptr);
  539. }
  540. gboolean
  541. rspamd_symcache_process_symbols(struct rspamd_task *task,
  542. struct rspamd_symcache *cache,
  543. guint stage)
  544. {
  545. auto *real_cache = C_API_SYMCACHE(cache);
  546. if (task->symcache_runtime == nullptr) {
  547. task->symcache_runtime = rspamd::symcache::symcache_runtime::create(task, *real_cache);
  548. }
  549. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  550. return cache_runtime->process_symbols(task, *real_cache, stage);
  551. }
  552. void rspamd_symcache_finalize_item(struct rspamd_task *task,
  553. struct rspamd_symcache_dynamic_item *item)
  554. {
  555. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  556. auto *real_dyn_item = C_API_SYMCACHE_DYN_ITEM(item);
  557. cache_runtime->finalize_item(task, real_dyn_item);
  558. }
  559. void rspamd_symcache_runtime_destroy(struct rspamd_task *task)
  560. {
  561. auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime);
  562. cache_runtime->savepoint_dtor();
  563. }