X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-pending-call.c;h=be5341058ad9b1d3a45259bc074370b86bd0dfa4;hb=9e835251cdcb80eeef8565721f4fbd4047f76b2b;hp=15564aadfc2ad90324f4ac3d0741786dd5493e38;hpb=7398ad7374c0a9201d41397c956deee325f3593e;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c index 15564aa..be53410 100644 --- a/dbus/dbus-pending-call.c +++ b/dbus/dbus-pending-call.c @@ -17,12 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +#include #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" @@ -77,13 +79,29 @@ struct DBusPendingCall unsigned int timeout_added : 1; /**< Have added the timeout */ }; +static void +_dbus_pending_call_trace_ref (DBusPendingCall *pending_call, + int old_refcount, + int new_refcount, + const char *why) +{ +#ifdef DBUS_ENABLE_VERBOSE_MODE + static int enabled = -1; + + _dbus_trace_ref ("DBusPendingCall", pending_call, old_refcount, + new_refcount, why, "DBUS_PENDING_CALL_TRACE", &enabled); +#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 for default, INT_MAX for no timeout + * @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. */ @@ -111,7 +129,7 @@ _dbus_pending_call_new_unlocked (DBusConnection *connection, return NULL; } - if (timeout_milliseconds != _DBUS_INT_MAX) + if (timeout_milliseconds != DBUS_TIMEOUT_INFINITE) { timeout = _dbus_timeout_new (timeout_milliseconds, timeout_handler, @@ -130,13 +148,15 @@ _dbus_pending_call_new_unlocked (DBusConnection *connection, { pending->timeout = NULL; } - - pending->refcount.value = 1; + + _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; } @@ -350,6 +370,8 @@ _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending, reply_link = _dbus_list_alloc_link (reply); if (reply_link == NULL) { + /* it's OK to unref this, nothing that could have attached a callback + * has ever seen it */ dbus_message_unref (reply); return FALSE; } @@ -371,8 +393,12 @@ _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending, DBusPendingCall * _dbus_pending_call_ref_unlocked (DBusPendingCall *pending) { - pending->refcount.value += 1; - + 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; } @@ -430,15 +456,16 @@ _dbus_pending_call_last_unref (DBusPendingCall *pending) void _dbus_pending_call_unref_and_unlock (DBusPendingCall *pending) { - dbus_bool_t last_unref; - - _dbus_assert (pending->refcount.value > 0); + dbus_int32_t old_refcount; - pending->refcount.value -= 1; - last_unref = pending->refcount.value == 0; + old_refcount = _dbus_atomic_dec (&pending->refcount); + _dbus_assert (old_refcount > 0); + _dbus_pending_call_trace_ref (pending, old_refcount, + old_refcount - 1, "unref_and_unlock"); CONNECTION_UNLOCK (pending->connection); - if (last_unref) + + if (old_refcount == 1) _dbus_pending_call_last_unref (pending); } @@ -455,8 +482,8 @@ _dbus_pending_call_get_completed_unlocked (DBusPendingCall *pending) return pending->completed; } -static DBusDataSlotAllocator slot_allocator; -_DBUS_DEFINE_GLOBAL_LOCK (pending_call_slots); +static DBusDataSlotAllocator slot_allocator = + _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (pending_call_slots)); /** * Stores a pointer on a #DBusPendingCall, along @@ -515,6 +542,26 @@ _dbus_pending_call_set_data_unlocked (DBusPendingCall *pending, */ /** + * @def DBUS_TIMEOUT_INFINITE + * + * An integer constant representing an infinite timeout. This has the + * numeric value 0x7fffffff (the largest 32-bit signed integer). + * + * For source compatibility with D-Bus versions earlier than 1.4.12, use + * 0x7fffffff, or INT32_MAX (assuming your platform has it). + */ + +/** + * @def DBUS_TIMEOUT_USE_DEFAULT + * + * An integer constant representing a request to use the default timeout. + * This has numeric value -1. + * + * For source compatibility with D-Bus versions earlier than 1.4.12, use a + * literal -1. + */ + +/** * @typedef DBusPendingCall * * Opaque data type representing a message pending. @@ -529,21 +576,14 @@ _dbus_pending_call_set_data_unlocked (DBusPendingCall *pending, DBusPendingCall * dbus_pending_call_ref (DBusPendingCall *pending) { + dbus_int32_t old_refcount; + _dbus_return_val_if_fail (pending != NULL, NULL); - /* The connection lock is better than the global - * lock in the atomic increment fallback - */ -#ifdef DBUS_HAVE_ATOMIC_INT - _dbus_atomic_inc (&pending->refcount); -#else - CONNECTION_LOCK (pending->connection); - _dbus_assert (pending->refcount.value > 0); + old_refcount = _dbus_atomic_inc (&pending->refcount); + _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount + 1, + "ref"); - pending->refcount.value += 1; - CONNECTION_UNLOCK (pending->connection); -#endif - return pending; } @@ -556,24 +596,15 @@ dbus_pending_call_ref (DBusPendingCall *pending) void dbus_pending_call_unref (DBusPendingCall *pending) { - dbus_bool_t last_unref; + dbus_int32_t old_refcount; _dbus_return_if_fail (pending != NULL); - /* More efficient to use the connection lock instead of atomic - * int fallback if we lack atomic int decrement - */ -#ifdef DBUS_HAVE_ATOMIC_INT - last_unref = (_dbus_atomic_dec (&pending->refcount) == 1); -#else - CONNECTION_LOCK (pending->connection); - _dbus_assert (pending->refcount.value > 0); - pending->refcount.value -= 1; - last_unref = pending->refcount.value == 0; - CONNECTION_UNLOCK (pending->connection); -#endif - - if (last_unref) + 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); } @@ -593,6 +624,8 @@ dbus_pending_call_set_notify (DBusPendingCall *pending, void *user_data, DBusFreeFunction free_user_data) { + dbus_bool_t ret = FALSE; + _dbus_return_val_if_fail (pending != NULL, FALSE); CONNECTION_LOCK (pending->connection); @@ -600,13 +633,15 @@ dbus_pending_call_set_notify (DBusPendingCall *pending, /* could invoke application code! */ if (!_dbus_pending_call_set_data_unlocked (pending, notify_user_data_slot, user_data, free_user_data)) - return FALSE; + goto out; pending->function = function; + ret = TRUE; +out: CONNECTION_UNLOCK (pending->connection); - return TRUE; + return ret; } /** @@ -678,7 +713,8 @@ dbus_pending_call_steal_reply (DBusPendingCall *pending) pending->reply = NULL; CONNECTION_UNLOCK (pending->connection); - + + _dbus_message_trace_ref (message, -1, -1, "dbus_pending_call_steal_reply"); return message; } @@ -725,7 +761,6 @@ 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); } @@ -806,19 +841,3 @@ dbus_pending_call_get_data (DBusPendingCall *pending, } /** @} */ - -#ifdef DBUS_BUILD_TESTS - -/** - * @ingroup DBusPendingCallInternals - * Unit test for DBusPendingCall. - * - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_pending_call_test (const char *test_data_dir) -{ - - return TRUE; -} -#endif /* DBUS_BUILD_TESTS */