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