예제 #1
0
/**
 * Allocates the given number of bytes, as with standard malloc(), but
 * all bytes are initialized to zero as with calloc(). Guaranteed to
 * return #NULL if bytes is zero on all platforms. Returns #NULL if the
 * allocation fails.  The memory must be released with dbus_free().
 *
 * dbus_malloc0() memory is NOT safe to free with regular free() from
 * the C library. Free it with dbus_free() only.
 *
 * @param bytes number of bytes to allocate
 * @return allocated memory, or #NULL if the allocation fails.
 */
void*
dbus_malloc0 (size_t bytes)
{
#ifdef DBUS_BUILD_TESTS
  _dbus_initialize_malloc_debug ();
  
  if (_dbus_decrement_fail_alloc_counter ())
    {
      _dbus_verbose (" FAILING malloc0 of %ld bytes\n", (long) bytes);
      
      return NULL;
    }
#endif
  
  if (bytes == 0)
    return NULL;
#ifdef DBUS_BUILD_TESTS
  else if (fail_size != 0 && bytes > fail_size)
    return NULL;
  else if (guards)
    {
      void *block;

      block = calloc (bytes + GUARD_EXTRA_SIZE, 1);

      if (block)
        {
          _dbus_atomic_inc (&n_blocks_outstanding);
        }
      else if (malloc_cannot_fail)
        {
          _dbus_warn ("out of memory: calloc (%ld + %ld, 1)\n",
              (long) bytes, (long) GUARD_EXTRA_SIZE);
          _dbus_abort ();
        }

      return set_guards (block, bytes, SOURCE_MALLOC_ZERO);
    }
#endif
  else
    {
      void *mem;
      mem = calloc (bytes, 1);

#ifdef DBUS_BUILD_TESTS
      if (mem)
        {
          _dbus_atomic_inc (&n_blocks_outstanding);
        }
      else if (malloc_cannot_fail)
        {
          _dbus_warn ("out of memory: calloc (%ld)\n", (long) bytes);
          _dbus_abort ();
        }
#endif

      return mem;
    }
}
예제 #2
0
/**
 * Allocates the given number of bytes, as with standard
 * malloc(). Guaranteed to return #NULL if bytes is zero
 * on all platforms. Returns #NULL if the allocation fails.
 * The memory must be released with dbus_free().
 *
 * dbus_malloc() memory is NOT safe to free with regular free() from
 * the C library. Free it with dbus_free() only.
 *
 * @param bytes number of bytes to allocate
 * @return allocated memory, or #NULL if the allocation fails.
 */
void*
dbus_malloc (size_t bytes)
{
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
    _dbus_initialize_malloc_debug ();

    if (_dbus_decrement_fail_alloc_counter ())
    {
        _dbus_verbose (" FAILING malloc of %ld bytes\n", (long) bytes);
        return NULL;
    }
#endif

    if (bytes == 0) /* some system mallocs handle this, some don't */
        return NULL;
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
    else if (fail_size != 0 && bytes > fail_size)
        return NULL;
    else if (guards)
    {
        void *block;

        block = malloc (bytes + GUARD_EXTRA_SIZE);
        if (block)
        {
            _dbus_atomic_inc (&n_blocks_outstanding);
        }
        else if (malloc_cannot_fail)
        {
            _dbus_warn ("out of memory: malloc (%ld + %ld)\n",
                        (long) bytes, (long) GUARD_EXTRA_SIZE);
            _dbus_abort ();
        }

        return set_guards (block, bytes, SOURCE_MALLOC);
    }
#endif
    else
    {
        void *mem;
        mem = malloc (bytes);

#ifdef DBUS_ENABLE_EMBEDDED_TESTS
        if (mem)
        {
            _dbus_atomic_inc (&n_blocks_outstanding);
        }
        else if (malloc_cannot_fail)
        {
            _dbus_warn ("out of memory: malloc (%ld)\n", (long) bytes);
            _dbus_abort ();
        }
#endif

        return mem;
    }
}
/**
 * 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_atomic_inc (&pending->refcount);

  return 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_return_val_if_fail (pending != NULL, NULL);

  _dbus_atomic_inc (&pending->refcount);

  return pending;
}
예제 #5
0
/**
 * 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;
}
예제 #6
0
/**
 * 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;
}
예제 #7
0
/**
 * Like dbus_server_ref() but does not acquire the lock (must already be held)
 *
 * @param server the server.
 */
