Merge branch 'reversed-dns-37095'
[platform/upstream/dbus.git] / dbus / dbus-pending-call.c
index 51b9378..e7f5cd9 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
+#include <config.h>
 #include "dbus-internals.h"
 #include "dbus-connection-internal.h"
 #include "dbus-pending-call-internal.h"
@@ -83,7 +84,9 @@ static dbus_int32_t notify_user_data_slot = -1;
  * Creates a new pending reply object.
  *
  * @param connection connection where reply will arrive
- * @param timeout_milliseconds length of timeout, -1 for default
+ * @param timeout_milliseconds length of timeout, -1 (or
+ *  #DBUS_TIMEOUT_USE_DEFAULT) for default,
+ *  #DBUS_TIMEOUT_INFINITE for no timeout
  * @param timeout_handler timeout handler, takes pending call as data
  * @returns a new #DBusPendingCall or #NULL if no memory.
  */
@@ -100,14 +103,6 @@ _dbus_pending_call_new_unlocked (DBusConnection    *connection,
   if (timeout_milliseconds == -1)
     timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;
 
-  /* it would probably seem logical to pass in _DBUS_INT_MAX for
-   * infinite timeout, but then math in
-   * _dbus_connection_block_for_reply would get all overflow-prone, so
-   * smack that down.
-   */
-  if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6)
-    timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6;
-  
   if (!dbus_pending_call_allocate_data_slot (&notify_user_data_slot))
     return NULL;
   
@@ -119,24 +114,30 @@ _dbus_pending_call_new_unlocked (DBusConnection    *connection,
       return NULL;
     }
 
-  timeout = _dbus_timeout_new (timeout_milliseconds,
-                               timeout_handler,
-                              pending, NULL);  
-
-  if (timeout == NULL)
+  if (timeout_milliseconds != DBUS_TIMEOUT_INFINITE)
     {
-      dbus_pending_call_free_data_slot (&notify_user_data_slot);
-      dbus_free (pending);
-      return NULL;
+      timeout = _dbus_timeout_new (timeout_milliseconds,
+                                   timeout_handler,
+                                   pending, NULL);  
+
+      if (timeout == NULL)
+        {
+          dbus_pending_call_free_data_slot (&notify_user_data_slot);
+          dbus_free (pending);
+          return NULL;
+        }
+
+      pending->timeout = timeout;
     }
-  
-  pending->refcount.value = 1;
+  else
+    {
+      pending->timeout = NULL;
+    }
+
+  _dbus_atomic_inc (&pending->refcount);
   pending->connection = connection;
   _dbus_connection_ref_unlocked (pending->connection);
 
-  pending->timeout = timeout;
-
-
   _dbus_data_slot_list_init (&pending->slot_list);
   
   return pending;
@@ -255,7 +256,7 @@ _dbus_pending_call_set_timeout_added_unlocked (DBusPendingCall  *pending,
  * Retrives the timeout
  *
  * @param pending the pending_call
- * @returns a timeout object 
+ * @returns a timeout object or NULL if call has no timeout
  */
 DBusTimeout *
 _dbus_pending_call_get_timeout_unlocked (DBusPendingCall  *pending)
@@ -352,6 +353,8 @@ _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending,
   reply_link = _dbus_list_alloc_link (reply);
   if (reply_link == NULL)
     {
+      /* it's OK to unref this, nothing that could have attached a callback
+       * has ever seen it */
       dbus_message_unref (reply);
       return FALSE;
     }
@@ -373,8 +376,8 @@ _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending,
 DBusPendingCall *
 _dbus_pending_call_ref_unlocked (DBusPendingCall *pending)
 {
-  pending->refcount.value += 1;
-  
+  _dbus_atomic_inc (&pending->refcount);
+
   return pending;
 }
 
@@ -432,15 +435,14 @@ _dbus_pending_call_last_unref (DBusPendingCall *pending)
 void
 _dbus_pending_call_unref_and_unlock (DBusPendingCall *pending)
 {
-  dbus_bool_t last_unref;
-  
-  _dbus_assert (pending->refcount.value > 0);
+  dbus_int32_t old_refcount;
 
-  pending->refcount.value -= 1;
-  last_unref = pending->refcount.value == 0;
+  old_refcount = _dbus_atomic_dec (&pending->refcount);
+  _dbus_assert (old_refcount > 0);
 
   CONNECTION_UNLOCK (pending->connection);
-  if (last_unref)
+
+  if (old_refcount == 1)
     _dbus_pending_call_last_unref (pending);
 }
 
@@ -517,6 +519,26 @@ _dbus_pending_call_set_data_unlocked (DBusPendingCall  *pending,
  */
 
 /**
+ * @def DBUS_TIMEOUT_INFINITE
+ *
+ * An integer constant representing an infinite timeout. This has the
+ * numeric value 0x7fffffff (the largest 32-bit signed integer).
+ *
+ * For source compatibility with D-Bus versions earlier than 1.4.12, use
+ * 0x7fffffff, or INT32_MAX (assuming your platform has it).
+ */
+
+/**
+ * @def DBUS_TIMEOUT_USE_DEFAULT
+ *
+ * An integer constant representing a request to use the default timeout.
+ * This has numeric value -1.
+ *
+ * For source compatibility with D-Bus versions earlier than 1.4.12, use a
+ * literal -1.
+ */
+
+/**
  * @typedef DBusPendingCall
  *
  * Opaque data type representing a message pending.
@@ -533,19 +555,8 @@ dbus_pending_call_ref (DBusPendingCall *pending)
 {
   _dbus_return_val_if_fail (pending != NULL, NULL);
 
-  /* The connection lock is better than the global
-   * lock in the atomic increment fallback
-   */
-#ifdef DBUS_HAVE_ATOMIC_INT
   _dbus_atomic_inc (&pending->refcount);
-#else
-  CONNECTION_LOCK (pending->connection);
-  _dbus_assert (pending->refcount.value > 0);
 
-  pending->refcount.value += 1;
-  CONNECTION_UNLOCK (pending->connection);
-#endif
-  
   return pending;
 }
 
@@ -562,19 +573,8 @@ dbus_pending_call_unref (DBusPendingCall *pending)
 
   _dbus_return_if_fail (pending != NULL);
 
-  /* More efficient to use the connection lock instead of atomic
-   * int fallback if we lack atomic int decrement
-   */
-#ifdef DBUS_HAVE_ATOMIC_INT
   last_unref = (_dbus_atomic_dec (&pending->refcount) == 1);
-#else
-  CONNECTION_LOCK (pending->connection);
-  _dbus_assert (pending->refcount.value > 0);
-  pending->refcount.value -= 1;
-  last_unref = pending->refcount.value == 0;
-  CONNECTION_UNLOCK (pending->connection);
-#endif
-  
+
   if (last_unref)
     _dbus_pending_call_last_unref(pending);
 }
@@ -808,19 +808,3 @@ dbus_pending_call_get_data (DBusPendingCall   *pending,
 }
 
 /** @} */
-
-#ifdef DBUS_BUILD_TESTS
-
-/**
- * @ingroup DBusPendingCallInternals
- * Unit test for DBusPendingCall.
- *
- * @returns #TRUE on success.
- */
-dbus_bool_t
-_dbus_pending_call_test (const char *test_data_dir)
-{  
-
-  return TRUE;
-}
-#endif /* DBUS_BUILD_TESTS */