/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-pending-call.c Object representing a call in progress.
 *
 * Copyright (C) 2002, 2003 Red Hat Inc.
 *
 * Licensed under the Academic Free License version 2.1
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "dbus-internals.h"
#include "dbus-connection-internal.h"
#include "dbus-message-internal.h"
#include "dbus-pending-call-internal.h"
#include "dbus-pending-call.h"
#include "dbus-list.h"
#include "dbus-threads.h"
#include "dbus-test.h"

/**
 * @defgroup DBusPendingCallInternals DBusPendingCall implementation details
 * @ingroup DBusInternals
 * @brief DBusPendingCall private implementation details.
 *
 * The guts of DBusPendingCall and its methods.
 *
 * @{
 */

/**
 * @brief Internals of DBusPendingCall
 *
 * Opaque object representing a reply message that we're waiting for.
 */

/**
 * shorter and more visible way to write _dbus_connection_lock()
 */
#define CONNECTION_LOCK(connection)   _dbus_connection_lock(connection)
/**
 * shorter and more visible way to write _dbus_connection_unlock()
 */
#define CONNECTION_UNLOCK(connection) _dbus_connection_unlock(connection)

/**
 * Implementation details of #DBusPendingCall - all fields are private.
 */
struct DBusPendingCall
{
  DBusAtomic refcount;                            /**< reference count */

  DBusDataSlotList slot_list;                     /**< Data stored by allocated integer ID */
  
  DBusPendingCallNotifyFunction function;         /**< Notifier when reply arrives. */

  DBusConnection *connection;                     /**< Connections we're associated with */
  DBusMessage *reply;                             /**< Reply (after we've received it) */
  DBusTimeout *timeout;                           /**< Timeout */

  DBusList *timeout_link;                         /**< Preallocated timeout response */
  
  dbus_uint32_t reply_serial;                     /**< Expected serial of reply */

  unsigned int completed : 1;                     /**< TRUE if completed */
  unsigned int timeout_added : 1;                 /**< Have added the timeout */
};

#ifdef DBUS_ENABLE_VERBOSE_MODE
static void
_dbus_pending_call_trace_ref (DBusPendingCall *pending_call,
    int old_refcount,
    int new_refcount,
    const char *why)
{
  static int enabled = -1;

  _dbus_trace_ref ("DBusPendingCall", pending_call, old_refcount,
      new_refcount, why, "DBUS_PENDING_CALL_TRACE", &enabled);
}
#else
#define _dbus_pending_call_trace_ref(p, o, n, w) \
  do \
  {\
    (void) (o); \
    (void) (n); \
  } while (0)
#endif

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 (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.
 */
DBusPendingCall*
_dbus_pending_call_new_unlocked (DBusConnection    *connection,
                                 int                timeout_milliseconds,
                                 DBusTimeoutHandler timeout_handler)
{
  DBusPendingCall *pending;
  DBusTimeout *timeout;

  _dbus_assert (timeout_milliseconds >= 0 || timeout_milliseconds == -1);
 
  if (timeout_milliseconds == -1)
    timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;

  if (!dbus_pending_call_allocate_data_slot (&notify_user_data_slot))
    return NULL;
  
  pending = dbus_new0 (DBusPendingCall, 1);
  
  if (pending == NULL)
    {
      dbus_pending_call_free_data_slot (&notify_user_data_slot);
      return NULL;
    }

  if (timeout_milliseconds != DBUS_TIMEOUT_INFINITE)
    {
      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;
    }
  else
    {
      pending->timeout = NULL;
    }

  _dbus_atomic_inc (&pending->refcount);
  pending->connection = connection;
  _dbus_connection_ref_unlocked (pending->connection);

  _dbus_data_slot_list_init (&pending->slot_list);

  _dbus_pending_call_trace_ref (pending, 0, 1, "new_unlocked");

  return pending;
}

/**
 * Sets the reply of a pending call with the given message,
 * or if the message is #NULL, by timing out the pending call.
 * 
 * @param pending the pending call
 * @param message the message to complete the call with, or #NULL
 *  to time out the call
 */
void
_dbus_pending_call_set_reply_unlocked (DBusPendingCall *pending,
                                       DBusMessage     *message)
{
  if (message == NULL)
    {
      message = pending->timeout_link->data;
      _dbus_list_clear (&pending->timeout_link);
    }
  else
    dbus_message_ref (message);

  _dbus_verbose ("  handing message %p (%s) to pending call serial %u\n",
                 message,
                 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ?
                 "method return" :
                 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ?
                 "error" : "other type",
                 pending->reply_serial);
  
  _dbus_assert (pending->reply == NULL);
  _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message));
  pending->reply = message;
}