void
_dbus_server_ref_unlocked (DBusServer *server)
{
    dbus_int32_t old_refcount;

    _dbus_assert (server != NULL);
    HAVE_LOCK_CHECK (server);

    old_refcount = _dbus_atomic_inc (&server->refcount);
    _dbus_assert (old_refcount > 0);
    _dbus_server_trace_ref (server, old_refcount, old_refcount + 1,
                            "ref_unlocked");
}
예제 #8
0
/**
 * 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;
}
예제 #9
0
/**
 * Like dbus_server_ref() but does not acquire the lock (must already be held)
 *
 * @param server the server.
 */
void
_dbus_server_ref_unlocked (DBusServer *server)
{
  _dbus_assert (server != NULL);
  _dbus_assert (server->refcount.value > 0);
  
  HAVE_LOCK_CHECK (server);

#ifdef DBUS_HAVE_ATOMIC_INT
  _dbus_atomic_inc (&server->refcount);
#else
  _dbus_assert (server->refcount.value > 0);

  server->refcount.value += 1;
#endif
}
예제 #10
0
/**
 * Increments the reference count of a DBusServer.
 *
 * @param server the server.
 * @returns the server
 */
DBusServer *
dbus_server_ref (DBusServer *server)
{
  _dbus_return_val_if_fail (server != NULL, NULL);
  _dbus_return_val_if_fail (server->refcount.value > 0, NULL);

#ifdef DBUS_HAVE_ATOMIC_INT
  _dbus_atomic_inc (&server->refcount);
#else
  SERVER_LOCK (server);
  _dbus_assert (server->refcount.value > 0);

  server->refcount.value += 1;
  SERVER_UNLOCK (server);
#endif

  return server;
}
예제 #11
0
/**
 * Decrements the reference count of a DBusServer.  Finalizes the
 * server if the reference count reaches zero.
 *
 * The server must be disconnected before the refcount reaches zero.
 *
 * @param server the server.
 */
void
dbus_server_unref (DBusServer *server)
{
    dbus_int32_t old_refcount;

    /* keep this in sync with unref_unlocked */

    _dbus_return_if_fail (server != NULL);

    old_refcount = _dbus_atomic_dec (&server->refcount);

#ifndef DBUS_DISABLE_CHECKS
    if (_DBUS_UNLIKELY (old_refcount <= 0))
    {
        /* undo side-effect first
         * please do not try to simplify the code here by using
         * _dbus_atomic_get(), why we don't use it is
         * because it issues another atomic operation even though
         * DBUS_DISABLE_CHECKS defined.
         * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=68303
         */
        _dbus_atomic_inc (&server->refcount);
        _dbus_warn_check_failed (_dbus_return_if_fail_warning_format,
                                 _DBUS_FUNCTION_NAME, "old_refcount > 0",
                                 __FILE__, __LINE__);
        return;
    }
#endif

    _dbus_server_trace_ref (server, old_refcount, old_refcount - 1, "unref");

    if (old_refcount == 1)
    {
        /* lock not held! */
        _dbus_assert (server->disconnected);

        _dbus_assert (server->vtable->finalize != NULL);

        (* server->vtable->finalize) (server);
    }
}
예제 #12
0
EXPORT_C 
#endif
 
DBusPendingCall *
dbus_pending_call_ref (DBusPendingCall *pending)
{
  _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);

  pending->refcount.value += 1;
  CONNECTION_UNLOCK (pending->connection);
#endif
  
  return pending;
}
예제 #13
0
파일: dbus-server.c 프로젝트: halfline/dbus
/**
 * Increments the reference count of a DBusServer.
 *
 * @param server the server.
 * @returns the server
 */
