Coverage report for dbus/dbus-pending-call.c.gcov
-: 0:Source:dbus-pending-call.c
-: 0:Graph:.libs/dbus-pending-call.gcno
-: 0:Data:.libs/dbus-pending-call.gcda
-: 0:Runs:11822
-: 0:Programs:5
-: 1:/* -*- mode: C; c-file-style: "gnu" -*- */
-: 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-: 21: *
-: 22: */
-: 23:
-: 24:#include "dbus-internals.h"
-: 25:#include "dbus-connection-internal.h"
-: 26:#include "dbus-pending-call.h"
-: 27:#include "dbus-list.h"
-: 28:#include "dbus-threads.h"
-: 29:#include "dbus-test.h"
-: 30:
-: 31:/**
-: 32: * @defgroup DBusPendingCallInternals DBusPendingCall implementation details
-: 33: * @ingroup DBusInternals
-: 34: * @brief DBusPendingCall private implementation details.
-: 35: *
-: 36: * The guts of DBusPendingCall and its methods.
-: 37: *
-: 38: * @{
-: 39: */
-: 40:
-: 41:static dbus_int32_t notify_user_data_slot = -1;
-: 42:
-: 43:/**
-: 44: * Creates a new pending reply object.
-: 45: *
-: 46: * @param connection connection where reply will arrive
-: 47: * @param timeout_milliseconds length of timeout, -1 for default
-: 48: * @param timeout_handler timeout handler, takes pending call as data
-: 49: * @returns a new #DBusPendingCall or #NULL if no memory.
-: 50: */
-: 51:DBusPendingCall*
-: 52:_dbus_pending_call_new (DBusConnection *connection,
-: 53: int timeout_milliseconds,
-: 54: DBusTimeoutHandler timeout_handler)
function _dbus_pending_call_new called 1346 returned 100% blocks executed 67%
1346: 55:{
-: 56: DBusPendingCall *pending;
-: 57: DBusTimeout *timeout;
-: 58:
1346: 59: _dbus_assert (timeout_milliseconds >= 0 || timeout_milliseconds == -1);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
call 4 returned 100%
-: 60:
1346: 61: if (timeout_milliseconds == -1)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
1346: 62: timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;
-: 63:
-: 64: /* it would probably seem logical to pass in _DBUS_INT_MAX for
-: 65: * infinite timeout, but then math in
-: 66: * _dbus_connection_block_for_reply would get all overflow-prone, so
-: 67: * smack that down.
-: 68: */
1346: 69: if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 70: timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6;
-: 71:
1346: 72: if (!dbus_pending_call_allocate_data_slot (¬ify_user_data_slot))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 73: return NULL;
-: 74:
1346: 75: pending = dbus_new0 (DBusPendingCall, 1);
call 0 returned 100%
-: 76:
1346: 77: if (pending == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 78: {
#####: 79: dbus_pending_call_free_data_slot (¬ify_user_data_slot);
call 0 never executed
#####: 80: return NULL;
-: 81: }
-: 82:
1346: 83: timeout = _dbus_timeout_new (timeout_milliseconds,
call 0 returned 100%
-: 84: timeout_handler,
-: 85: pending, NULL);
-: 86:
1346: 87: if (timeout == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 88: {
#####: 89: dbus_pending_call_free_data_slot (¬ify_user_data_slot);
call 0 never executed
#####: 90: dbus_free (pending);
call 0 never executed
#####: 91: return NULL;
-: 92: }
-: 93:
1346: 94: pending->refcount.value = 1;
1346: 95: pending->connection = connection;
1346: 96: pending->timeout = timeout;
-: 97:
1346: 98: _dbus_data_slot_list_init (&pending->slot_list);
call 0 returned 100%
-: 99:
1346: 100: return pending;
-: 101:}
-: 102:
-: 103:/**
-: 104: * Calls notifier function for the pending call
-: 105: * and sets the call to completed.
-: 106: *
-: 107: * @param pending the pending call
-: 108: *
-: 109: */
-: 110:void
-: 111:_dbus_pending_call_notify (DBusPendingCall *pending)
function _dbus_pending_call_notify called 1346 returned 100% blocks executed 60%
1346: 112:{
1346: 113: _dbus_assert (!pending->completed);
call 0 returned 100%
-: 114:
1346: 115: pending->completed = TRUE;
-: 116:
1346: 117: if (pending->function)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 118: {
-: 119: void *user_data;
#####: 120: user_data = dbus_pending_call_get_data (pending,
call 0 never executed
-: 121: notify_user_data_slot);
-: 122:
#####: 123: (* pending->function) (pending, user_data);
call 0 never executed
-: 124: }
1346: 125:}
-: 126:
-: 127:/** @} */
-: 128:
-: 129:/**
-: 130: * @defgroup DBusPendingCall DBusPendingCall
-: 131: * @ingroup DBus
-: 132: * @brief Pending reply to a method call message
-: 133: *
-: 134: * A DBusPendingCall is an object representing an
-: 135: * expected reply. A #DBusPendingCall can be created
-: 136: * when you send a message that should have a reply.
-: 137: *
-: 138: * @{
-: 139: */
-: 140:
-: 141:/**
-: 142: * @typedef DBusPendingCall
-: 143: *
-: 144: * Opaque data type representing a message pending.
-: 145: */
-: 146:
-: 147:/**
-: 148: * Increments the reference count on a pending call.
-: 149: *
-: 150: * @param pending the pending call object
-: 151: * @returns the pending call object
-: 152: */
-: 153:DBusPendingCall *
-: 154:dbus_pending_call_ref (DBusPendingCall *pending)
function dbus_pending_call_ref called 5384 returned 100% blocks executed 63%
5384: 155:{
5384: 156: _dbus_return_val_if_fail (pending != NULL, NULL);
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
call 3 never executed
call 4 never executed
-: 157:
5384: 158: _dbus_atomic_inc (&pending->refcount);
call 0 returned 100%
-: 159:
5384: 160: return pending;
-: 161:}
-: 162:
-: 163:/**
-: 164: * Decrements the reference count on a pending call,
-: 165: * freeing it if the count reaches 0.
-: 166: *
-: 167: * @param pending the pending call object
-: 168: */
-: 169:void
-: 170:dbus_pending_call_unref (DBusPendingCall *pending)
function dbus_pending_call_unref called 6730 returned 100% blocks executed 81%
6730: 171:{
-: 172: dbus_bool_t last_unref;
-: 173:
6730: 174: _dbus_return_if_fail (pending != NULL);
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
call 3 never executed
call 4 never executed
-: 175:
6730: 176: last_unref = (_dbus_atomic_dec (&pending->refcount) == 1);
call 0 returned 100%
-: 177:
6730: 178: if (last_unref)
branch 0 taken 20% (fallthrough)
branch 1 taken 80%
-: 179: {
-: 180: /* If we get here, we should be already detached
-: 181: * from the connection, or never attached.
-: 182: */
1346: 183: _dbus_assert (pending->connection == NULL);
call 0 returned 100%
1346: 184: _dbus_assert (!pending->timeout_added);
call 0 returned 100%
-: 185:
-: 186: /* this assumes we aren't holding connection lock... */
1346: 187: _dbus_data_slot_list_free (&pending->slot_list);
call 0 returned 100%
-: 188:
1346: 189: if (pending->timeout != NULL)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
1346: 190: _dbus_timeout_unref (pending->timeout);
call 0 returned 100%
-: 191:
1346: 192: if (pending->timeout_link)
branch 0 taken 91% (fallthrough)
branch 1 taken 9%
-: 193: {
1230: 194: dbus_message_unref ((DBusMessage *)pending->timeout_link->data);
call 0 returned 100%
1230: 195: _dbus_list_free_link (pending->timeout_link);
call 0 returned 100%
1230: 196: pending->timeout_link = NULL;
-: 197: }
-: 198:
1346: 199: if (pending->reply)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 200: {
#####: 201: dbus_message_unref (pending->reply);
call 0 never executed
#####: 202: pending->reply = NULL;
-: 203: }
-: 204:
1346: 205: dbus_free (pending);
call 0 returned 100%
-: 206:
1346: 207: dbus_pending_call_free_data_slot (¬ify_user_data_slot);
call 0 returned 100%
-: 208: }
-: 209:}
-: 210:
-: 211:/**
-: 212: * Sets a notification function to be called when the reply is
-: 213: * received or the pending call times out.
-: 214: *
-: 215: * @param pending the pending call
-: 216: * @param function notifier function
-: 217: * @param user_data data to pass to notifier function
-: 218: * @param free_user_data function to free the user data
-: 219: * @returns #FALSE if not enough memory
-: 220: */
-: 221:dbus_bool_t
-: 222:dbus_pending_call_set_notify (DBusPendingCall *pending,
-: 223: DBusPendingCallNotifyFunction function,
-: 224: void *user_data,
-: 225: DBusFreeFunction free_user_data)
function dbus_pending_call_set_notify called 0 returned 0% blocks executed 0%
#####: 226:{
#####: 227: _dbus_return_val_if_fail (pending != NULL, FALSE);
call 0 never executed
branch 1 never executed
branch 2 never executed
call 3 never executed
call 4 never executed
-: 228:
-: 229: /* could invoke application code! */
#####: 230: if (!dbus_pending_call_set_data (pending, notify_user_data_slot,
call 0 never executed
branch 1 never executed
branch 2 never executed
-: 231: user_data, free_user_data))
#####: 232: return FALSE;
-: 233:
#####: 234: pending->function = function;
-: 235:
#####: 236: return TRUE;
-: 237:}
-: 238:
-: 239:/**
-: 240: * Cancels the pending call, such that any reply or error received
-: 241: * will just be ignored. Drops the dbus library's internal reference
-: 242: * to the #DBusPendingCall so will free the call if nobody else is
-: 243: * holding a reference. However you usually get a reference
-: 244: * from dbus_connection_send() so probably your app owns a ref also.
-: 245: *
-: 246: * @param pending the pending call
-: 247: */
-: 248:void
-: 249:dbus_pending_call_cancel (DBusPendingCall *pending)
function dbus_pending_call_cancel called 0 returned 0% blocks executed 0%
#####: 250:{
#####: 251: if (pending->connection)
branch 0 never executed
branch 1 never executed
#####: 252: _dbus_connection_remove_pending_call (pending->connection,
call 0 never executed
-: 253: pending);
#####: 254:}
-: 255:
-: 256:/**
-: 257: * Checks whether the pending call has received a reply
-: 258: * yet, or not.
-: 259: *
-: 260: * @todo not thread safe? I guess it has to lock though it sucks
-: 261: *
-: 262: * @param pending the pending call
-: 263: * @returns #TRUE if a reply has been received */
-: 264:dbus_bool_t
-: 265:dbus_pending_call_get_completed (DBusPendingCall *pending)
function dbus_pending_call_get_completed called 2693 returned 100% blocks executed 100%
2693: 266:{
2693: 267: return pending->completed;
-: 268:}
-: 269:
-: 270:/**
-: 271: * Gets the reply, or returns #NULL if none has been received
-: 272: * yet. Ownership of the reply message passes to the caller. This
-: 273: * function can only be called once per pending call, since the reply
-: 274: * message is tranferred to the caller.
-: 275: *
-: 276: * @param pending the pending call
-: 277: * @returns the reply message or #NULL.
-: 278: */
-: 279:DBusMessage*
-: 280:dbus_pending_call_steal_reply (DBusPendingCall *pending)
function dbus_pending_call_steal_reply called 1346 returned 100% blocks executed 50%
1346: 281:{
-: 282: DBusMessage *message;
-: 283:
1346: 284: _dbus_return_val_if_fail (pending->completed, NULL);
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
call 3 never executed
call 4 never executed
1346: 285: _dbus_return_val_if_fail (pending->reply != NULL, NULL);
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
call 3 never executed
call 4 never executed
-: 286:
1346: 287: message = pending->reply;
1346: 288: pending->reply = NULL;
-: 289:
1346: 290: return message;
-: 291:}
-: 292:
-: 293:/**
-: 294: * Block until the pending call is completed. The blocking is as with
-: 295: * dbus_connection_send_with_reply_and_block(); it does not enter the
-: 296: * main loop or process other messages, it simply waits for the reply
-: 297: * in question.
-: 298: *
-: 299: * If the pending call is already completed, this function returns
-: 300: * immediately.
-: 301: *
-: 302: * @todo when you start blocking, the timeout is reset, but it should
-: 303: * really only use time remaining since the pending call was created.
-: 304: *
-: 305: * @param pending the pending call
-: 306: */
-: 307:void
-: 308:dbus_pending_call_block (DBusPendingCall *pending)
function dbus_pending_call_block called 1346 returned 100% blocks executed 100%
1346: 309:{
1346: 310: _dbus_connection_block_pending_call (pending);
call 0 returned 100%
1346: 311:}
-: 312:
-: 313:static DBusDataSlotAllocator slot_allocator;
-: 314:_DBUS_DEFINE_GLOBAL_LOCK (pending_call_slots);
-: 315:
-: 316:/**
-: 317: * Allocates an integer ID to be used for storing application-specific
-: 318: * data on any DBusPendingCall. The allocated ID may then be used
-: 319: * with dbus_pending_call_set_data() and dbus_pending_call_get_data().
-: 320: * The passed-in slot must be initialized to -1, and is filled in
-: 321: * with the slot ID. If the passed-in slot is not -1, it's assumed
-: 322: * to be already allocated, and its refcount is incremented.
-: 323: *
-: 324: * The allocated slot is global, i.e. all DBusPendingCall objects will
-: 325: * have a slot with the given integer ID reserved.
-: 326: *
-: 327: * @param slot_p address of a global variable storing the slot
-: 328: * @returns #FALSE on failure (no memory)
-: 329: */
-: 330:dbus_bool_t
-: 331:dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p)
function dbus_pending_call_allocate_data_slot called 1346 returned 100% blocks executed 100%
1346: 332:{
1346: 333: return _dbus_data_slot_allocator_alloc (&slot_allocator,
call 0 returned 100%
-: 334: _DBUS_LOCK_NAME (pending_call_slots),
-: 335: slot_p);
-: 336:}
-: 337:
-: 338:/**
-: 339: * Deallocates a global ID for #DBusPendingCall data slots.
-: 340: * dbus_pending_call_get_data() and dbus_pending_call_set_data() may
-: 341: * no longer be used with this slot. Existing data stored on existing
-: 342: * DBusPendingCall objects will be freed when the #DBusPendingCall is
-: 343: * finalized, but may not be retrieved (and may only be replaced if
-: 344: * someone else reallocates the slot). When the refcount on the
-: 345: * passed-in slot reaches 0, it is set to -1.
-: 346: *
-: 347: * @param slot_p address storing the slot to deallocate
-: 348: */
-: 349:void
-: 350:dbus_pending_call_free_data_slot (dbus_int32_t *slot_p)
function dbus_pending_call_free_data_slot called 1346 returned 100% blocks executed 67%
1346: 351:{
1346: 352: _dbus_return_if_fail (*slot_p >= 0);
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
call 3 never executed
call 4 never executed
-: 353:
1346: 354: _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
call 0 returned 100%
-: 355:}
-: 356:
-: 357:/**
-: 358: * Stores a pointer on a #DBusPendingCall, along
-: 359: * with an optional function to be used for freeing
-: 360: * the data when the data is set again, or when
-: 361: * the pending call is finalized. The slot number
-: 362: * must have been allocated with dbus_pending_call_allocate_data_slot().
-: 363: *
-: 364: * @param pending the pending_call
-: 365: * @param slot the slot number
-: 366: * @param data the data to store
-: 367: * @param free_data_func finalizer function for the data
-: 368: * @returns #TRUE if there was enough memory to store the data
-: 369: */
-: 370:dbus_bool_t
-: 371:dbus_pending_call_set_data (DBusPendingCall *pending,
-: 372: dbus_int32_t slot,
-: 373: void *data,
-: 374: DBusFreeFunction free_data_func)
function dbus_pending_call_set_data called 0 returned 0% blocks executed 0%
#####: 375:{
-: 376: DBusFreeFunction old_free_func;
-: 377: void *old_data;
-: 378: dbus_bool_t retval;
-: 379:
#####: 380: _dbus_return_val_if_fail (pending != NULL, FALSE);
call 0 never executed
branch 1 never executed
branch 2 never executed
call 3 never executed
call 4 never executed
#####: 381: _dbus_return_val_if_fail (slot >= 0, FALSE);
call 0 never executed
branch 1 never executed
branch 2 never executed
call 3 never executed
call 4 never executed
-: 382:
#####: 383: retval = _dbus_data_slot_list_set (&slot_allocator,
call 0 never executed
-: 384: &pending->slot_list,
-: 385: slot, data, free_data_func,
-: 386: &old_free_func, &old_data);
-: 387:
#####: 388: if (retval)
branch 0 never executed
branch 1 never executed
-: 389: {
#####: 390: if (old_free_func)
branch 0 never executed
branch 1 never executed
#####: 391: (* old_free_func) (old_data);
call 0 never executed
-: 392: }
-: 393:
#####: 394: return retval;
-: 395:}
-: 396:
-: 397:/**
-: 398: * Retrieves data previously set with dbus_pending_call_set_data().
-: 399: * The slot must still be allocated (must not have been freed).
-: 400: *
-: 401: * @param pending the pending_call
-: 402: * @param slot the slot to get data from
-: 403: * @returns the data, or #NULL if not found
-: 404: */
-: 405:void*
-: 406:dbus_pending_call_get_data (DBusPendingCall *pending,
-: 407: dbus_int32_t slot)
function dbus_pending_call_get_data called 0 returned 0% blocks executed 0%
#####: 408:{
-: 409: void *res;
-: 410:
#####: 411: _dbus_return_val_if_fail (pending != NULL, NULL);
call 0 never executed
branch 1 never executed
branch 2 never executed
call 3 never executed
call 4 never executed
-: 412:
#####: 413: res = _dbus_data_slot_list_get (&slot_allocator,
call 0 never executed
-: 414: &pending->slot_list,
-: 415: slot);
-: 416:
#####: 417: return res;
-: 418:}
-: 419:
-: 420:/** @} */
-: 421:
-: 422:#ifdef DBUS_BUILD_TESTS
-: 423:
-: 424:/**
-: 425: * @ingroup DBusPendingCallInternals
-: 426: * Unit test for DBusPendingCall.
-: 427: *
-: 428: * @returns #TRUE on success.
-: 429: */
-: 430:dbus_bool_t
-: 431:_dbus_pending_call_test (const char *test_data_dir)
function _dbus_pending_call_test called 1 returned 100% blocks executed 100%
1: 432:{
-: 433:
1: 434: return TRUE;
-: 435:}
-: 436:#endif /* DBUS_BUILD_TESTS */