/**
 * Calls notifier function for the pending call
 * and sets the call to completed.
 *
 * @param pending the pending call
 * 
 */
void
_dbus_pending_call_complete (DBusPendingCall *pending)
{
  _dbus_assert (!pending->completed);
  
  pending->completed = TRUE;

  if (pending->function)
    {
      void *user_data;
      user_data = dbus_pending_call_get_data (pending,
                                              notify_user_data_slot);
      
      (* pending->function) (pending, user_data);
    }
}

/**
 * If the pending call hasn't been timed out, add its timeout
 * error reply to the connection's incoming message queue.
 *
 * @param pending the pending call
 * @param connection the connection the call was sent to
 */
void
_dbus_pending_call_queue_timeout_error_unlocked (DBusPendingCall *pending, 
                                                 DBusConnection  *connection)
{
  _dbus_assert (connection == pending->connection);
  
  if (pending->timeout_link)
    {
      _dbus_connection_queue_synthesized_message_link (connection,
						       pending->timeout_link);
      pending->timeout_link = NULL;
    }
}

/**
 * Checks to see if a timeout has been added
 *
 * @param pending the pending_call
 * @returns #TRUE if there is a timeout or #FALSE if not
 */
dbus_bool_t 
_dbus_pending_call_is_timeout_added_unlocked (DBusPendingCall  *pending)
{
  _dbus_assert (pending != NULL);

  return pending->timeout_added;
}


/**
 * Sets wether the timeout has been added
 *
 * @param pending the pending_call
 * @param is_added whether or not a timeout is added
 */
void
_dbus_pending_call_set_timeout_added_unlocked (DBusPendingCall  *pending,
                                               dbus_bool_t       is_added)
{
  _dbus_assert (pending != NULL);

  pending->timeout_added = is_added;
}


/**
 * Retrives the timeout
 *
 * @param pending the pending_call
 * @returns a timeout object or NULL if call has no timeout
 */
DBusTimeout *
_dbus_pending_call_get_timeout_unlocked (DBusPendingCall  *pending)
{
  _dbus_assert (pending != NULL);

  return pending->timeout;
}

/**
 * Gets the reply's serial number
 *
 * @param pending the pending_call
 * @returns a serial number for the reply or 0 
 */
dbus_uint32_t 
_dbus_pending_call_get_reply_serial_unlocked (DBusPendingCall  *pending)
{
  _dbus_assert (pending != NULL);

  return pending->reply_serial;
}

/**
 * Sets the reply's serial number
 *
 * @param pending the pending_call
 * @param serial the serial number 
 */
void
_dbus_pending_call_set_reply_serial_unlocked  (DBusPendingCall *pending,
                                               dbus_uint32_t serial)
{
  _dbus_assert (pending != NULL);
  _dbus_assert (pending->reply_serial == 0);

  pending->reply_serial = serial;
}

/**
 * Gets the connection associated with this pending call.
 *
 * @param pending the pending_call
 * @returns the connection associated with the pending call
 */
DBusConnection *
_dbus_pending_call_get_connection_and_lock (DBusPendingCall *pending)
{
  _dbus_assert (pending != NULL);
 
  CONNECTION_LOCK (pending->connection);
  return pending->connection;
}

/**
 * Gets the connection associated with this pending call.
 *
 * @param pending the pending_call
 * @returns the connection associated with the pending call
 */
DBusConnection *
_dbus_pending_call_get_connection_unlocked (DBusPendingCall *pending)
{
  _dbus_assert (pending != NULL);
 
  return pending->connection;
}

/**
 * Sets the reply message associated with the pending call to a timeout error
 *
 * @param pending the pending_call
 * @param message the message we are sending the error reply to 
 * @param serial serial number for the reply
 * @return #FALSE on OOM
 */
