unix-fd: add logic to count unix fds the same way as allocated memory
authorLennart Poettering <lennart@poettering.net>
Tue, 19 May 2009 23:32:46 +0000 (01:32 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 20 May 2009 00:09:32 +0000 (02:09 +0200)
This make all counters count both bytes of memory and unix fds.

dbus/dbus-connection.c
dbus/dbus-connection.h
dbus/dbus-message-internal.h
dbus/dbus-message-private.h
dbus/dbus-message.c
dbus/dbus-resources.c
dbus/dbus-resources.h
dbus/dbus-transport-protected.h
dbus/dbus-transport-socket.c
dbus/dbus-transport.c
dbus/dbus-transport.h

index 8433b64..e46fbc3 100644 (file)
@@ -627,8 +627,8 @@ _dbus_connection_message_sent (DBusConnection *connection,
                  connection, connection->n_outgoing);
 
   /* Save this link in the link cache also */
-  _dbus_message_remove_size_counter (message, connection->outgoing_counter,
-                                     &link);
+  _dbus_message_remove_counter (message, connection->outgoing_counter,
+                                &link);
   _dbus_list_prepend_link (&connection->link_cache, link);
   
   dbus_message_unref (message);
@@ -1922,8 +1922,8 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *con
   _dbus_list_prepend_link (&connection->outgoing_messages,
                            preallocated->queue_link);
 
-  _dbus_message_add_size_counter_link (message,
-                                       preallocated->counter_link);
+  _dbus_message_add_counter_link (message,
+                                  preallocated->counter_link);
 
   dbus_free (preallocated);
   preallocated = NULL;
@@ -2539,9 +2539,9 @@ free_outgoing_message (void *element,
   DBusMessage *message = element;
   DBusConnection *connection = data;
 
-  _dbus_message_remove_size_counter (message,
-                                     connection->outgoing_counter,
-                                     NULL);
+  _dbus_message_remove_counter (message,
+                                connection->outgoing_counter,
+                                NULL);
   dbus_message_unref (message);
 }
 
@@ -5932,6 +5932,45 @@ dbus_connection_get_max_message_size (DBusConnection *connection)
 }
 
 /**
+ * Specifies the maximum number of unix fds a message on this
+ * connection is allowed to receive. Messages with more unix fds will
+ * result in disconnecting the connection.
+ *
+ * @param connection a #DBusConnection
+ * @param size maximum message unix fds the connection can receive
+ */
+void
+dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
+                                          long            n)
+{
+  _dbus_return_if_fail (connection != NULL);
+
+  CONNECTION_LOCK (connection);
+  _dbus_transport_set_max_message_unix_fds (connection->transport,
+                                            n);
+  CONNECTION_UNLOCK (connection);
+}
+
+/**
+ * Gets the value set by dbus_connection_set_max_message_unix_fds().
+ *
+ * @param connection the connection
+ * @returns the max numer of unix fds of a single message
+ */
+long
+dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
+{
+  long res;
+
+  _dbus_return_val_if_fail (connection != NULL, 0);
+
+  CONNECTION_LOCK (connection);
+  res = _dbus_transport_get_max_message_unix_fds (connection->transport);
+  CONNECTION_UNLOCK (connection);
+  return res;
+}
+
+/**
  * Sets the maximum total number of bytes that can be used for all messages
  * received on this connection. Messages count toward the maximum until
  * they are finalized. When the maximum is reached, the connection will
@@ -5988,6 +6027,48 @@ dbus_connection_get_max_received_size (DBusConnection *connection)
 }
 
 /**
+ * Sets the maximum total number of unix fds that can be used for all messages
+ * received on this connection. Messages count toward the maximum until
+ * they are finalized. When the maximum is reached, the connection will
+ * not read more data until some messages are finalized.
+ *
+ * The semantics are analogous to those of dbus_connection_set_max_received_size().
+ *
+ * @param connection the connection
+ * @param size the maximum size in bytes of all outstanding messages
+ */
+void
+dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
+                                           long            n)
+{
+  _dbus_return_if_fail (connection != NULL);
+
+  CONNECTION_LOCK (connection);
+  _dbus_transport_set_max_received_unix_fds (connection->transport,
+                                             n);
+  CONNECTION_UNLOCK (connection);
+}
+
+/**
+ * Gets the value set by dbus_connection_set_max_received_unix_fds().
+ *
+ * @param connection the connection
+ * @returns the max unix fds of all live messages
+ */
+long
+dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
+{
+  long res;
+
+  _dbus_return_val_if_fail (connection != NULL, 0);
+
+  CONNECTION_LOCK (connection);
+  res = _dbus_transport_get_max_received_unix_fds (connection->transport);
+  CONNECTION_UNLOCK (connection);
+  return res;
+}
+
+/**
  * Gets the approximate size in bytes of all messages in the outgoing
  * message queue. The size is approximate in that you shouldn't use
  * it to decide how many bytes to read off the network or anything
@@ -6003,9 +6084,29 @@ dbus_connection_get_outgoing_size (DBusConnection *connection)
   long res;
 
   _dbus_return_val_if_fail (connection != NULL, 0);
-  
+
+  CONNECTION_LOCK (connection);
+  res = _dbus_counter_get_size_value (connection->outgoing_counter);
+  CONNECTION_UNLOCK (connection);
+  return res;
+}
+
+/**
+ * Gets the approximate number of uni fds of all messages in the
+ * outgoing message queue.
+ *
+ * @param connection the connection
+ * @returns the number of unix fds that have been queued up but not sent
+ */
+long
+dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
+{
+  long res;
+
+  _dbus_return_val_if_fail (connection != NULL, 0);
+
   CONNECTION_LOCK (connection);
-  res = _dbus_counter_get_value (connection->outgoing_counter);
+  res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
   CONNECTION_UNLOCK (connection);
   return res;
 }