DBusServer *
dbus_server_ref (DBusServer *server)
{
  dbus_int32_t old_refcount;

  _dbus_return_val_if_fail (server != NULL, NULL);

  old_refcount = _dbus_atomic_inc (&server->refcount);

#ifndef DBUS_DISABLE_CHECKS
  if (_DBUS_UNLIKELY (old_refcount <= 0))
    {
      _dbus_atomic_dec (&server->refcount);
      _dbus_warn_return_if_fail (_DBUS_FUNCTION_NAME, "old_refcount > 0",
                                 __FILE__, __LINE__);
      return NULL;
    }
#endif

  _dbus_server_trace_ref (server, old_refcount, old_refcount + 1, "ref");

  return server;
}
예제 #14
0
파일: dbus-memory.c 프로젝트: mirsal/dbus
/**
 * Resizes a block of memory previously allocated by dbus_malloc() or
 * dbus_malloc0(). Guaranteed to free the memory and return #NULL if bytes
 * is zero on all platforms. Returns #NULL if the resize fails.
 * If the resize fails, the memory is not freed.
 *
 * @param memory block to be resized
 * @param bytes new size of the memory block
 * @return allocated memory, or #NULL if the resize fails.
 */
void*
dbus_realloc (void  *memory,
              size_t bytes)
{
#ifdef DBUS_BUILD_TESTS
  _dbus_initialize_malloc_debug ();
  
  if (_dbus_decrement_fail_alloc_counter ())
    {
      _dbus_verbose (" FAILING realloc of %ld bytes\n", (long) bytes);
      
      return NULL;
    }
#endif
  
  if (bytes == 0) /* guarantee this is safe */
    {
      dbus_free (memory);
      return NULL;
    }
#ifdef DBUS_BUILD_TESTS
  else if (fail_size != 0 && bytes > fail_size)
    return NULL;
  else if (guards)
    {
      if (memory)
        {
          size_t old_bytes;
          void *block;
          
          check_guards (memory, FALSE);
          
          block = realloc (((unsigned char*)memory) - GUARD_START_OFFSET,
                           bytes + GUARD_EXTRA_SIZE);

	  old_bytes = *(dbus_uint32_t*)block;
          if (block && bytes >= old_bytes)
            /* old guards shouldn't have moved */
            check_guards (((unsigned char*)block) + GUARD_START_OFFSET, FALSE);
          
          return set_guards (block, bytes, SOURCE_REALLOC);
        }
      else
        {
          void *block;
          
          block = malloc (bytes + GUARD_EXTRA_SIZE);

          if (block)
	    _dbus_atomic_inc (&n_blocks_outstanding);
          
          return set_guards (block, bytes, SOURCE_REALLOC_NULL);   
        }
    }
#endif
  else
    {
      void *mem;
      mem = realloc (memory, bytes);
#ifdef DBUS_BUILD_TESTS
      if (memory == NULL && mem != NULL)
	    _dbus_atomic_inc (&n_blocks_outstanding);
#endif
      return mem;
    }
}
예제 #15
0
/**
 * Initializes the members of the DBusServer base class.
 * Chained up to by subclass constructors.
 *
 * @param server the server.
 * @param vtable the vtable for the subclass.
 * @param address the server's address
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_server_init_base (DBusServer             *server,
                        const DBusServerVTable *vtable,
                        const DBusString       *address)
{
    server->vtable = vtable;

#ifdef DBUS_DISABLE_ASSERT
    _dbus_atomic_inc (&server->refcount);
#else
    {
        dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);

        _dbus_assert (old_refcount == 0);
    }
#endif

    server->address = NULL;
    server->watches = NULL;
    server->timeouts = NULL;
    server->published_address = FALSE;

    if (!_dbus_string_init (&server->guid_hex))
        return FALSE;

    _dbus_generate_uuid (&server->guid);

    if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
        goto failed;

    server->address = copy_address_with_guid_appended (address,
                      &server->guid_hex);
    if (server->address == NULL)
        goto failed;

    _dbus_rmutex_new_at_location (&server->mutex);
    if (server->mutex == NULL)
        goto failed;

    server->watches = _dbus_watch_list_new ();
    if (server->watches == NULL)
        goto failed;

    server->timeouts = _dbus_timeout_list_new ();
    if (server->timeouts == NULL)
        goto failed;

    _dbus_data_slot_list_init (&server->slot_list);

    _dbus_verbose ("Initialized server on address %s\n", server->address);

    return TRUE;

failed:
    _dbus_rmutex_free_at_location (&server->mutex);
    server->mutex = NULL;
    if (server->watches)
    {
        _dbus_watch_list_free (server->watches);
        server->watches = NULL;
    }
    if (server->timeouts)
    {
        _dbus_timeout_list_free (server->timeouts);
        server->timeouts = NULL;
    }
    if (server->address)
    {
        dbus_free (server->address);
        server->address = NULL;
    }
    _dbus_string_free (&server->guid_hex);

    return FALSE;
}
예제 #16
0
/**
 * Resizes a block of memory previously allocated by dbus_malloc() or
 * dbus_malloc0(). Guaranteed to free the memory and return #NULL if bytes
 * is zero on all platforms. Returns #NULL if the resize fails.
 * If the resize fails, the memory is not freed.
 *
 * @param memory block to be resized
 * @param bytes new size of the memory block
 * @return allocated memory, or #NULL if the resize fails.
 */