dbus_bool_t
_dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending,
                                               DBusMessage     *message,
                                               dbus_uint32_t    serial)
{ 
  DBusList *reply_link;
  DBusMessage *reply;

  reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY,
                                  "Did not receive a reply. Possible causes include: "
                                  "the remote application did not send a reply, "
                                  "the message bus security policy blocked the reply, "
                                  "the reply timeout expired, or "
                                  "the network connection was broken.");
  if (reply == NULL)
    return FALSE;

  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;
    }

  pending->timeout_link = reply_link;

  _dbus_pending_call_set_reply_serial_unlocked (pending, serial);
  
  return TRUE;
}

/**
 * Increments the reference count on a pending call,
 * while the lock on its connection is already held.
 *
 * @param pending the pending call object
 * @returns the pending call object
 */
DBusPendingCall *
_dbus_pending_call_ref_unlocked (DBusPendingCall *pending)
{
  dbus_int32_t old_refcount;

  old_refcount = _dbus_atomic_inc (&pending->refcount);
  _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount + 1,
      "ref_unlocked");

  return pending;
}


static void
_dbus_pending_call_last_unref (DBusPendingCall *pending)
{
  DBusConnection *connection;
  
  /* If we get here, we should be already detached
   * from the connection, or never attached.
   */
  _dbus_assert (!pending->timeout_added);  

  connection = pending->connection;

  /* this assumes we aren't holding connection lock... */
  _dbus_data_slot_list_free (&pending->slot_list);

  if (pending->timeout != NULL)
    _dbus_timeout_unref (pending->timeout);
      
  if (pending->timeout_link)
    {
      dbus_message_unref ((DBusMessage *)pending->timeout_link->data);
      _dbus_list_free_link (pending->timeout_link);
      pending->timeout_link = NULL;
    }

  if (pending->reply)
    {
      dbus_message_unref (pending->reply);
      pending->reply = NULL;
    }
      
  dbus_free (pending);

  dbus_pending_call_free_data_slot (&notify_user_data_slot);

  /* connection lock should not be held. */
  /* Free the connection last to avoid a weird state while
   * calling out to application code where the pending exists
   * but not the connection.
   */
  dbus_connection_unref (connection);
}

/**
 * Decrements the reference count on a pending call,
 * freeing it if the count reaches 0. Assumes
 * connection lock is already held.
 *
 * @param pending the pending call object
 */
void
_dbus_pending_call_unref_and_unlock (DBusPendingCall *pending)
{
  dbus_int32_t old_refcount;

  old_refcount = _dbus_atomic_dec (&pending->refcount);
  _dbus_assert (old_refcount > 0);
  _dbus_pending_call_trace_ref (pending, old_refcount,
      old_refcount - 1, "unref_and_unlock");

  CONNECTION_UNLOCK (pending->connection);

  if (old_refcount == 1)
    _dbus_pending_call_last_unref (pending);
}

/**
 * Checks whether the pending call has received a reply
 * yet, or not. Assumes connection lock is held.
 *
 * @param pending the pending call
 * @returns #TRUE if a reply has been received
 */
dbus_bool_t
_dbus_pending_call_get_completed_unlocked (DBusPendingCall    *pending)
{
  return pending->completed;
}

static DBusDataSlotAllocator slot_allocator;
_DBUS_DEFINE_GLOBAL_LOCK (pending_call_slots);

/**
 * Stores a pointer on a #DBusPendingCall, along
 * with an optional function to be used for freeing
 * the data when the data is set again, or when
 * the pending call is finalized. The slot number
 * must have been allocated with dbus_pending_call_allocate_data_slot().
 *
 * @param pending the pending_call
 * @param slot the slot number
 * @param data the data to store
 * @param free_data_func finalizer function for the data
 * @returns #TRUE if there was enough memory to store the data
 */
dbus_bool_t
_dbus_pending_call_set_data_unlocked (DBusPendingCall  *pending,
                                     dbus_int32_t      slot,
                                     void             *data,
                                     DBusFreeFunction  free_data_func)
{
  DBusFreeFunction old_free_func;
  void *old_data;
  dbus_bool_t retval;

  retval = _dbus_data_slot_list_set (&slot_allocator,
                                     &pending->slot_list,
                                     slot, data, free_data_func,
                                     &old_free_func, &old_data);

  /* Drop locks to call out to app code */
  CONNECTION_UNLOCK (pending->connection);
  
  if (retval)
    {
      if (old_free_func)
        (* old_free_func) (old_data);
    }

  CONNECTION_LOCK (pending->connection);
  
  return retval;
}