index c9b9aa3..3facc87 100644 (file)
@@ -281,7 +281,16 @@ long dbus_connection_get_max_message_size  (DBusConnection *connection);
 void dbus_connection_set_max_received_size (DBusConnection *connection,
                                             long            size);
 long dbus_connection_get_max_received_size (DBusConnection *connection);
+
+void dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
+                                               long            n);
+long dbus_connection_get_max_message_unix_fds (DBusConnection *connection);
+void dbus_connection_set_max_received_unix_fds(DBusConnection *connection,
+                                               long            n);
+long dbus_connection_get_max_received_unix_fds(DBusConnection *connection);
+
 long dbus_connection_get_outgoing_size     (DBusConnection *connection);
+long dbus_connection_get_outgoing_unix_fds (DBusConnection *connection);
 
 DBusPreallocatedSend* dbus_connection_preallocate_send       (DBusConnection       *connection);
 void                  dbus_connection_free_preallocated_send (DBusConnection       *connection,
index 032268f..0565d61 100644 (file)
@@ -40,11 +40,11 @@ void _dbus_message_get_unix_fds      (DBusMessage *messgage,
 
 void        _dbus_message_lock                  (DBusMessage  *message);
 void        _dbus_message_unlock                (DBusMessage  *message);
-dbus_bool_t _dbus_message_add_size_counter      (DBusMessage  *message,
+dbus_bool_t _dbus_message_add_counter           (DBusMessage  *message,
                                                  DBusCounter  *counter);
-void        _dbus_message_add_size_counter_link (DBusMessage  *message,
+void        _dbus_message_add_counter_link      (DBusMessage  *message,
                                                  DBusList     *link);
-void        _dbus_message_remove_size_counter   (DBusMessage  *message,
+void        _dbus_message_remove_counter        (DBusMessage  *message,
                                                  DBusCounter  *counter,
                                                  DBusList    **link_return);
 
index 1e8b107..03257a9 100644 (file)
@@ -112,7 +112,7 @@ struct DBusMessage
   unsigned int in_cache : 1; /**< Has been "freed" since it's in the cache (this is a debug feature) */
 #endif
 
-  DBusList *size_counters;   /**< 0-N DBusCounter used to track message size. */
+  DBusList *counters;   /**< 0-N DBusCounter used to track message size/unix fds. */
   long size_counter_delta;   /**< Size we incremented the size counters by.   */
 
   dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS; /**< Incremented when iterators are invalidated. */
@@ -130,6 +130,8 @@ struct DBusMessage
      them when adding or removing them here. */
   unsigned n_unix_fds; /**< Number of valid fds in the array */
   unsigned n_unix_fds_allocated; /**< Allocated size of the array */
+
+  long unix_fd_counter_delta; /**< Size we incremented the unix fd counter by */
 #endif
 };
 
index 54bceb0..4533d5a 100644 (file)
@@ -209,20 +209,19 @@ dbus_message_set_serial (DBusMessage   *message,
 }
 
 /**
- * Adds a counter to be incremented immediately with the
- * size of this message, and decremented by the size
- * of this message when this message if finalized.
- * The link contains a counter with its refcount already
- * incremented, but the counter itself not incremented.
- * Ownership of link and counter refcount is passed to
- * the message.
+ * Adds a counter to be incremented immediately with the size/unix fds
+ * of this message, and decremented by the size/unix fds of this
+ * message when this message if finalized.  The link contains a
+ * counter with its refcount already incremented, but the counter
+ * itself not incremented.  Ownership of link and counter refcount is
+ * passed to the message.
  *
  * @param message the message
  * @param link link with counter as data
  */
 void
-_dbus_message_add_size_counter_link (DBusMessage  *message,
-                                     DBusList     *link)
+_dbus_message_add_counter_link (DBusMessage  *message,
+                                DBusList     *link)
 {
   /* right now we don't recompute the delta when message
    * size changes, and that's OK for current purposes
@@ -230,35 +229,43 @@ _dbus_message_add_size_counter_link (DBusMessage  *message,
    * Do recompute it whenever there are no outstanding counters,
    * since it's basically free.
    */
-  if (message->size_counters == NULL)
+  if (message->counters == NULL)
     {
       message->size_counter_delta =
         _dbus_string_get_length (&message->header.data) +
         _dbus_string_get_length (&message->body);
 
+#ifdef HAVE_UNIX_FD_PASSING
+      message->unix_fd_counter_delta = message->n_unix_fds;
+#endif
+
 #if 0
       _dbus_verbose ("message has size %ld\n",
                      message->size_counter_delta);
 #endif
     }
 
-  _dbus_list_append_link (&message->size_counters, link);
+  _dbus_list_append_link (&message->counters, link);
 
-  _dbus_counter_adjust (link->data, message->size_counter_delta);
+  _dbus_counter_adjust_size (link->data, message->size_counter_delta);
+
+#ifdef HAVE_UNIX_FD_PASSING
+  _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
+#endif
 }
 
 /**
- * Adds a counter to be incremented immediately with the
- * size of this message, and decremented by the size
- * of this message when this message if finalized.
+ * Adds a counter to be incremented immediately with the size/unix fds
+ * of this message, and decremented by the size/unix fds of this
+ * message when this message if finalized.
  *
  * @param message the message
  * @param counter the counter
  * @returns #FALSE if no memory
  */
 dbus_bool_t
-_dbus_message_add_size_counter (DBusMessage *message,
-                                DBusCounter *counter)
+_dbus_message_add_counter (DBusMessage *message,
+                           DBusCounter *counter)
 {
   DBusList *link;
 
@@ -267,38 +274,42 @@ _dbus_message_add_size_counter (DBusMessage *message,
     return FALSE;
 
   _dbus_counter_ref (counter);
-  _dbus_message_add_size_counter_link (message, link);
+  _dbus_message_add_counter_link (message, link);
 
   return TRUE;
 }
 
 /**
- * Removes a counter tracking the size of this message, and decrements
- * the counter by the size of this message.
+ * Removes a counter tracking the size/unix fds of this message, and
+ * decrements the counter by the size/unix fds of this message.
  *
  * @param message the message
  * @param link_return return the link used
  * @param counter the counter
  */
 void
-_dbus_message_remove_size_counter (DBusMessage  *message,
-                                   DBusCounter  *counter,
-                                   DBusList    **link_return)
+_dbus_message_remove_counter (DBusMessage  *message,
+                              DBusCounter  *counter,
+                              DBusList    **link_return)
 {
   DBusList *link;
 
-  link = _dbus_list_find_last (&message->size_counters,
+  link = _dbus_list_find_last (&message->counters,
                                counter);
   _dbus_assert (link != NULL);
 
-  _dbus_list_unlink (&message->size_counters,
+  _dbus_list_unlink (&message->counters,
                      link);
   if (link_return)
     *link_return = link;
   else
     _dbus_list_free_link (link);
 
-  _dbus_counter_adjust (counter, - message->size_counter_delta);
+  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
+
+#ifdef HAVE_UNIX_FD_PASSING
+  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
+#endif
 
   _dbus_counter_unref (counter);
 }
@@ -515,7 +526,7 @@ dbus_message_get_cached (void)
   _dbus_assert (message != NULL);
 
   _dbus_assert (message->refcount.value == 0);
-  _dbus_assert (message->size_counters == NULL);
+  _dbus_assert (message->counters == NULL);
   
   _DBUS_UNLOCK (message_cache);
 
@@ -550,13 +561,16 @@ close_unix_fds(int *fds, unsigned *n_fds)
 #endif
 
 static void
-free_size_counter (void *element,
-                   void *data)
+free_counter (void *element,
+              void *data)
 {
   DBusCounter *counter = element;
   DBusMessage *message = data;
 
-  _dbus_counter_adjust (counter, - message->size_counter_delta);
+  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
+#ifdef HAVE_UNIX_FD_PASSING
+  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
+#endif
 
   _dbus_counter_unref (counter);
 }
@@ -579,9 +593,9 @@ dbus_message_cache_or_finalize (DBusMessage *message)
    */
   _dbus_data_slot_list_clear (&message->slot_list);
 
-  _dbus_list_foreach (&message->size_counters,
-                      free_size_counter, message);
-  _dbus_list_clear (&message->size_counters);
+  _dbus_list_foreach (&message->counters,
+                      free_counter, message);
+  _dbus_list_clear (&message->counters);
 
 #ifdef HAVE_UNIX_FD_PASSING
   close_unix_fds(message->unix_fds, &message->n_unix_fds);
@@ -1033,9 +1047,9 @@ dbus_message_finalize (DBusMessage *message)
   /* This calls application callbacks! */
   _dbus_data_slot_list_free (&message->slot_list);
 
-  _dbus_list_foreach (&message->size_counters,
-                      free_size_counter, message);
-  _dbus_list_clear (&message->size_counters);
+  _dbus_list_foreach (&message->counters,
+                      free_counter, message);
+  _dbus_list_clear (&message->counters);
 
   _dbus_header_free (&message->header);
   _dbus_string_free (&message->body);
@@ -1084,12 +1098,13 @@ dbus_message_new_empty_header (void)
 #ifndef DBUS_DISABLE_CHECKS
   message->in_cache = FALSE;
 #endif
-  message->size_counters = NULL;
+  message->counters = NULL;
   message->size_counter_delta = 0;
   message->changed_stamp = 0;
 
 #ifdef HAVE_UNIX_FD_PASSING
   message->n_unix_fds = 0;
+  message->unix_fd_counter_delta = 0;
 #endif
 
   if (!from_cache)
index 5ff1622..e6dcde1 100644 (file)
@@ -29,7 +29,7 @@
  * @brief DBusCounter and other stuff related to resource limits
  *
  * Types and functions related to tracking resource limits,
- * such as the maximum amount of memory a connection can use
+ * such as the maximum amount of memory/unix fds a connection can use
  * for messages, etc.
  */
 
@@ -53,9 +53,12 @@ struct DBusCounter
 {
   int refcount;  /**< reference count */
 
-  long value;    /**< current counter value */
+  long size_value;       /**< current size counter value */
+  long unix_fd_value;    /**< current unix fd counter value */
+
+  long notify_size_guard_value;    /**< call notify function when crossing this size value */
+  long notify_unix_fd_guard_value; /**< call notify function when crossing this unix fd value */
 
-  long notify_guard_value; /**< call notify function when crossing this value */
   DBusCounterNotifyFunction notify_function; /**< notify function */
   void *notify_data; /**< data for notify function */
 };
@@ -83,9 +86,11 @@ _dbus_counter_new (void)
     return NULL;
   
   counter->refcount = 1;
-  counter->value = 0;
+  counter->size_value = 0;
+  counter->unix_fd_value = 0;
 
-  counter->notify_guard_value = 0;
+  counter->notify_size_guard_value = 0;
+  counter->notify_unix_fd_guard_value = 0;
   counter->notify_function = NULL;
   counter->notify_data = NULL;
   
@@ -129,64 +134,109 @@ _dbus_counter_unref (DBusCounter *counter)
 }
 
 /**
- * Adjusts the value of the counter by the given
+ * Adjusts the value of the size counter by the given
+ * delta which may be positive or negative.
+ * Calls the notify function from _dbus_counter_set_notify()
+ * if that function has been specified.
+ *
+ * @param counter the counter
+ * @param delta value to add to the size counter's current value
+ */
+void
+_dbus_counter_adjust_size (DBusCounter *counter,
+                           long         delta)
+{
+  long old = counter->size_value;
+
+  counter->size_value += delta;
+
+#if 0
+  _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n",
+                 old, delta, counter->size_value);
+#endif
+
+  if (counter->notify_function != NULL &&
+      ((old < counter->notify_size_guard_value &&
+        counter->size_value >= counter->notify_size_guard_value) ||
+       (old >= counter->notify_size_guard_value &&
+        counter->size_value < counter->notify_size_guard_value)))
+    (* counter->notify_function) (counter, counter->notify_data);
+}
+
+/**
+ * Adjusts the value of the unix fd counter by the given
  * delta which may be positive or negative.
  * Calls the notify function from _dbus_counter_set_notify()
  * if that function has been specified.
  *
  * @param counter the counter
- * @param delta value to add to the counter's current value
+ * @param delta value to add to the unix fds counter's current value
  */
 void
-_dbus_counter_adjust (DBusCounter *counter,
-                      long         delta)
+_dbus_counter_adjust_unix_fd (DBusCounter *counter,
+                              long         delta)
 {
-  long old = counter->value;
+  long old = counter->unix_fd_value;
   
-  counter->value += delta;
+  counter->unix_fd_value += delta;
 
 #if 0
   _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n",
-                 old, delta, counter->value);
+                 old, delta, counter->unix_fd_value);
 #endif
   
   if (counter->notify_function != NULL &&
-      ((old < counter->notify_guard_value &&
-        counter->value >= counter->notify_guard_value) ||
-       (old >= counter->notify_guard_value &&
-        counter->value < counter->notify_guard_value)))
+      ((old < counter->notify_unix_fd_guard_value &&
+        counter->unix_fd_value >= counter->notify_unix_fd_guard_value) ||
+       (old >= counter->notify_unix_fd_guard_value &&
+        counter->unix_fd_value < counter->notify_unix_fd_guard_value)))
     (* counter->notify_function) (counter, counter->notify_data);
 }
 
 /**
- * Gets the current value of the counter.
+ * Gets the current value of the size counter.
+ *
+ * @param counter the counter
+ * @returns its current size value
+ */
+long
+_dbus_counter_get_size_value (DBusCounter *counter)
+{
+  return counter->size_value;
+}
+
+/**
+ * Gets the current value of the unix fd counter.
  *
  * @param counter the counter
- * @returns its current value
+ * @returns its current unix fd value
  */
 long
-_dbus_counter_get_value (DBusCounter *counter)
+_dbus_counter_get_unix_fd_value (DBusCounter *counter)
 {
-  return counter->value;
+  return counter->unix_fd_value;
 }
 
 /**
  * Sets the notify function for this counter; the notify function is
- * called whenever the counter's value crosses the guard value in
+ * called whenever the counter's values cross the guard values in
  * either direction (moving up, or moving down).
  *
  * @param counter the counter
- * @param guard_value the value we're notified if the counter crosses
+ * @param size_guard_value the value we're notified if the size counter crosses
+ * @param unix_fd_guard_value the value we're notified if the unix fd counter crosses
  * @param function function to call in order to notify
  * @param user_data data to pass to the function
  */
 void
 _dbus_counter_set_notify (DBusCounter               *counter,
-                          long                       guard_value,
+                          long                       size_guard_value,
+                          long                       unix_fd_guard_value,
                           DBusCounterNotifyFunction  function,
                           void                      *user_data)
 {
-  counter->notify_guard_value = guard_value;
+  counter->notify_size_guard_value = size_guard_value;
+  counter->notify_unix_fd_guard_value = unix_fd_guard_value;
   counter->notify_function = function;
   counter->notify_data = user_data;
 }
index 7b6e0d4..cf3cc1a 100644 (file)
@@ -37,14 +37,19 @@ typedef void (* DBusCounterNotifyFunction) (DBusCounter *counter,
 DBusCounter* _dbus_counter_new       (void);
 DBusCounter* _dbus_counter_ref       (DBusCounter *counter);
 void         _dbus_counter_unref     (DBusCounter *counter);
-void         _dbus_counter_adjust    (DBusCounter *counter,
-                                      long         delta);
-long         _dbus_counter_get_value (DBusCounter *counter);
-
-void _dbus_counter_set_notify (DBusCounter               *counter,
-                               long                       guard_value,
-                               DBusCounterNotifyFunction  function,
-                               void                      *user_data);
+
+void         _dbus_counter_adjust_size       (DBusCounter *counter,
+                                              long         delta);
+void         _dbus_counter_adjust_unix_fd    (DBusCounter *counter,
+                                              long         delta);
+long         _dbus_counter_get_size_value    (DBusCounter *counter);
+long         _dbus_counter_get_unix_fd_value (DBusCounter *counter);
+
+void _dbus_counter_set_notify    (DBusCounter               *counter,
+                                  long                       size_guard_value,
+                                  long                       unix_fd_guard_value,
+                                  DBusCounterNotifyFunction  function,
+                                  void                      *user_data);
 
 
 DBUS_END_DECLS
index 8c389a6..50ec6ce 100644 (file)
@@ -73,10 +73,6 @@ struct DBusTransportVTable
   /**< Get socket file descriptor */
 };
 
-/** How many unix file descriptors may be queued up before they are
-   handed off to messages */
-#define DBUS_MAX_QUEUED_FDS 1024
-
 /**
  * Object representing a transport such as a socket.
  * A transport can shuttle messages from point A to point B,
@@ -98,9 +94,9 @@ struct DBusTransport
   DBusCredentials *credentials;               /**< Credentials of other end read from the socket */  
 
   long max_live_messages_size;                /**< Max total size of received messages. */
+  long max_live_messages_unix_fds;            /**< Max total unix fds of received messages. */
 
-  DBusCounter *live_messages_size;            /**< Counter for size of all live messages. */
-
+  DBusCounter *live_messages;                 /**< Counter for size/unix fds of all live messages. */
 
   char *address;                              /**< Address of the server we are connecting to (#NULL for the server side of a transport) */
 
index 7669950..8e13bae 100644 (file)
@@ -191,7 +191,8 @@ check_read_watch (DBusTransport *transport)
 
   if (_dbus_transport_get_is_authenticated (transport))
     need_read_watch =
-      _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
+      (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
+      (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
   else
     {
       if (transport->receive_credentials_pending)
index 7ba0135..11edc6a 100644 (file)
@@ -57,7 +57,7 @@
  */
 
 static void
-live_messages_size_notify (DBusCounter *counter,
+live_messages_notify (DBusCounter *counter,
                            void        *user_data)
 {
   DBusTransport *transport = user_data;
@@ -65,8 +65,10 @@ live_messages_size_notify (DBusCounter *counter,
   _dbus_transport_ref (transport);
 
 #if 0
-  _dbus_verbose ("Counter value is now %d\n",
-                 (int) _dbus_counter_get_value (counter));
+  _dbus_verbose ("Size counter value is now %d\n",
+                 (int) _dbus_counter_get_size_value (counter));
+  _dbus_verbose ("Unix FD counter value is now %d\n",
+                 (int) _dbus_counter_get_unix_fd_value (counter));
 #endif
   
   /* disable or re-enable the read watch for the transport if
@@ -157,7 +159,7 @@ _dbus_transport_init_base (DBusTransport             *transport,
   transport->vtable = vtable;
   transport->loader = loader;
   transport->auth = auth;
-  transport->live_messages_size = counter;
+  transport->live_messages = counter;
   transport->authenticated = FALSE;
   transport->disconnected = FALSE;
   transport->is_server = (server_guid != NULL);
@@ -180,17 +182,17 @@ _dbus_transport_init_base (DBusTransport             *transport,
    */
   transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
 
+  /* On Linux RLIMIT_NOFILE defaults to 1024, so allowing 4096 fds live
+     should be more than enough */
+  transport->max_live_messages_unix_fds = 4096;
+
   /* credentials read from socket if any */
   transport->credentials = creds;
 
-#ifdef HAVE_UNIX_FD_PASSING
-  transport->unix_fds = NULL;
-  transport->n_unix_fds = 0;
-#endif
-
-  _dbus_counter_set_notify (transport->live_messages_size,
+  _dbus_counter_set_notify (transport->live_messages,
                             transport->max_live_messages_size,
-                            live_messages_size_notify,
+                            transport->max_live_messages_unix_fds,
+                            live_messages_notify,
                             transport);
 
   if (transport->address)
@@ -219,9 +221,9 @@ _dbus_transport_finalize_base (DBusTransport *transport)
   
   _dbus_message_loader_unref (transport->loader);
   _dbus_auth_unref (transport->auth);
-  _dbus_counter_set_notify (transport->live_messages_size,
-                            0, NULL, NULL);
-  _dbus_counter_unref (transport->live_messages_size);
+  _dbus_counter_set_notify (transport->live_messages,
+                            0, 0, NULL, NULL);
+  _dbus_counter_unref (transport->live_messages);
   dbus_free (transport->address);
   dbus_free (transport->expected_guid);
   if (transport->credentials)
@@ -1078,7 +1080,8 @@ recover_unused_bytes (DBusTransport *transport)
 DBusDispatchStatus
 _dbus_transport_get_dispatch_status (DBusTransport *transport)
 {
-  if (_dbus_counter_get_value (transport->live_messages_size) >= transport->max_live_messages_size)
+  if (_dbus_counter_get_size_value (transport->live_messages) >= transport->max_live_messages_size ||
+      _dbus_counter_get_unix_fd_value (transport->live_messages) >= transport->max_live_messages_unix_fds)
     return DBUS_DISPATCH_COMPLETE; /* complete for now */
 
   if (!_dbus_transport_get_is_authenticated (transport))
@@ -1135,7 +1138,7 @@ _dbus_transport_queue_messages (DBusTransport *transport)
       
       _dbus_verbose ("queueing received message %p\n", message);
 
-      if (!_dbus_message_add_size_counter (message, transport->live_messages_size))
+      if (!_dbus_message_add_counter (message, transport->live_messages))
         {
           _dbus_message_loader_putback_message_link (transport->loader,
                                                      link);
@@ -1173,6 +1176,19 @@ _dbus_transport_set_max_message_size (DBusTransport  *transport,
 }
 
 /**
+ * See dbus_connection_set_max_message_unix_fds().
+ *
+ * @param transport the transport
+ * @param n the max number of unix fds of a single message
+ */
+void
+_dbus_transport_set_max_message_unix_fds (DBusTransport  *transport,
+                                          long            n)
+{
+  _dbus_message_loader_set_max_message_unix_fds (transport->loader, n);
+}
+
+/**
  * See dbus_connection_get_max_message_size().
  *
  * @param transport the transport
@@ -1185,6 +1201,18 @@ _dbus_transport_get_max_message_size (DBusTransport  *transport)
 }
 
 /**
+ * See dbus_connection_get_max_message_unix_fds().
+ *
+ * @param transport the transport
+ * @returns max message unix fds
+ */
+long
+_dbus_transport_get_max_message_unix_fds (DBusTransport  *transport)
+{
+  return _dbus_message_loader_get_max_message_unix_fds (transport->loader);
+}
+
+/**
  * See dbus_connection_set_max_received_size().
  *
  * @param transport the transport
@@ -1195,12 +1223,30 @@ _dbus_transport_set_max_received_size (DBusTransport  *transport,
                                        long            size)
 {
   transport->max_live_messages_size = size;
-  _dbus_counter_set_notify (transport->live_messages_size,
+  _dbus_counter_set_notify (transport->live_messages,
                             transport->max_live_messages_size,
-                            live_messages_size_notify,
+                            transport->max_live_messages_unix_fds,
+                            live_messages_notify,
                             transport);
 }
 
+/**
+ * See dbus_connection_set_max_received_unix_fds().
+ *
+ * @param transport the transport
+ * @param n the max unix fds of all incoming messages
+ */
+void
+_dbus_transport_set_max_received_unix_fds (DBusTransport  *transport,
+                                           long            n)
+{
+  transport->max_live_messages_unix_fds = n;
+  _dbus_counter_set_notify (transport->live_messages,
+                            transport->max_live_messages_size,
+                            transport->max_live_messages_unix_fds,
+                            live_messages_notify,
+                            transport);
+}
 
 /**
  * See dbus_connection_get_max_received_size().
@@ -1215,6 +1261,18 @@ _dbus_transport_get_max_received_size (DBusTransport  *transport)
 }
 
 /**
+ * See dbus_connection_set_max_received_unix_fds().
+ *
+ * @param transport the transport
+ * @returns max unix fds for all live messages
+ */
+long
+_dbus_transport_get_max_received_unix_fds (DBusTransport  *transport)
+{
+  return transport->max_live_messages_unix_fds;
+}
+
+/**
  * See dbus_connection_get_unix_user().
  *
  * @param transport the transport
index 4554faf..994bf6e 100644 (file)
@@ -54,12 +54,21 @@ void               _dbus_transport_do_iteration           (DBusTransport
                                                            int                         timeout_milliseconds);
 DBusDispatchStatus _dbus_transport_get_dispatch_status    (DBusTransport              *transport);
 dbus_bool_t        _dbus_transport_queue_messages         (DBusTransport              *transport);
+
 void               _dbus_transport_set_max_message_size   (DBusTransport              *transport,
                                                            long                        size);
 long               _dbus_transport_get_max_message_size   (DBusTransport              *transport);
 void               _dbus_transport_set_max_received_size  (DBusTransport              *transport,
                                                            long                        size);
 long               _dbus_transport_get_max_received_size  (DBusTransport              *transport);
+
+void               _dbus_transport_set_max_message_unix_fds (DBusTransport              *transport,
+                                                             long                        n);
+long               _dbus_transport_get_max_message_unix_fds (DBusTransport              *transport);
+void               _dbus_transport_set_max_received_unix_fds(DBusTransport              *transport,
+                                                             long                        n);
+long               _dbus_transport_get_max_received_unix_fds(DBusTransport              *transport);
+
 dbus_bool_t        _dbus_transport_get_socket_fd          (DBusTransport              *transport,
                                                            int                        *fd_p);
 dbus_bool_t        _dbus_transport_get_unix_user          (DBusTransport              *transport,