예제 #1
0
/**
 * Like dbus_server_unref() but does not acquire the lock (must already be held)
 *
 * @param server the server.
 */
void
_dbus_server_unref_unlocked (DBusServer *server)
{
    dbus_int32_t old_refcount;

    /* Keep this in sync with dbus_server_unref */

    _dbus_assert (server != NULL);

    HAVE_LOCK_CHECK (server);

    old_refcount = _dbus_atomic_dec (&server->refcount);
    _dbus_assert (old_refcount > 0);

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

    if (old_refcount == 1)
    {
        _dbus_assert (server->disconnected);

        SERVER_UNLOCK (server);

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

        (* server->vtable->finalize) (server);
    }
}
예제 #2
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");
}
예제 #3
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);
    }
}
예제 #4
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;
}
예제 #5
0
/**
 * Creates a new server listening on the given file descriptor.  The
 * file descriptor should be nonblocking (use
 * _dbus_set_fd_nonblocking() to make it so). The file descriptor
 * should be listening for connections, that is, listen() should have
 * been successfully invoked on it. The server will use accept() to
 * accept new client connections.
 *
 * @param fds list of file descriptors.
 * @param n_fds number of file descriptors
 * @param address the server's address
 * @param noncefile to be used for authentication (NULL if not needed)
 * @returns the new server, or #NULL if no memory.
 *
 */
DBusServer*
_dbus_server_new_for_socket (int              *fds,
                             int               n_fds,
                             const DBusString *address,
                             DBusNonceFile    *noncefile)
{
  DBusServerSocket *socket_server;
  DBusServer *server;
  int i;

  socket_server = dbus_new0 (DBusServerSocket, 1);
  if (socket_server == NULL)
    return NULL;

  socket_server->noncefile = noncefile;

  socket_server->fds = dbus_new (int, n_fds);
  if (!socket_server->fds)
    goto failed_0;

  socket_server->watch = dbus_new0 (DBusWatch *, n_fds);
  if (!socket_server->watch)
    goto failed_1;

  for (i = 0 ; i < n_fds ; i++)
    {
      DBusWatch *watch;

      watch = _dbus_watch_new (fds[i],
                               DBUS_WATCH_READABLE,
                               TRUE,
                               socket_handle_watch, socket_server,
                               NULL);
      if (watch == NULL)
        goto failed_2;

      socket_server->n_fds++;
      socket_server->fds[i] = fds[i];
      socket_server->watch[i] = watch;
    }

  if (!_dbus_server_init_base (&socket_server->base,
                               &socket_vtable, address))
    goto failed_2;

  server = (DBusServer*)socket_server;

  SERVER_LOCK (server);

  for (i = 0 ; i < n_fds ; i++)
    {
      if (!_dbus_server_add_watch (&socket_server->base,
                                   socket_server->watch[i]))
        {
          int j;
          for (j = 0 ; j < i ; j++)
            _dbus_server_remove_watch (server,
                                       socket_server->watch[j]);

          SERVER_UNLOCK (server);
          _dbus_server_finalize_base (&socket_server->base);
          goto failed_2;
        }
    }

  SERVER_UNLOCK (server);

  _dbus_server_trace_ref (&socket_server->base, 0, 1, "new_for_socket");
  return (DBusServer*) socket_server;

 failed_2:
  for (i = 0 ; i < n_fds ; i++)
    {
      if (socket_server->watch[i] != NULL)
        {
          _dbus_watch_unref (socket_server->watch[i]);
          socket_server->watch[i] = NULL;
        }
    }
  dbus_free (socket_server->watch);

 failed_1:
  dbus_free (socket_server->fds);

 failed_0:
  dbus_free (socket_server);
  return NULL;
}
/**
 * Creates a new debug server using an in-process pipe
 *
 * @param server_name the name of the server.
 * @param error address where an error can be returned.
 * @returns a new server, or #NULL on failure.
 */
DBusServer*
_dbus_server_debug_pipe_new (const char     *server_name,
                             DBusError      *error)
{
  DBusServerDebugPipe *debug_server;
  DBusString address;
  DBusString name_str;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  if (!pipe_hash_ref ())
    return NULL;
  
  if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL)
    {
      dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL);
      pipe_hash_unref ();
      return NULL;
    }
  
  debug_server = dbus_new0 (DBusServerDebugPipe, 1);
  if (debug_server == NULL)
    goto nomem_0;

  if (!_dbus_string_init (&address))
    goto nomem_1;

  _dbus_string_init_const (&name_str, server_name);
  if (!_dbus_string_append (&address, "debug-pipe:name=") ||
      !_dbus_address_append_escaped (&address, &name_str))
    goto nomem_2;
  
  debug_server->name = _dbus_strdup (server_name);
  if (debug_server->name == NULL)
    goto nomem_2;
  
  if (!_dbus_server_init_base (&debug_server->base,
			       &debug_vtable, &address))
    goto nomem_3;

  if (!_dbus_hash_table_insert_string (server_pipe_hash,
				       debug_server->name,
				       debug_server))
    goto nomem_4;

  _dbus_string_free (&address);

  /* server keeps the pipe hash ref */

  _dbus_server_trace_ref (&debug_server->base, 0, 1, "debug_pipe_new");
  return (DBusServer *)debug_server;

 nomem_4:
  _dbus_server_finalize_base (&debug_server->base);
 nomem_3:
  dbus_free (debug_server->name);
 nomem_2:
  _dbus_string_free (&address);
 nomem_1:
  dbus_free (debug_server);
 nomem_0:
  pipe_hash_unref ();
  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
  return NULL;
}