Example #1
0
static dbus_bool_t
protected_change_watch (DBusServer             *server,
                        DBusWatch              *watch,
                        DBusWatchAddFunction    add_function,
                        DBusWatchRemoveFunction remove_function,
                        DBusWatchToggleFunction toggle_function,
                        dbus_bool_t             enabled)
{
    DBusWatchList *watches;
    dbus_bool_t retval;

    HAVE_LOCK_CHECK (server);

    /* This isn't really safe or reasonable; a better pattern is the "do
     * everything, then drop lock and call out" one; but it has to be
     * propagated up through all callers
     */

    watches = server->watches;
    if (watches)
    {
        server->watches = NULL;
        _dbus_server_ref_unlocked (server);
        SERVER_UNLOCK (server);

        if (add_function)
            retval = (* add_function) (watches, watch);
        else if (remove_function)
        {
            retval = TRUE;
            (* remove_function) (watches, watch);
        }
        else
        {
            retval = TRUE;
            (* toggle_function) (watches, watch, enabled);
        }

        SERVER_LOCK (server);
        server->watches = watches;
        _dbus_server_unref_unlocked (server);

        return retval;
    }
    else
        return FALSE;
}
Example #2
0
static dbus_bool_t
protected_change_timeout (DBusServer               *server,
                          DBusTimeout              *timeout,
                          DBusTimeoutAddFunction    add_function,
                          DBusTimeoutRemoveFunction remove_function,
                          DBusTimeoutToggleFunction toggle_function,
                          dbus_bool_t               enabled)
{
    DBusTimeoutList *timeouts;
    dbus_bool_t retval;

    HAVE_LOCK_CHECK (server);

    /* This isn't really safe or reasonable; a better pattern is the "do everything, then
     * drop lock and call out" one; but it has to be propagated up through all callers
     */

    timeouts = server->timeouts;
    if (timeouts)
    {
        server->timeouts = NULL;
        _dbus_server_ref_unlocked (server);
        SERVER_UNLOCK (server);

        if (add_function)
            retval = (* add_function) (timeouts, timeout);
        else if (remove_function)
        {
            retval = TRUE;
            (* remove_function) (timeouts, timeout);
        }
        else
        {
            retval = TRUE;
            (* toggle_function) (timeouts, timeout, enabled);
        }

        SERVER_LOCK (server);
        server->timeouts = timeouts;
        _dbus_server_unref_unlocked (server);

        return retval;
    }
    else
        return FALSE;
}
/**
 * Releases the server's address and stops listening for
 * new clients. If called more than once, only the first
 * call has an effect. Does not modify the server's
 * reference count.
 * 
 * @param server the server.
 */
void
dbus_server_disconnect (DBusServer *server)
{
  _dbus_return_if_fail (server != NULL);
  _dbus_return_if_fail (server->refcount.value > 0);

  SERVER_LOCK (server);
  _dbus_server_ref_unlocked (server);
  
  _dbus_assert (server->vtable->disconnect != NULL);

  if (!server->disconnected)
    {
      /* this has to be first so recursive calls to disconnect don't happen */
      server->disconnected = TRUE;
      
      (* server->vtable->disconnect) (server);
    }

  SERVER_UNLOCK (server);
  dbus_server_unref (server);
}
/* Return value is just for memory, not other failures. */
static dbus_bool_t
handle_new_client_fd_and_unlock (DBusServer *server,
                                 int         client_fd)
{
  DBusConnection *connection;
  DBusTransport *transport;
  DBusNewConnectionFunction new_connection_function;
  DBusServerSocket* socket_server;
  void *new_connection_data;

  socket_server = (DBusServerSocket*)server;
  _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);

  HAVE_LOCK_CHECK (server);

  if (!_dbus_set_fd_nonblocking (client_fd, NULL))
    {
      SERVER_UNLOCK (server);
      return TRUE;
    }

  transport = _dbus_transport_new_for_socket (client_fd, &server->guid_hex, FALSE);
  if (transport == NULL)
    {
      _dbus_close_socket (client_fd, NULL);
      SERVER_UNLOCK (server);
      return FALSE;
    }

  if (!_dbus_transport_set_auth_mechanisms (transport,
                                            (const char **) server->auth_mechanisms))
    {
      _dbus_transport_unref (transport);
      SERVER_UNLOCK (server);
      return FALSE;
    }

  /* note that client_fd is now owned by the transport, and will be
   * closed on transport disconnection/finalization
   */

  connection = _dbus_connection_new_for_transport (transport);
  _dbus_transport_unref (transport);
  transport = NULL; /* now under the connection lock */

  if (connection == NULL)
    {
      SERVER_UNLOCK (server);
      return FALSE;
    }

  /* See if someone wants to handle this new connection, self-referencing
   * for paranoia.
   */
  new_connection_function = server->new_connection_function;
  new_connection_data = server->new_connection_data;

  _dbus_server_ref_unlocked (server);
  SERVER_UNLOCK (server);

  if (new_connection_function)
    {
      (* new_connection_function) (server, connection,
                                   new_connection_data);
    }
  dbus_server_unref (server);

  /* If no one grabbed a reference, the connection will die. */
  _dbus_connection_close_if_only_one_ref (connection);
  dbus_connection_unref (connection);

  return TRUE;
}