Add and use _dbus_message_trace_ref
[platform/upstream/dbus.git] / dbus / dbus-pending-call.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-pending-call.c Object representing a call in progress.
3  *
4  * Copyright (C) 2002, 2003 Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include <config.h>
25 #include "dbus-internals.h"
26 #include "dbus-connection-internal.h"
27 #include "dbus-message-internal.h"
28 #include "dbus-pending-call-internal.h"
29 #include "dbus-pending-call.h"
30 #include "dbus-list.h"
31 #include "dbus-threads.h"
32 #include "dbus-test.h"
33
34 /**
35  * @defgroup DBusPendingCallInternals DBusPendingCall implementation details
36  * @ingroup DBusInternals
37  * @brief DBusPendingCall private implementation details.
38  *
39  * The guts of DBusPendingCall and its methods.
40  *
41  * @{
42  */
43
44 /**
45  * @brief Internals of DBusPendingCall
46  *
47  * Opaque object representing a reply message that we're waiting for.
48  */
49
50 /**
51  * shorter and more visible way to write _dbus_connection_lock()
52  */
53 #define CONNECTION_LOCK(connection)   _dbus_connection_lock(connection)
54 /**
55  * shorter and more visible way to write _dbus_connection_unlock()
56  */
57 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock(connection)
58
59 /**
60  * Implementation details of #DBusPendingCall - all fields are private.
61  */
62 struct DBusPendingCall
63 {
64   DBusAtomic refcount;                            /**< reference count */
65
66   DBusDataSlotList slot_list;                     /**< Data stored by allocated integer ID */
67   
68   DBusPendingCallNotifyFunction function;         /**< Notifier when reply arrives. */
69
70   DBusConnection *connection;                     /**< Connections we're associated with */
71   DBusMessage *reply;                             /**< Reply (after we've received it) */
72   DBusTimeout *timeout;                           /**< Timeout */
73
74   DBusList *timeout_link;                         /**< Preallocated timeout response */
75   
76   dbus_uint32_t reply_serial;                     /**< Expected serial of reply */
77
78   unsigned int completed : 1;                     /**< TRUE if completed */
79   unsigned int timeout_added : 1;                 /**< Have added the timeout */
80 };
81
82 static dbus_int32_t notify_user_data_slot = -1;
83
84 /**
85  * Creates a new pending reply object.
86  *
87  * @param connection connection where reply will arrive
88  * @param timeout_milliseconds length of timeout, -1 (or
89  *  #DBUS_TIMEOUT_USE_DEFAULT) for default,
90  *  #DBUS_TIMEOUT_INFINITE for no timeout
91  * @param timeout_handler timeout handler, takes pending call as data
92  * @returns a new #DBusPendingCall or #NULL if no memory.
93  */
94 DBusPendingCall*
95 _dbus_pending_call_new_unlocked (DBusConnection    *connection,
96                                  int                timeout_milliseconds,
97                                  DBusTimeoutHandler timeout_handler)
98 {
99   DBusPendingCall *pending;
100   DBusTimeout *timeout;
101
102   _dbus_assert (timeout_milliseconds >= 0 || timeout_milliseconds == -1);
103  
104   if (timeout_milliseconds == -1)
105     timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;
106
107   if (!dbus_pending_call_allocate_data_slot (&notify_user_data_slot))
108     return NULL;
109   
110   pending = dbus_new0 (DBusPendingCall, 1);
111   
112   if (pending == NULL)
113     {
114       dbus_pending_call_free_data_slot (&notify_user_data_slot);
115       return NULL;
116     }
117
118   if (timeout_milliseconds != DBUS_TIMEOUT_INFINITE)
119     {
120       timeout = _dbus_timeout_new (timeout_milliseconds,
121                                    timeout_handler,
122                                    pending, NULL);  
123
124       if (timeout == NULL)
125         {
126           dbus_pending_call_free_data_slot (&notify_user_data_slot);
127           dbus_free (pending);
128           return NULL;
129         }
130
131       pending->timeout = timeout;
132     }
133   else
134     {
135       pending->timeout = NULL;
136     }
137
138   _dbus_atomic_inc (&pending->refcount);
139   pending->connection = connection;
140   _dbus_connection_ref_unlocked (pending->connection);
141
142   _dbus_data_slot_list_init (&pending->slot_list);
143   
144   return pending;
145 }
146
147 /**
148  * Sets the reply of a pending call with the given message,
149  * or if the message is #NULL, by timing out the pending call.
150  * 
151  * @param pending the pending call
152  * @param message the message to complete the call with, or #NULL
153  *  to time out the call
154  */
155 void
156 _dbus_pending_call_set_reply_unlocked (DBusPendingCall *pending,
157                                        DBusMessage     *message)
158 {
159   if (message == NULL)
160     {
161       message = pending->timeout_link->data;
162       _dbus_list_clear (&pending->timeout_link);
163     }
164   else
165     dbus_message_ref (message);
166
167   _dbus_verbose ("  handing message %p (%s) to pending call serial %u\n",
168                  message,
169                  dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ?
170                  "method return" :
171                  dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ?
172                  "error" : "other type",
173                  pending->reply_serial);
174   
175   _dbus_assert (pending->reply == NULL);
176   _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message));
177   pending->reply = message;
178 }
179
180 /**
181  * Calls notifier function for the pending call
182  * and sets the call to completed.
183  *
184  * @param pending the pending call
185  * 
186  */
187 void
188 _dbus_pending_call_complete (DBusPendingCall *pending)
189 {
190   _dbus_assert (!pending->completed);
191   
192   pending->completed = TRUE;
193
194   if (pending->function)
195     {
196       void *user_data;
197       user_data = dbus_pending_call_get_data (pending,
198                                               notify_user_data_slot);
199       
200       (* pending->function) (pending, user_data);
201     }
202 }
203
204 /**
205  * If the pending call hasn't been timed out, add its timeout
206  * error reply to the connection's incoming message queue.
207  *
208  * @param pending the pending call
209  * @param connection the connection the call was sent to
210  */
211 void
212 _dbus_pending_call_queue_timeout_error_unlocked (DBusPendingCall *pending, 
213                                                  DBusConnection  *connection)
214 {
215   _dbus_assert (connection == pending->connection);
216   
217   if (pending->timeout_link)
218     {
219       _dbus_connection_queue_synthesized_message_link (connection,
220                                                        pending->timeout_link);
221       pending->timeout_link = NULL;
222     }
223 }
224
225 /**
226  * Checks to see if a timeout has been added
227  *
228  * @param pending the pending_call
229  * @returns #TRUE if there is a timeout or #FALSE if not
230  */
231 dbus_bool_t 
232 _dbus_pending_call_is_timeout_added_unlocked (DBusPendingCall  *pending)
233 {
234   _dbus_assert (pending != NULL);
235
236   return pending->timeout_added;
237 }
238
239
240 /**
241  * Sets wether the timeout has been added
242  *
243  * @param pending the pending_call
244  * @param is_added whether or not a timeout is added
245  */
246 void
247 _dbus_pending_call_set_timeout_added_unlocked (DBusPendingCall  *pending,
248                                                dbus_bool_t       is_added)
249 {
250   _dbus_assert (pending != NULL);
251
252   pending->timeout_added = is_added;
253 }
254
255
256 /**
257  * Retrives the timeout
258  *
259  * @param pending the pending_call
260  * @returns a timeout object or NULL if call has no timeout
261  */
262 DBusTimeout *
263 _dbus_pending_call_get_timeout_unlocked (DBusPendingCall  *pending)
264 {
265   _dbus_assert (pending != NULL);
266
267   return pending->timeout;
268 }
269
270 /**
271  * Gets the reply's serial number
272  *
273  * @param pending the pending_call
274  * @returns a serial number for the reply or 0 
275  */
276 dbus_uint32_t 
277 _dbus_pending_call_get_reply_serial_unlocked (DBusPendingCall  *pending)
278 {
279   _dbus_assert (pending != NULL);
280
281   return pending->reply_serial;
282 }
283
284 /**
285  * Sets the reply's serial number
286  *
287  * @param pending the pending_call
288  * @param serial the serial number 
289  */
290 void
291 _dbus_pending_call_set_reply_serial_unlocked  (DBusPendingCall *pending,
292                                                dbus_uint32_t serial)
293 {
294   _dbus_assert (pending != NULL);
295   _dbus_assert (pending->reply_serial == 0);
296
297   pending->reply_serial = serial;
298 }
299
300 /**
301  * Gets the connection associated with this pending call.
302  *
303  * @param pending the pending_call
304  * @returns the connection associated with the pending call
305  */
306 DBusConnection *
307 _dbus_pending_call_get_connection_and_lock (DBusPendingCall *pending)
308 {
309   _dbus_assert (pending != NULL);
310  
311   CONNECTION_LOCK (pending->connection);
312   return pending->connection;
313 }
314
315 /**
316  * Gets the connection associated with this pending call.
317  *
318  * @param pending the pending_call
319  * @returns the connection associated with the pending call
320  */
321 DBusConnection *
322 _dbus_pending_call_get_connection_unlocked (DBusPendingCall *pending)
323 {
324   _dbus_assert (pending != NULL);
325  
326   return pending->connection;
327 }
328
329 /**
330  * Sets the reply message associated with the pending call to a timeout error
331  *
332  * @param pending the pending_call
333  * @param message the message we are sending the error reply to 
334  * @param serial serial number for the reply
335  * @return #FALSE on OOM
336  */
337 dbus_bool_t
338 _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending,
339                                                DBusMessage     *message,
340                                                dbus_uint32_t    serial)
341
342   DBusList *reply_link;
343   DBusMessage *reply;
344
345   reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY,
346                                   "Did not receive a reply. Possible causes include: "
347                                   "the remote application did not send a reply, "
348                                   "the message bus security policy blocked the reply, "
349                                   "the reply timeout expired, or "
350                                   "the network connection was broken.");
351   if (reply == NULL)
352     return FALSE;
353
354   reply_link = _dbus_list_alloc_link (reply);
355   if (reply_link == NULL)
356     {
357       /* it's OK to unref this, nothing that could have attached a callback
358        * has ever seen it */
359       dbus_message_unref (reply);
360       return FALSE;
361     }
362
363   pending->timeout_link = reply_link;
364
365   _dbus_pending_call_set_reply_serial_unlocked (pending, serial);
366   
367   return TRUE;
368 }
369
370 /**
371  * Increments the reference count on a pending call,
372  * while the lock on its connection is already held.
373  *
374  * @param pending the pending call object
375  * @returns the pending call object
376  */
377 DBusPendingCall *
378 _dbus_pending_call_ref_unlocked (DBusPendingCall *pending)
379 {
380   _dbus_atomic_inc (&pending->refcount);
381
382   return pending;
383 }
384
385
386 static void
387 _dbus_pending_call_last_unref (DBusPendingCall *pending)
388 {
389   DBusConnection *connection;
390   
391   /* If we get here, we should be already detached
392    * from the connection, or never attached.
393    */
394   _dbus_assert (!pending->timeout_added);  
395
396   connection = pending->connection;
397
398   /* this assumes we aren't holding connection lock... */
399   _dbus_data_slot_list_free (&pending->slot_list);
400
401   if (pending->timeout != NULL)
402     _dbus_timeout_unref (pending->timeout);
403       
404   if (pending->timeout_link)
405     {
406       dbus_message_unref ((DBusMessage *)pending->timeout_link->data);
407       _dbus_list_free_link (pending->timeout_link);
408       pending->timeout_link = NULL;
409     }
410
411   if (pending->reply)
412     {
413       dbus_message_unref (pending->reply);
414       pending->reply = NULL;
415     }
416       
417   dbus_free (pending);
418
419   dbus_pending_call_free_data_slot (&notify_user_data_slot);
420
421   /* connection lock should not be held. */
422   /* Free the connection last to avoid a weird state while
423    * calling out to application code where the pending exists
424    * but not the connection.
425    */
426   dbus_connection_unref (connection);
427 }
428
429 /**
430  * Decrements the reference count on a pending call,
431  * freeing it if the count reaches 0. Assumes
432  * connection lock is already held.
433  *
434  * @param pending the pending call object
435  */
436 void
437 _dbus_pending_call_unref_and_unlock (DBusPendingCall *pending)
438 {
439   dbus_int32_t old_refcount;
440
441   old_refcount = _dbus_atomic_dec (&pending->refcount);
442   _dbus_assert (old_refcount > 0);
443
444   CONNECTION_UNLOCK (pending->connection);
445
446   if (old_refcount == 1)
447     _dbus_pending_call_last_unref (pending);
448 }
449
450 /**
451  * Checks whether the pending call has received a reply
452  * yet, or not. Assumes connection lock is held.
453  *
454  * @param pending the pending call
455  * @returns #TRUE if a reply has been received
456  */
457 dbus_bool_t
458 _dbus_pending_call_get_completed_unlocked (DBusPendingCall    *pending)
459 {
460   return pending->completed;
461 }
462
463 static DBusDataSlotAllocator slot_allocator;
464 _DBUS_DEFINE_GLOBAL_LOCK (pending_call_slots);
465
466 /**
467  * Stores a pointer on a #DBusPendingCall, along
468  * with an optional function to be used for freeing
469  * the data when the data is set again, or when
470  * the pending call is finalized. The slot number
471  * must have been allocated with dbus_pending_call_allocate_data_slot().
472  *
473  * @param pending the pending_call
474  * @param slot the slot number
475  * @param data the data to store
476  * @param free_data_func finalizer function for the data
477  * @returns #TRUE if there was enough memory to store the data
478  */
479 dbus_bool_t
480 _dbus_pending_call_set_data_unlocked (DBusPendingCall  *pending,
481                                      dbus_int32_t      slot,
482                                      void             *data,
483                                      DBusFreeFunction  free_data_func)
484 {
485   DBusFreeFunction old_free_func;
486   void *old_data;
487   dbus_bool_t retval;
488
489   retval = _dbus_data_slot_list_set (&slot_allocator,
490                                      &pending->slot_list,
491                                      slot, data, free_data_func,
492                                      &old_free_func, &old_data);
493
494   /* Drop locks to call out to app code */
495   CONNECTION_UNLOCK (pending->connection);
496   
497   if (retval)
498     {
499       if (old_free_func)
500         (* old_free_func) (old_data);
501     }
502
503   CONNECTION_LOCK (pending->connection);
504   
505   return retval;
506 }
507
508 /** @} */
509
510 /**
511  * @defgroup DBusPendingCall DBusPendingCall
512  * @ingroup  DBus
513  * @brief Pending reply to a method call message
514  *
515  * A DBusPendingCall is an object representing an
516  * expected reply. A #DBusPendingCall can be created
517  * when you send a message that should have a reply.
518  *
519  * @{
520  */
521
522 /**
523  * @def DBUS_TIMEOUT_INFINITE
524  *
525  * An integer constant representing an infinite timeout. This has the
526  * numeric value 0x7fffffff (the largest 32-bit signed integer).
527  *
528  * For source compatibility with D-Bus versions earlier than 1.4.12, use
529  * 0x7fffffff, or INT32_MAX (assuming your platform has it).
530  */
531
532 /**
533  * @def DBUS_TIMEOUT_USE_DEFAULT
534  *
535  * An integer constant representing a request to use the default timeout.
536  * This has numeric value -1.
537  *
538  * For source compatibility with D-Bus versions earlier than 1.4.12, use a
539  * literal -1.
540  */
541
542 /**
543  * @typedef DBusPendingCall
544  *
545  * Opaque data type representing a message pending.
546  */
547
548 /**
549  * Increments the reference count on a pending call.
550  *
551  * @param pending the pending call object
552  * @returns the pending call object
553  */
554 DBusPendingCall *
555 dbus_pending_call_ref (DBusPendingCall *pending)
556 {
557   _dbus_return_val_if_fail (pending != NULL, NULL);
558
559   _dbus_atomic_inc (&pending->refcount);
560
561   return pending;
562 }
563
564 /**
565  * Decrements the reference count on a pending call,
566  * freeing it if the count reaches 0.
567  *
568  * @param pending the pending call object
569  */
570 void
571 dbus_pending_call_unref (DBusPendingCall *pending)
572 {
573   dbus_bool_t last_unref;
574
575   _dbus_return_if_fail (pending != NULL);
576
577   last_unref = (_dbus_atomic_dec (&pending->refcount) == 1);
578
579   if (last_unref)
580     _dbus_pending_call_last_unref(pending);
581 }
582
583 /**
584  * Sets a notification function to be called when the reply is
585  * received or the pending call times out.
586  *
587  * @param pending the pending call
588  * @param function notifier function
589  * @param user_data data to pass to notifier function
590  * @param free_user_data function to free the user data
591  * @returns #FALSE if not enough memory
592  */
593 dbus_bool_t
594 dbus_pending_call_set_notify (DBusPendingCall              *pending,
595                               DBusPendingCallNotifyFunction function,
596                               void                         *user_data,
597                               DBusFreeFunction              free_user_data)
598 {
599   _dbus_return_val_if_fail (pending != NULL, FALSE);
600
601   CONNECTION_LOCK (pending->connection);
602   
603   /* could invoke application code! */
604   if (!_dbus_pending_call_set_data_unlocked (pending, notify_user_data_slot,
605                                              user_data, free_user_data))
606     return FALSE;
607   
608   pending->function = function;
609
610   CONNECTION_UNLOCK (pending->connection);
611   
612   return TRUE;
613 }
614
615 /**
616  * Cancels the pending call, such that any reply or error received
617  * will just be ignored.  Drops the dbus library's internal reference
618  * to the #DBusPendingCall so will free the call if nobody else is
619  * holding a reference. However you usually get a reference from
620  * dbus_connection_send_with_reply() so probably your app owns a ref
621  * also.
622  *
623  * Note that canceling a pending call will <em>not</em> simulate a
624  * timed-out call; if a call times out, then a timeout error reply is
625  * received. If you cancel the call, no reply is received unless the
626  * the reply was already received before you canceled.
627  * 
628  * @param pending the pending call
629  */
630 void
631 dbus_pending_call_cancel (DBusPendingCall *pending)
632 {
633   _dbus_return_if_fail (pending != NULL);
634
635   _dbus_connection_remove_pending_call (pending->connection,
636                                         pending);
637 }
638
639 /**
640  * Checks whether the pending call has received a reply
641  * yet, or not.
642  *
643  * @param pending the pending call
644  * @returns #TRUE if a reply has been received
645  */
646 dbus_bool_t
647 dbus_pending_call_get_completed (DBusPendingCall *pending)
648 {
649   dbus_bool_t completed;
650   
651   _dbus_return_val_if_fail (pending != NULL, FALSE);
652
653   CONNECTION_LOCK (pending->connection);
654   completed = pending->completed;
655   CONNECTION_UNLOCK (pending->connection);
656
657   return completed;
658 }
659
660 /**
661  * Gets the reply, or returns #NULL if none has been received
662  * yet. Ownership of the reply message passes to the caller. This
663  * function can only be called once per pending call, since the reply
664  * message is tranferred to the caller.
665  * 
666  * @param pending the pending call
667  * @returns the reply message or #NULL.
668  */
669 DBusMessage*
670 dbus_pending_call_steal_reply (DBusPendingCall *pending)
671 {
672   DBusMessage *message;
673   
674   _dbus_return_val_if_fail (pending != NULL, NULL);
675   _dbus_return_val_if_fail (pending->completed, NULL);
676   _dbus_return_val_if_fail (pending->reply != NULL, NULL);
677
678   CONNECTION_LOCK (pending->connection);
679   
680   message = pending->reply;
681   pending->reply = NULL;
682
683   CONNECTION_UNLOCK (pending->connection);
684
685   _dbus_message_trace_ref (message, -1, -1, "dbus_pending_call_steal_reply");
686   return message;
687 }
688
689 /**
690  * Block until the pending call is completed.  The blocking is as with
691  * dbus_connection_send_with_reply_and_block(); it does not enter the
692  * main loop or process other messages, it simply waits for the reply
693  * in question.
694  *
695  * If the pending call is already completed, this function returns
696  * immediately.
697  *
698  * @todo when you start blocking, the timeout is reset, but it should
699  * really only use time remaining since the pending call was created.
700  * This requires storing timestamps instead of intervals in the timeout
701  *
702  * @param pending the pending call
703  */
704 void
705 dbus_pending_call_block (DBusPendingCall *pending)
706 {
707   _dbus_return_if_fail (pending != NULL);
708
709   _dbus_connection_block_pending_call (pending);
710 }
711
712 /**
713  * Allocates an integer ID to be used for storing application-specific
714  * data on any DBusPendingCall. The allocated ID may then be used
715  * with dbus_pending_call_set_data() and dbus_pending_call_get_data().
716  * The passed-in slot must be initialized to -1, and is filled in
717  * with the slot ID. If the passed-in slot is not -1, it's assumed
718  * to be already allocated, and its refcount is incremented.
719  * 
720  * The allocated slot is global, i.e. all DBusPendingCall objects will
721  * have a slot with the given integer ID reserved.
722  *
723  * @param slot_p address of a global variable storing the slot
724  * @returns #FALSE on failure (no memory)
725  */
726 dbus_bool_t
727 dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p)
728 {
729   _dbus_return_val_if_fail (slot_p != NULL, FALSE);
730
731   return _dbus_data_slot_allocator_alloc (&slot_allocator,
732                                           &_DBUS_LOCK_NAME (pending_call_slots),
733                                           slot_p);
734 }
735
736 /**
737  * Deallocates a global ID for #DBusPendingCall data slots.
738  * dbus_pending_call_get_data() and dbus_pending_call_set_data() may
739  * no longer be used with this slot.  Existing data stored on existing
740  * DBusPendingCall objects will be freed when the #DBusPendingCall is
741  * finalized, but may not be retrieved (and may only be replaced if
742  * someone else reallocates the slot).  When the refcount on the
743  * passed-in slot reaches 0, it is set to -1.
744  *
745  * @param slot_p address storing the slot to deallocate
746  */
747 void
748 dbus_pending_call_free_data_slot (dbus_int32_t *slot_p)
749 {
750   _dbus_return_if_fail (slot_p != NULL);
751   _dbus_return_if_fail (*slot_p >= 0);
752
753   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
754 }
755
756 /**
757  * Stores a pointer on a #DBusPendingCall, along
758  * with an optional function to be used for freeing
759  * the data when the data is set again, or when
760  * the pending call is finalized. The slot number
761  * must have been allocated with dbus_pending_call_allocate_data_slot().
762  *
763  * @param pending the pending_call
764  * @param slot the slot number
765  * @param data the data to store
766  * @param free_data_func finalizer function for the data
767  * @returns #TRUE if there was enough memory to store the data
768  */
769 dbus_bool_t
770 dbus_pending_call_set_data (DBusPendingCall  *pending,
771                             dbus_int32_t      slot,
772                             void             *data,
773                             DBusFreeFunction  free_data_func)
774 {
775   dbus_bool_t retval;
776   
777   _dbus_return_val_if_fail (pending != NULL, FALSE);
778   _dbus_return_val_if_fail (slot >= 0, FALSE);
779
780   
781   CONNECTION_LOCK (pending->connection);
782   retval = _dbus_pending_call_set_data_unlocked (pending, slot, data, free_data_func);
783   CONNECTION_UNLOCK (pending->connection);
784   return retval;
785 }
786
787 /**
788  * Retrieves data previously set with dbus_pending_call_set_data().
789  * The slot must still be allocated (must not have been freed).
790  *
791  * @param pending the pending_call
792  * @param slot the slot to get data from
793  * @returns the data, or #NULL if not found
794  */
795 void*
796 dbus_pending_call_get_data (DBusPendingCall   *pending,
797                             dbus_int32_t       slot)
798 {
799   void *res;
800
801   _dbus_return_val_if_fail (pending != NULL, NULL);
802
803   CONNECTION_LOCK (pending->connection);
804   res = _dbus_data_slot_list_get (&slot_allocator,
805                                   &pending->slot_list,
806                                   slot);
807   CONNECTION_UNLOCK (pending->connection);
808
809   return res;
810 }
811
812 /** @} */