diff --git a/bus/bus.c b/bus/bus.c
index 62d58f8e..cf251234 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -1513,6 +1513,12 @@ bus_context_get_max_replies_per_connection (BusContext *context)
return context->limits.max_replies_per_connection;
}
+int
+bus_context_get_max_messages_for_service_per_connection (BusContext *context)
+{
+ return context->limits.max_messages_for_service_per_connection;
+}
+
int
bus_context_get_reply_timeout (BusContext *context)
{
diff --git a/bus/bus.h b/bus/bus.h
index 88451ebb..6ca0a1fe 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -67,6 +67,7 @@ typedef struct
int max_services_per_connection; /**< Max number of owned services for a single connection */
int max_match_rules_per_connection; /**< Max number of match rules for a single connection */
int max_replies_per_connection; /**< Max number of replies that can be pending for each connection */
+ int max_messages_for_service_per_connection; /**< Max number of messages that can be pending for a single service per connection */
int reply_timeout; /**< How long to wait before timing out a reply */
int max_containers; /**< Max number of restricted servers for app-containers */
int max_containers_per_user; /**< Max number of restricted servers for app-containers, per user */
@@ -129,6 +130,8 @@ int bus_context_get_max_pending_activations (BusContext
int bus_context_get_max_services_per_connection (BusContext *context);
int bus_context_get_max_match_rules_per_connection (BusContext *context);
int bus_context_get_max_replies_per_connection (BusContext *context);
+int bus_context_get_max_messages_for_service_per_connection
+ (BusContext *context);
int bus_context_get_reply_timeout (BusContext *context);
int bus_context_get_max_containers (BusContext *context);
int bus_context_get_max_containers_per_user (BusContext *context);
diff --git a/bus/config-parser.c b/bus/config-parser.c
index cb388473..4e26e091 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -554,6 +554,12 @@ bus_config_parser_new (const DBusString *basedir,
* that require a reply
*/
parser->limits.max_replies_per_connection = 128;
+
+ /* Limit the maximum number of pending messages for a single service
+ * per connection. The default is half the pending replies limit for
+ * the connection.
+ */
+ parser->limits.max_messages_for_service_per_connection = 64;
}
parser->refcount = 1;
@@ -2189,6 +2195,12 @@ set_limit (BusConfigParser *parser,
must_be_int = TRUE;
parser->limits.max_replies_per_connection = value;
}
+ else if (strcmp (name, "max_messages_for_service_per_connection") == 0)
+ {
+ must_be_positive = TRUE;
+ must_be_int = TRUE;
+ parser->limits.max_messages_for_service_per_connection = value;
+ }
else if (strcmp (name, "max_containers") == 0)
{
must_be_positive = TRUE;
@@ -3496,6 +3508,7 @@ limits_equal (const BusLimits *a,
&& a->max_services_per_connection == b->max_services_per_connection
&& a->max_match_rules_per_connection == b->max_match_rules_per_connection
&& a->max_replies_per_connection == b->max_replies_per_connection
+ && a->max_messages_for_service_per_connection == b->max_messages_for_service_per_connection
&& a->reply_timeout == b->reply_timeout);
}
diff --git a/bus/connection.c b/bus/connection.c
index f0177c6f..41e09f66 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -1960,7 +1960,8 @@ bus_connections_expect_reply (BusConnections *connections,
dbus_uint32_t reply_serial;
DBusList *link;
CancelPendingReplyData *cprd;
- int count;
+ int wait_for_replies_count;
+ int service_outgoing_msg_count;
int limit;
_dbus_assert (will_get_reply != NULL);
@@ -1973,7 +1974,8 @@ bus_connections_expect_reply (BusConnections *connections,
reply_serial = dbus_message_get_serial (reply_to_this);
link = bus_expire_list_get_first_link (connections->pending_replies);
- count = 0;
+ wait_for_replies_count = 0;
+ service_outgoing_msg_count = 0;
while (link != NULL)
{
pending = link->data;
@@ -1990,12 +1992,31 @@ bus_connections_expect_reply (BusConnections *connections,
link = bus_expire_list_get_next_link (connections->pending_replies,
link);
if (pending->will_get_reply == will_get_reply)
- ++count;
+ ++wait_for_replies_count;
+ if (pending->will_send_reply == will_send_reply)
+ ++service_outgoing_msg_count;
}
+ limit = bus_context_get_max_messages_for_service_per_connection (connections->context);
+
+ if (service_outgoing_msg_count >= limit)
+ {
+ bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
+ "the maximum number of pending messages for "
+ "\"%s\" (%s) has been reached "
+ "(max_messages_for_service_per_connection=%d)",
+ bus_connection_get_name (will_send_reply),
+ bus_connection_get_loginfo (will_send_reply),
+ limit);
+
+ dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
+ "the maximum number of pending messages for service per connection has been reached");
+ return FALSE;
+ }
+
limit = bus_context_get_max_replies_per_connection (connections->context);
- if (count >= limit)
+ if (wait_for_replies_count >= limit)
{
bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
"The maximum number of pending replies for "
diff --git a/bus/session.conf.in b/bus/session.conf.in
index affa7f1d..6b2531fd 100644
--- a/bus/session.conf.in
+++ b/bus/session.conf.in
@@ -76,5 +76,6 @@
50000
50000
50000
+ 25000
diff --git a/bus/system.conf.in b/bus/system.conf.in
index dea09bd5..a442da5a 100644
--- a/bus/system.conf.in
+++ b/bus/system.conf.in
@@ -126,6 +126,7 @@
+
diff --git a/doc/dbus-daemon.1.xml.in b/doc/dbus-daemon.1.xml.in
index 5bf93b93..0fe13b83 100644
--- a/doc/dbus-daemon.1.xml.in
+++ b/doc/dbus-daemon.1.xml.in
@@ -854,6 +854,9 @@ Available limit names are:
"max_replies_per_connection" : max number of pending method
replies per connection
(number of calls-in-progress)
+ "max_messages_for_service_per_connection": max number of pending method
+ calls for a single service per
+ connection.
"reply_timeout" : milliseconds (thousandths)
until a method call times out
diff --git a/test/data/valid-config-files-system/tmp-session-like-system.conf.in b/test/data/valid-config-files-system/tmp-session-like-system.conf.in
index 9665a22a..d59d1b3b 100644
--- a/test/data/valid-config-files-system/tmp-session-like-system.conf.in
+++ b/test/data/valid-config-files-system/tmp-session-like-system.conf.in
@@ -84,6 +84,7 @@
50000
50000
50000
+ 25000
300000
diff --git a/test/data/valid-config-files/incoming-limit.conf.in b/test/data/valid-config-files/incoming-limit.conf.in
index cd813442..ba789545 100644
--- a/test/data/valid-config-files/incoming-limit.conf.in
+++ b/test/data/valid-config-files/incoming-limit.conf.in
@@ -18,4 +18,5 @@
1000000
+ 500000
diff --git a/test/data/valid-config-files/max-replies-per-connection.conf.in b/test/data/valid-config-files/max-replies-per-connection.conf.in
index d4615ed8..79e01abc 100644
--- a/test/data/valid-config-files/max-replies-per-connection.conf.in
+++ b/test/data/valid-config-files/max-replies-per-connection.conf.in
@@ -15,4 +15,6 @@
3
+
+ 10000
diff --git a/test/data/valid-config-files/tmp-session.conf.in b/test/data/valid-config-files/tmp-session.conf.in
index d1effae1..206ba29b 100644
--- a/test/data/valid-config-files/tmp-session.conf.in
+++ b/test/data/valid-config-files/tmp-session.conf.in
@@ -57,4 +57,5 @@
50000
50000
50000
+ 25000