/** @} */

/**
 * @defgroup DBusPendingCall DBusPendingCall
 * @ingroup  DBus
 * @brief Pending reply to a method call message
 *
 * A DBusPendingCall is an object representing an
 * expected reply. A #DBusPendingCall can be created
 * when you send a message that should have a reply.
 *
 * @{
 */

/**
 * @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.
 */

/**
 * Increments the reference count on a pending call.
 *
 * @param pending the pending call object
 * @returns the pending call object
 */
DBusPendingCall *
dbus_pending_call_ref (DBusPendingCall *pending)
{
  dbus_int32_t old_refcount;

  _dbus_return_val_if_fail (pending != NULL, NULL);

  old_refcount = _dbus_atomic_inc (&pending->refcount);
  _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount + 1,
      "ref");

  return pending;
}

/**
 * Decrements the reference count on a pending call,
 * freeing it if the count reaches 0.
 *
 * @param pending the pending call object
 */
void
dbus_pending_call_unref (DBusPendingCall *pending)
{
  dbus_int32_t old_refcount;

  _dbus_return_if_fail (pending != NULL);

  old_refcount = _dbus_atomic_dec (&pending->refcount);
  _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount - 1,
      "unref");

  if (old_refcount == 1)
    _dbus_pending_call_last_unref(pending);
}

/**
 * Sets a notification function to be called when the reply is
 * received or the pending call times out.
 *
 * @param pending the pending call
 * @param function notifier function
 * @param user_data data to pass to notifier function
 * @param free_user_data function to free the user data
 * @returns #FALSE if not enough memory
 */
dbus_bool_t
dbus_pending_call_set_notify (DBusPendingCall              *pending,
                              DBusPendingCallNotifyFunction function,
                              void                         *user_data,
                              DBusFreeFunction              free_user_data)
{
  dbus_bool_t ret = FALSE;

  _dbus_return_val_if_fail (pending != NULL, FALSE);

  CONNECTION_LOCK (pending->connection);
  
  /* could invoke application code! */
  if (!_dbus_pending_call_set_data_unlocked (pending, notify_user_data_slot,
                                             user_data, free_user_data))
    goto out;
  
  pending->function = function;
  ret = TRUE;

out:
  CONNECTION_UNLOCK (pending->connection);
  
  return ret;
}

/**
 * Cancels the pending call, such that any reply or error received
 * will just be ignored.  Drops the dbus library's internal reference
 * to the #DBusPendingCall so will free the call if nobody else is
 * holding a reference. However you usually get a reference from
 * dbus_connection_send_with_reply() so probably your app owns a ref
 * also.
 *
 * Note that canceling a pending call will <em>not</em> simulate a
 * timed-out call; if a call times out, then a timeout error reply is
 * received. If you cancel the call, no reply is received unless the
 * the reply was already received before you canceled.
 * 
 * @param pending the pending call
 */
void
dbus_pending_call_cancel (DBusPendingCall *pending)
{
  _dbus_return_if_fail (pending != NULL);

  _dbus_connection_remove_pending_call (pending->connection,
                                        pending);
}

/**
 * Checks whether the pending call has received a reply
 * yet, or not.
 *
 * @param pending the pending call
 * @returns #TRUE if a reply has been received
 */
dbus_bool_t
dbus_pending_call_get_completed (DBusPendingCall *pending)
{
  dbus_bool_t completed;
  
  _dbus_return_val_if_fail (pending != NULL, FALSE);

  CONNECTION_LOCK (pending->connection);
  completed = pending->completed;
  CONNECTION_UNLOCK (pending->connection);

  return completed;
}

/**
 * Gets the reply, or returns #NULL if none has been received
 * yet. Ownership of the reply message passes to the caller. This
 * function can only be called once per pending call, since the reply
 * message is tranferred to the caller.
 * 
 * @param pending the pending call
 * @returns the reply message or #NULL.
 */
DBusMessage*
dbus_pending_call_steal_reply (DBusPendingCall *pending)
{
  DBusMessage *message;
  
  _dbus_return_val_if_fail (pending != NULL, NULL);
  _dbus_return_val_if_fail (pending->completed, NULL);
  _dbus_return_val_if_fail (pending->reply != NULL, NULL);

  CONNECTION_LOCK (pending->connection);
  
  message = pending->reply;
  pending->reply = NULL;

  CONNECTION_UNLOCK (pending->connection);

  _dbus_message_trace_ref (message, -1, -1, "dbus_pending_call_steal_reply");
  return message;
}