void*
_dbus_realloc (void  *memory,
               size_t bytes,
               const char *file,
               int line)
{
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
  _dbus_initialize_malloc_debug ();
  
  if (_dbus_decrement_fail_alloc_counter ())
    {
      _dbus_verbose (" FAILING realloc of %ld bytes\n", (long) bytes);
      
      return NULL;
    }
#endif
  
  if (bytes == 0) /* guarantee this is safe */
    {
      dbus_free (memory);
      return NULL;
    }
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
  else if (fail_size != 0 && bytes > fail_size)
    return NULL;
  else if (guards)
    {
      if (memory)
        {
          size_t old_bytes;
          void *block;
          
          check_guards (memory, FALSE);
          
          block = realloc (((unsigned char*)memory) - GUARD_START_OFFSET,
                           bytes + GUARD_EXTRA_SIZE);

          if (block == NULL)
            {
              if (malloc_cannot_fail)
                {
                  _dbus_warn ("out of memory: realloc (%p, %ld + %ld)\n",
                      memory, (long) bytes, (long) GUARD_EXTRA_SIZE);
                  _dbus_abort ();
                }

              return NULL;
            }
          dbus_track_free (((unsigned char*)memory) - GUARD_START_OFFSET);
          dbus_track_realloc (((unsigned char*)memory) - GUARD_START_OFFSET, bytes + GUARD_EXTRA_SIZE, file, line);

          old_bytes = *(dbus_uint32_t*)block;
          if (bytes >= old_bytes)
            /* old guards shouldn't have moved */
            check_guards (((unsigned char*)block) + GUARD_START_OFFSET, FALSE);
          
          return set_guards (block, bytes, SOURCE_REALLOC);
        }
      else
        {
          void *block;
          
          block = malloc (bytes + GUARD_EXTRA_SIZE);

          if (block)
            {
              _dbus_atomic_inc (&n_blocks_outstanding);
              dbus_track_malloc(block, bytes + GUARD_EXTRA_SIZE, file, line);
            }
          else if (malloc_cannot_fail)
            {
              _dbus_warn ("out of memory: malloc (%ld + %ld)\n",
                  (long) bytes, (long) GUARD_EXTRA_SIZE);
              _dbus_abort ();
            }

          return set_guards (block, bytes, SOURCE_REALLOC_NULL);   
        }
    }
#endif
  else
    {
      void *mem;
      mem = realloc (memory, bytes);

#ifdef DBUS_ENABLE_EMBEDDED_TESTS
      if (mem == NULL && malloc_cannot_fail)
        {
          _dbus_warn ("out of memory: malloc (%ld)\n", (long) bytes);
          _dbus_abort ();
        }

      if (memory == NULL && mem != NULL)
	    _dbus_atomic_inc (&n_blocks_outstanding);
#endif
      dbus_track_free (memory);
      dbus_track_realloc (mem, bytes, file, line);
      return mem;
    }
}