commit ad664dd: [Feature] Allow to explicitly set events backend

Vsevolod Stakhov vsevolod at highsecure.ru
Sun Oct 27 12:21:06 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-10-27 09:42:59 +0000
URL: https://github.com/rspamd/rspamd/commit/ad664dd4c66be1f803dcdf208bb228478422f102

[Feature] Allow to explicitly set events backend

---
 src/libserver/cfg_file.h    |  4 +++
 src/libserver/cfg_rcl.c     |  6 ++++
 src/libserver/cfg_utils.c   | 76 +++++++++++++++++++++++++++++++++++++++++++++
 src/libserver/worker_util.c |  3 +-
 src/rspamd.c                | 41 ++++++------------------
 5 files changed, 97 insertions(+), 33 deletions(-)

diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 3ee832d5a..0aa8df36c 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -439,6 +439,7 @@ struct rspamd_config {
 	gchar *history_file;                           /**< file to save rolling history						*/
 	gchar *tld_file;                               /**< file to load effective tld list from				*/
 	gchar *hs_cache_dir;                           /**< directory to save hyperscan databases				*/
+	gchar *events_backend;                         /**< string representation of the events backend used	*/
 
 	gdouble dns_timeout;                            /**< timeout in milliseconds for waiting for dns reply	*/
 	guint32 dns_retransmits;                        /**< maximum retransmits count							*/
@@ -808,6 +809,9 @@ struct rspamd_action *rspamd_config_get_action (struct rspamd_config *cfg,
 struct rspamd_action *rspamd_config_get_action_by_type (struct rspamd_config *cfg,
 														enum rspamd_action_type type);
 
+int rspamd_config_ev_backend_get (struct rspamd_config *cfg);
+const gchar * rspamd_config_ev_backend_to_string (int ev_backend, gboolean *effective);
+
 #define msg_err_config(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \
         cfg->cfg_pool->tag.tagname, cfg->checksum, \
         G_STRFUNC, \
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index 7936c8725..bc2d50bb2 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -2207,6 +2207,12 @@ rspamd_rcl_config_init (struct rspamd_config *cfg, GHashTable *skip_sections)
 				G_STRUCT_OFFSET (struct rspamd_config, max_blas_threads),
 				RSPAMD_CL_FLAG_INT_32,
 				"Maximum number of Blas threads for learning neural networks (default: 1)");
+		rspamd_rcl_add_default_handler (sub,
+				"events_backend",
+				rspamd_rcl_parse_struct_string,
+				G_STRUCT_OFFSET (struct rspamd_config, events_backend),
+				0,
+				"Events backend to use: kqueue, epoll, select, poll or auto (default: auto)");
 
 		/* Neighbours configuration */
 		rspamd_rcl_add_section_doc (&sub->subsections, "neighbours", "name",
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 98a50bea3..59840847b 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -2511,3 +2511,79 @@ rspamd_config_register_settings_id (struct rspamd_config *cfg,
 		DL_APPEND (cfg->setting_ids, elt);
 	}
 }
+
+int
+rspamd_config_ev_backend_get (struct rspamd_config *cfg)
+{
+	if (cfg == NULL || cfg->events_backend == NULL) {
+		return ev_supported_backends ();
+	}
+
+	if (strcmp (cfg->events_backend, "auto") == 0) {
+		return ev_supported_backends ();
+	}
+	else if (strcmp (cfg->events_backend, "epoll") == 0) {
+		if (ev_supported_backends () & EVBACKEND_EPOLL) {
+			return EVBACKEND_EPOLL;
+		}
+		else {
+			msg_warn_config ("unsupported events_backend: %s; defaulting to auto",
+					cfg->events_backend);
+			return ev_supported_backends ();
+		}
+	}
+	else if (strcmp (cfg->events_backend, "kqueue") == 0) {
+		if (ev_supported_backends () & EVBACKEND_KQUEUE) {
+			return EVBACKEND_KQUEUE;
+		}
+		else {
+			msg_warn_config ("unsupported events_backend: %s; defaulting to auto",
+					cfg->events_backend);
+			return ev_supported_backends ();
+		}
+	}
+	else if (strcmp (cfg->events_backend, "poll") == 0) {
+		return EVBACKEND_POLL;
+	}
+	else if (strcmp (cfg->events_backend, "select") == 0) {
+		return EVBACKEND_SELECT;
+	}
+	else {
+		msg_warn_config ("unknown events_backend: %s; defaulting to auto",
+				cfg->events_backend);
+	}
+
+	return EVBACKEND_ALL;
+}
+
+const gchar *
+rspamd_config_ev_backend_to_string (int ev_backend, gboolean *effective)
+{
+#define SET_EFFECTIVE(b) do { if ((effective) != NULL) *(effective) = b; } while(0)
+
+	if ((ev_backend & EVBACKEND_ALL) == EVBACKEND_ALL) {
+		SET_EFFECTIVE (TRUE);
+		return "auto";
+	}
+
+	if (ev_backend & EVBACKEND_EPOLL) {
+		SET_EFFECTIVE (TRUE);
+		return "epoll";
+	}
+	if (ev_backend & EVBACKEND_KQUEUE) {
+		SET_EFFECTIVE (TRUE);
+		return "kqueue";
+	}
+	if (ev_backend & EVBACKEND_POLL) {
+		SET_EFFECTIVE (FALSE);
+		return "poll";
+	}
+	if (ev_backend & EVBACKEND_SELECT) {
+		SET_EFFECTIVE (FALSE);
+		return "select";
+	}
+
+	SET_EFFECTIVE (FALSE);
+	return "unknown";
+#undef SET_EFFECTIVE
+}
\ No newline at end of file
diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c
index 630d1fbbd..c45060aa6 100644
--- a/src/libserver/worker_util.c
+++ b/src/libserver/worker_util.c
@@ -361,7 +361,8 @@ rspamd_prepare_worker (struct rspamd_worker *worker, const char *name,
 	worker->signal_events = g_hash_table_new_full (g_direct_hash, g_direct_equal,
 			NULL, rspamd_sigh_free);
 
-	event_loop = ev_loop_new (EVBACKEND_ALL|EVFLAG_SIGNALFD);
+	event_loop = ev_loop_new (rspamd_config_ev_backend_get (worker->srv->cfg) |
+			EVFLAG_SIGNALFD);
 
 	worker->srv->event_loop = event_loop;
 
diff --git a/src/rspamd.c b/src/rspamd.c
index f726865e7..4b33e7577 100644
--- a/src/rspamd.c
+++ b/src/rspamd.c
@@ -1387,42 +1387,19 @@ main (gint argc, gchar **argv, gchar **env)
 	rspamd_main->workers = g_hash_table_new (g_direct_hash, g_direct_equal);
 
 	/* Init event base */
-	event_loop = ev_default_loop (EVFLAG_SIGNALFD|EVBACKEND_ALL);
+	event_loop = ev_default_loop (EVFLAG_SIGNALFD|
+			rspamd_config_ev_backend_get (rspamd_main->cfg));
 	rspamd_main->event_loop = event_loop;
 
 	if (event_loop) {
-		unsigned loop_type = ev_backend (event_loop);
-		const gchar *loop_str = "unknown";
-		gboolean poor_backend = TRUE;
-
-		switch (loop_type) {
-		case EVBACKEND_EPOLL:
-			loop_str = "epoll";
-			poor_backend = FALSE;
-			break;
-		case EVBACKEND_POLL:
-			loop_str = "poll";
-			break;
-		case EVBACKEND_SELECT:
-			loop_str = "select";
-			break;
-		case EVBACKEND_KQUEUE:
-			loop_str = "kqueue";
-			poor_backend = FALSE;
-			break;
-		case EVBACKEND_PORT:
-			loop_str = "port";
-			poor_backend = FALSE;
-			break;
-		case EVBACKEND_DEVPOLL:
-			loop_str = "/dev/poll";
-			poor_backend = FALSE;
-			break;
-		default:
-			break;
-		}
+		int loop_type = ev_backend (event_loop);
+		gboolean effective_backend;
+		const gchar *loop_str;
+
+		loop_str =
+				rspamd_config_ev_backend_to_string (loop_type, &effective_backend);
 
-		if (poor_backend) {
+		if (!effective_backend) {
 			msg_warn_main ("event loop uses non-optimal backend: %s", loop_str);
 		}
 		else {


More information about the Commits mailing list