/**
 * Block until the pending call is completed.  The blocking is as with
 * dbus_connection_send_with_reply_and_block(); it does not enter the
 * main loop or process other messages, it simply waits for the reply
 * in question.
 *
 * If the pending call is already completed, this function returns
 * immediately.
 *
 * @todo when you start blocking, the timeout is reset, but it should
 * really only use time remaining since the pending call was created.
 * This requires storing timestamps instead of intervals in the timeout
 *
 * @param pending the pending call
 */
void
dbus_pending_call_block (DBusPendingCall *pending)
{
  _dbus_return_if_fail (pending != NULL);

  _dbus_connection_block_pending_call (pending);
}

/**
 * Allocates an integer ID to be used for storing application-specific
 * data on any DBusPendingCall. The allocated ID may then be used
 * with dbus_pending_call_set_data() and dbus_pending_call_get_data().
 * The passed-in slot must be initialized to -1, and is filled in
 * with the slot ID. If the passed-in slot is not -1, it's assumed
 * to be already allocated, and its refcount is incremented.
 * 
 * The allocated slot is global, i.e. all DBusPendingCall objects will
 * have a slot with the given integer ID reserved.
 *
 * @param slot_p address of a global variable storing the slot
 * @returns #FALSE on failure (no memory)
 */
dbus_bool_t
dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p)
{
  _dbus_return_val_if_fail (slot_p != NULL, FALSE);

  return _dbus_data_slot_allocator_alloc (&slot_allocator,
                                          &_DBUS_LOCK_NAME (pending_call_slots),
                                          slot_p);
}

/**
 * Deallocates a global ID for #DBusPendingCall data slots.
 * dbus_pending_call_get_data() and dbus_pending_call_set_data() may
 * no longer be used with this slot.  Existing data stored on existing
 * DBusPendingCall objects will be freed when the #DBusPendingCall is
 * finalized, but may not be retrieved (and may only be replaced if
 * someone else reallocates the slot).  When the refcount on the
 * passed-in slot reaches 0, it is set to -1.
 *
 * @param slot_p address storing the slot to deallocate
 */
void
dbus_pending_call_free_data_slot (dbus_int32_t *slot_p)
{
  _dbus_return_if_fail (slot_p != NULL);
  _dbus_return_if_fail (*slot_p >= 0);

  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
}

/**
 * Stores a pointer on a #DBusPendingCall, along
 * with an optional function to be used for freeing
 * the data when the data is set again, or when
 * the pending call is finalized. The slot number
 * must have been allocated with dbus_pending_call_allocate_data_slot().
 *
 * @param pending the pending_call
 * @param slot the slot number
 * @param data the data to store
 * @param free_data_func finalizer function for the data
 * @returns #TRUE if there was enough memory to store the data
 */
dbus_bool_t
dbus_pending_call_set_data (DBusPendingCall  *pending,
                            dbus_int32_t      slot,
                            void             *data,
                            DBusFreeFunction  free_data_func)
{
  dbus_bool_t retval;
  
  _dbus_return_val_if_fail (pending != NULL, FALSE);
  _dbus_return_val_if_fail (slot >= 0, FALSE);

  
  CONNECTION_LOCK (pending->connection);
  retval = _dbus_pending_call_set_data_unlocked (pending, slot, data, free_data_func);
  CONNECTION_UNLOCK (pending->connection);
  return retval;
}

/**
 * Retrieves data previously set with dbus_pending_call_set_data().
 * The slot must still be allocated (must not have been freed).
 *
 * @param pending the pending_call
 * @param slot the slot to get data from
 * @returns the data, or #NULL if not found
 */
void*
dbus_pending_call_get_data (DBusPendingCall   *pending,
                            dbus_int32_t       slot)
{
  void *res;

  _dbus_return_val_if_fail (pending != NULL, NULL);

  CONNECTION_LOCK (pending->connection);
  res = _dbus_data_slot_list_get (&slot_allocator,
                                  &pending->slot_list,
                                  slot);
  CONNECTION_UNLOCK (pending->connection);

  return res;
}

/** @} */
