static gboolean
message_queue_prepare (GSource *source, gint *timeout)
{
	DBusConnection *connection = ((DBusGMessageQueue *)source)->connection;
	*timeout = -1;
	return (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_DATA_REMAINS);
}
Ejemplo n.º 2
0
static gboolean setup_bus(DBusConnection *conn, const char *name,
						DBusError *error)
{
	gboolean result;
	DBusDispatchStatus status;

	if (name != NULL) {
		result = g_dbus_request_name(conn, name, error);

		if (error != NULL) {
			if (dbus_error_is_set(error) == TRUE)
				return FALSE;
		}

		if (result == FALSE)
			return FALSE;
	}

	setup_dbus_with_main_loop(conn);

	status = dbus_connection_get_dispatch_status(conn);
	queue_dispatch(conn, status);

	return TRUE;
}
Ejemplo n.º 3
0
static Eina_Bool watch_handler_dispatch(void *data,
					Ecore_Fd_Handler *e_handler)
{
	struct watch_handler *io_handler = data;
	DBusDispatchStatus status;
	unsigned int flags = 0;

	if (ecore_main_fd_handler_active_get(e_handler, ECORE_FD_ERROR)
								== EINA_TRUE)
		flags |= DBUS_WATCH_ERROR;
	if (ecore_main_fd_handler_active_get(e_handler, ECORE_FD_READ)
								== EINA_TRUE)
		flags |= DBUS_WATCH_READABLE;
	if (ecore_main_fd_handler_active_get(e_handler, ECORE_FD_WRITE)
								== EINA_TRUE)
		flags |= DBUS_WATCH_WRITABLE;

	dbus_watch_handle(io_handler->watch, flags);

	status = dbus_connection_get_dispatch_status(io_handler->dbus_cnx);
	if (status == DBUS_DISPATCH_DATA_REMAINS)
		ecore_timer_add(0, efl_dispatch_dbus, io_handler->dbus_cnx);

	dbus_connection_unref(io_handler->dbus_cnx);

	return TRUE;
}
Ejemplo n.º 4
0
Archivo: dbus.c Proyecto: etix/vlc
/**
 * DispatchDBusMessages() dispatches incoming dbus messages
 * (indirectly invoking the callbacks), then it sends outgoing
 * messages which needs to be sent on the bus (method replies and signals)
 *
 * This function must be called with p_sys->lock unlocked
 *
 * @param intf_thread_t *p_intf This interface thread state
 */
static void DispatchDBusMessages( intf_thread_t *p_intf )
{
    DBusDispatchStatus status;
    intf_sys_t *p_sys = p_intf->p_sys;

    /* Dispatch incoming messages */
    status = dbus_connection_get_dispatch_status( p_sys->p_conn );
    while( status != DBUS_DISPATCH_COMPLETE )
    {
        dbus_connection_dispatch( p_sys->p_conn );
        status = dbus_connection_get_dispatch_status( p_sys->p_conn );
    }

    /* Send outgoing data */
    if( dbus_connection_has_messages_to_send( p_sys->p_conn ) )
        dbus_connection_flush( p_sys->p_conn );
}
Ejemplo n.º 5
0
/**
 * dispatch_initial_dbus_messages - Dispatch initial dbus messages after
 *     claiming bus name
 * @eloop_ctx: the DBusConnection to dispatch on
 * @timeout_ctx: unused
 *
 * If clients are quick to notice that wpa_supplicant claimed its bus name,
 * there may have been messages that came in before initialization was
 * all finished.  Dispatch those here.
 */
static void dispatch_initial_dbus_messages(void *eloop_ctx, void *timeout_ctx)
{
	DBusConnection *con = eloop_ctx;

	while (dbus_connection_get_dispatch_status(con) ==
	       DBUS_DISPATCH_DATA_REMAINS)
		dbus_connection_dispatch(con);
}
Ejemplo n.º 6
0
void pcmk_dbus_connection_setup_with_select(DBusConnection *c){
        dbus_connection_set_exit_on_disconnect (c, FALSE);
	dbus_connection_set_timeout_functions(
            c, pcmk_dbus_timeout_add, pcmk_dbus_timeout_remove, pcmk_dbus_timeout_toggle, NULL, NULL);
	dbus_connection_set_watch_functions(c, pcmk_dbus_watch_add, pcmk_dbus_watch_remove, pcmk_dbus_watch_toggle, NULL, NULL);
	dbus_connection_set_dispatch_status_function(c, pcmk_dbus_connection_dispatch, NULL, NULL);

	pcmk_dbus_connection_dispatch(c, dbus_connection_get_dispatch_status(c), NULL);
}
Ejemplo n.º 7
0
static void Run          ( intf_thread_t *p_intf )
{
    for( ;; )
    {
        if( dbus_connection_get_dispatch_status(p_intf->p_sys->p_conn)
                                             == DBUS_DISPATCH_COMPLETE )
            msleep( INTF_IDLE_SLEEP );
        int canc = vlc_savecancel();
        dbus_connection_read_write_dispatch( p_intf->p_sys->p_conn, 0 );

        /* Get the list of events to process
         *
         * We can't keep the lock on p_intf->p_sys->p_events, else we risk a
         * deadlock:
         * The signal functions could lock mutex X while p_events is locked;
         * While some other function in vlc (playlist) might lock mutex X
         * and then set a variable which would call AllCallback(), which itself
         * needs to lock p_events to add a new event.
         */
        vlc_mutex_lock( &p_intf->p_sys->lock );
        int i_events = vlc_array_count( p_intf->p_sys->p_events );
        callback_info_t* info[i_events];
        for( int i = i_events - 1; i >= 0; i-- )
        {
            info[i] = vlc_array_item_at_index( p_intf->p_sys->p_events, i );
            vlc_array_remove( p_intf->p_sys->p_events, i );
        }
        vlc_mutex_unlock( &p_intf->p_sys->lock );

        for( int i = 0; i < i_events; i++ )
        {
            switch( info[i]->signal )
            {
            case SIGNAL_ITEM_CURRENT:
                TrackChange( p_intf );
                break;
            case SIGNAL_INTF_CHANGE:
            case SIGNAL_PLAYLIST_ITEM_APPEND:
            case SIGNAL_PLAYLIST_ITEM_DELETED:
                TrackListChangeEmit( p_intf, info[i]->signal, info[i]->i_node );
                break;
            case SIGNAL_RANDOM:
            case SIGNAL_REPEAT:
            case SIGNAL_LOOP:
                StatusChangeEmit( p_intf );
                break;
            case SIGNAL_STATE:
                StateChange( p_intf, info[i]->i_input_state );
                break;
            default:
                assert(0);
            }
            free( info[i] );
        }
        vlc_restorecancel( canc );
    }
}
Ejemplo n.º 8
0
void block_hook_cb( hidval data )
{
  /* phantom */ DBusConnection *connection;
  if ( dbus_connection_get_dispatch_status( &data.lval ) == 0 )
  {
    data = data;
  }
  return;
}
Ejemplo n.º 9
0
static void pcmk_dbus_connection_dispatch(DBusConnection *connection, DBusDispatchStatus new_status, void *data){
    crm_trace("status %d for %p", new_status, data);
    if (new_status == DBUS_DISPATCH_DATA_REMAINS){
        dbus_connection_dispatch(connection);

        while (dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS) {
            dbus_connection_dispatch(connection);
        }
    }
}
Ejemplo n.º 10
0
static void request_dispatch(ConnectionData *d, int enable) {
    static const struct timeval tv = { 0, 0 };
    assert(d);

    if (enable) {
        assert(dbus_connection_get_dispatch_status(d->connection) == DBUS_DISPATCH_DATA_REMAINS);
        d->poll_api->timeout_update(d->dispatch_timeout, &tv);
    } else
        d->poll_api->timeout_update(d->dispatch_timeout, NULL);
}
Ejemplo n.º 11
0
Archivo: dbus.c Proyecto: chaind/chaind
int dbus_update(struct dbus* dbus)
{
    DBusDispatchStatus status;

    // handle watches
    Word_t watch_count = 0;
    JLC(watch_count, dbus->watches, 0, -1);
    struct pollfd* pollfds = (struct pollfd*)alloca(sizeof(struct pollfd) * watch_count);
    int fdcount = get_pollfds(dbus, pollfds);

    if(poll(pollfds, fdcount, 0) < 0) {
        return -1;
    }

    // process the watches
    DBusWatch** pwatch;
    Word_t index = 0;
    int c = 0;
    JLF(pwatch, dbus->watches, index);
    while(pwatch != NULL) {
        struct pollfd* poll_result = &pollfds[c];
        struct DBusWatch* watch = *pwatch;

        if(dbus_watch_get_enabled(watch)) {
            assert(poll_result->fd == dbus_watch_get_unix_fd(watch));

            int flags = 0;
            int revents = poll_result->revents;

            if((revents & POLLIN) != 0) flags |= DBUS_WATCH_READABLE;
            if((revents & POLLOUT) != 0) flags |= DBUS_WATCH_WRITABLE;
            if((revents & POLLERR) != 0) flags |= DBUS_WATCH_ERROR;
            if((revents & POLLHUP) != 0) flags |= DBUS_WATCH_HANGUP;

            if(flags != 0) dbus_watch_handle(watch, flags);

            c++;
        }
        JLN(pwatch, dbus->watches, index);
    }

    // dispatch incoming messages
    while((status = dbus_connection_get_dispatch_status(dbus->conn)) != DBUS_DISPATCH_COMPLETE) {
        dbus_connection_dispatch(dbus->conn);
    }

    // Send outgoing messages
    if(dbus_connection_has_messages_to_send(dbus->conn)) {
        dbus_connection_flush(dbus->conn);
    }

    return 0;
}
Ejemplo n.º 12
0
static void efl_dbus_dispatch_status(DBusConnection *connection,
				DBusDispatchStatus new_status, void *data)
{
	DBusDispatchStatus status;

	if (dbus_connection_get_is_connected(connection) == FALSE)
		return;

	status = dbus_connection_get_dispatch_status(connection);
	if (status == DBUS_DISPATCH_DATA_REMAINS)
		ecore_timer_add(0, efl_dispatch_dbus, connection);
}
Ejemplo n.º 13
0
dbus_bool_t
test_connection_setup (DBusLoop       *loop,
                       DBusConnection *connection)
{
  CData *cd;

  cd = NULL;
  
  dbus_connection_set_dispatch_status_function (connection, dispatch_status_function,
                                                loop, NULL);
  
  cd = cdata_new (loop, connection);
  if (cd == NULL)
    goto nomem;

  if (!dbus_connection_set_watch_functions (connection,
                                            add_watch,
                                            remove_watch,
                                            toggle_watch,
                                            cd, cdata_free))
    goto nomem;


  cd = cdata_new (loop, connection);
  if (cd == NULL)
    goto nomem;
  
  if (!dbus_connection_set_timeout_functions (connection,
                                              add_timeout,
                                              remove_timeout,
                                              NULL,
                                              cd, cdata_free))
    goto nomem;

  if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
    {
      if (!_dbus_loop_queue_dispatch (loop, connection))
        goto nomem;
    }
  
  return TRUE;
  
 nomem:
  if (cd)
    cdata_free (cd);
  
  dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
  dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, NULL, NULL);
  dbus_connection_set_timeout_functions (connection, NULL, NULL, NULL, NULL, NULL);
  
  return FALSE;
}
Ejemplo n.º 14
0
void asdbus_handleDispatches (){
#ifdef ASDBUS_DISPATCH
	void *data;
	while ((data = extract_first_bidirelem (ASDBus.dispatches)) != NULL){
		ASDBusDispatch *d = (ASDBusDispatch*)data;
		while (dbus_connection_get_dispatch_status(d->data) == DBUS_DISPATCH_DATA_REMAINS){
			dbus_connection_dispatch(d->data);
			show_debug(__FILE__,__FUNCTION__,__LINE__,"dispatching dbus  data=%p\n", d->data);
		}
		free (d);
	}
#endif
}
Ejemplo n.º 15
0
static void
wakeup_handler(void *data, int err, void *read_mask)
{
    struct dbus_core_info *info = data;

    if (info->connection && FD_ISSET(info->fd, (fd_set *) read_mask)) {
        do {
            dbus_connection_read_write_dispatch(info->connection, 0);
        } while (info->connection &&
                 dbus_connection_get_is_connected(info->connection) &&
                 dbus_connection_get_dispatch_status(info->connection) ==
                 DBUS_DISPATCH_DATA_REMAINS);
    }
}
Ejemplo n.º 16
0
/*
 * dbus notifications
 */
static void
_cs_dbus_auto_flush(void)
{
	dbus_connection_ref(db);
	while (dbus_connection_get_dispatch_status(db) == DBUS_DISPATCH_DATA_REMAINS) {
		dbus_connection_dispatch(db);
	}

	while (dbus_connection_has_messages_to_send(db)) {
		dbus_connection_flush(db);
	}

	dbus_connection_unref(db);
}
Ejemplo n.º 17
0
static void process_wakeup_main(int sig, void *eloop_ctx, void *signal_ctx)
{
	struct ctrl_iface_dbus_priv *iface = signal_ctx;

	if (sig != SIGPOLL || !iface->con)
		return;

	if (dbus_connection_get_dispatch_status(iface->con) !=
	    DBUS_DISPATCH_DATA_REMAINS)
		return;

	/* Only dispatch once - we do not want to starve other events */
	dbus_connection_ref(iface->con);
	dbus_connection_dispatch(iface->con);
	dbus_connection_unref(iface->con);
}
Ejemplo n.º 18
0
static void
block_hook_cb (hidval data) {
    DBusConnection *connection = (DBusConnection *) data.ptr;

    if (dbus_connection_get_dispatch_status (connection) !=
            DBUS_DISPATCH_DATA_REMAINS) {
        return;
    }

    // TODO: IS THIS NEEDED?
    // dbus_connection_ref (connection);
    /* Only dispatch once - we don't want to starve other mainloop users */
    dbus_connection_dispatch (connection);
    // dbus_connection_unref (connection);
    return;
}
Ejemplo n.º 19
0
static void
timeout_handler(EV_P_ struct ev_timer *ev, int revents)
{
	struct timeout *t = (struct timeout *)ev;

	(void)revents;

	lem_debug("timeout");

	(void)dbus_timeout_handle(t->timeout);

	if (dbus_connection_get_dispatch_status(t->conn)
	    == DBUS_DISPATCH_DATA_REMAINS) {
		while (dbus_connection_dispatch(t->conn)
		       == DBUS_DISPATCH_DATA_REMAINS);
	}
}
Ejemplo n.º 20
0
static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	DBusWatch *watch = data;
	struct watch_info *info = dbus_watch_get_data(watch);
	int flags = 0;

	if (cond & G_IO_IN)  flags |= DBUS_WATCH_READABLE;
	if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
	if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
	if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;

	dbus_watch_handle(watch, flags);

	if (dbus_connection_get_dispatch_status(info->conn) == DBUS_DISPATCH_DATA_REMAINS)
		g_timeout_add(DISPATCH_TIMEOUT, message_dispatch_cb, info->conn);

	return TRUE;
}
Ejemplo n.º 21
0
static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct watch_info *info = data;
	unsigned int flags = 0;
	DBusDispatchStatus status;

	if (cond & G_IO_IN)  flags |= DBUS_WATCH_READABLE;
	if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
	if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
	if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;

	dbus_watch_handle(info->watch, flags);

	status = dbus_connection_get_dispatch_status(info->conn);
	queue_dispatch(info->conn, status);

	return TRUE;
}
Ejemplo n.º 22
0
int avahi_dbus_connection_glue(DBusConnection *c, const AvahiPoll *poll_api) {
    ConnectionData *d = NULL;

    assert(c);
    assert(poll_api);

    if (!(d = avahi_new(ConnectionData, 1)))
        goto fail;;

    d->poll_api = poll_api;
    d->connection = c;
    d->ref = 1;

    if (!(d->dispatch_timeout = poll_api->timeout_new(poll_api, NULL, dispatch_timeout_callback, d)))
        goto fail;

    if (!(dbus_connection_set_watch_functions(c, add_watch, remove_watch, watch_toggled, connection_data_ref(d), (DBusFreeFunction)connection_data_unref)))
        goto fail;

    if (!(dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, timeout_toggled, connection_data_ref(d), (DBusFreeFunction)connection_data_unref)))
        goto fail;

    dbus_connection_set_dispatch_status_function(c, dispatch_status, connection_data_ref(d), (DBusFreeFunction)connection_data_unref);

    if (dbus_connection_get_dispatch_status(c) == DBUS_DISPATCH_DATA_REMAINS)
        request_dispatch(d, 1);

    connection_data_unref(d);

    return 0;

fail:

    if (d) {
        d->poll_api->timeout_free(d->dispatch_timeout);

        avahi_free(d);
    }

    return -1;
}
Ejemplo n.º 23
0
Bool asdbus_init ()
{																/* return connection unix fd */
	char *tmp;
#ifdef ASDBUS_DISPATCH
	if (!ASDBus.dispatches)
		ASDBus.dispatches = create_asbidirlist(asdbus_dispatch_destroy);
#endif
	if (!ASDBus.session_conn) {
		ASDBus.session_conn = _asdbus_get_session_connection();
		if (!dbus_connection_set_watch_functions(ASDBus.session_conn, add_watch, remove_watch,  toggle_watch, ASDBus.session_conn, NULL)) {
		 	show_error("dbus_connection_set_watch_functions() failed");
		}
		_asdbus_add_match (ASDBus.session_conn,  SESSIONMANAGER_INTERFACE, NULL);
		//_asdbus_add_match (ASDBus.session_conn,  IFACE_SESSION_PRIVATE, "QueryEndSession");
		//_asdbus_add_match (ASDBus.session_conn,  IFACE_SESSION_PRIVATE, "EndSession");
		//_asdbus_add_match (ASDBus.session_conn,  IFACE_SESSION_PRIVATE, "Stop");
		dbus_connection_set_timeout_functions(ASDBus.session_conn, add_timeout, remove_timeout, toggle_timeout, NULL, NULL);
#ifdef ASDBUS_DISPATCH
		dbus_connection_set_dispatch_status_function(ASDBus.session_conn, queue_dispatch, NULL, NULL);
		queue_dispatch(ASDBus.session_conn, dbus_connection_get_dispatch_status(ASDBus.session_conn), NULL);
#endif
	}

	if (!ASDBus.system_conn){
		ASDBus.system_conn = _asdbus_get_system_connection();
		/*if (!dbus_connection_set_watch_functions(ASDBus.system_conn, add_watch, remove_watch,  toggle_watch, ASDBus.system_conn, NULL)) {
		 	show_error("dbus_connection_set_watch_functions() failed");
		}*/
	}

	/*if (ASDBus.session_conn && ASDBus.watchFds == NULL){
		//dbus_connection_get_unix_fd (ASDBus.session_conn, &(ASDBus.watch_fd));
		//dbus_whatch_get_unix_fd (ASDBus.session_conn, &(ASDBus.watch_fd));
	}*/

	if ((tmp = getenv ("KDE_SESSION_VERSION")) != NULL)
		ASDBus.kdeSessionVersion = atoi(tmp);

	return (ASDBus.session_conn != NULL);
}
Ejemplo n.º 24
0
static void process_watch(struct ctrl_iface_dbus_priv *iface,
			  DBusWatch *watch, eloop_event_type type)
{
	dbus_connection_ref(iface->con);

	iface->should_dispatch = 0;

	if (type == EVENT_TYPE_READ)
		dbus_watch_handle(watch, DBUS_WATCH_READABLE);
	else if (type == EVENT_TYPE_WRITE)
		dbus_watch_handle(watch, DBUS_WATCH_WRITABLE);
	else if (type == EVENT_TYPE_EXCEPTION)
		dbus_watch_handle(watch, DBUS_WATCH_ERROR);

	if (iface->should_dispatch) {
		while (dbus_connection_get_dispatch_status(iface->con) ==
		       DBUS_DISPATCH_DATA_REMAINS)
			dbus_connection_dispatch(iface->con);
		iface->should_dispatch = 0;
	}

	dbus_connection_unref(iface->con);
}
Ejemplo n.º 25
0
static dbus_bool_t setup_dbus_in_efl_mainloop(DBusConnection *dbus_cnx)
{
	DBusDispatchStatus status;

	if (dbus_connection_set_watch_functions(dbus_cnx,
			efl_dbus_watch_add, efl_dbus_watch_remove,
			efl_dbus_watch_toggled, dbus_cnx, NULL) == FALSE)
		return FALSE;

	if (dbus_connection_set_timeout_functions(dbus_cnx,
			efl_dbus_timeout_add, efl_dbus_timeout_remove,
			efl_dbus_timeout_toggled, dbus_cnx, NULL) == FALSE)
		return FALSE;

	dbus_connection_set_dispatch_status_function(dbus_cnx,
			efl_dbus_dispatch_status, dbus_cnx, NULL);

	status = dbus_connection_get_dispatch_status(dbus_cnx);
	if (status == DBUS_DISPATCH_DATA_REMAINS)
		ecore_timer_add(0, efl_dispatch_dbus, dbus_cnx);

	return TRUE;
}
Ejemplo n.º 26
0
static void
watch_handler(EV_P_ struct ev_io *ev, int revents)
{
	struct watch *w = (struct watch *)ev;
	unsigned int flags = 0;

	if (revents & EV_READ)
		flags |= DBUS_WATCH_READABLE;
	if (revents & EV_WRITE)
		flags |= DBUS_WATCH_WRITABLE;
	if (revents & EV_ERROR)
		flags |= DBUS_WATCH_ERROR;

	lem_debug("flags = %s", flags & DBUS_WATCH_ERROR ? "ERROR" :
	                        flags & DBUS_WATCH_READABLE ? "READ" : "WRITE");

	(void)dbus_watch_handle(w->watch, flags);

	if (dbus_connection_get_dispatch_status(w->conn)
	    == DBUS_DISPATCH_DATA_REMAINS) {
		while (dbus_connection_dispatch(w->conn)
		       == DBUS_DISPATCH_DATA_REMAINS);
	}
}
Ejemplo n.º 27
0
void DBus_SetupProc(ClientData data, int flags)
{
   Tcl_Time blockTime;
   DBusDispatchStatus status;
   Tcl_HashEntry *hPtr;
   Tcl_HashSearch search;
   Tcl_DBusBus *dbus;
   
   blockTime.sec = 0;
   blockTime.usec = 100000;
   /* Check the incoming message queues */
   for (hPtr = Tcl_FirstHashEntry(&bus, &search); hPtr != NULL;
	hPtr = Tcl_NextHashEntry(&search)) {
      dbus = (Tcl_DBusBus *) Tcl_GetHashValue(hPtr);
      dbus_connection_read_write(dbus->conn, 0);
      status = dbus_connection_get_dispatch_status(dbus->conn);
      if (status == DBUS_DISPATCH_DATA_REMAINS) {
	 blockTime.sec = 0;
	 blockTime.usec = 0;
	 break;
      }
   }
   Tcl_SetMaxBlockTime(&blockTime);
}
Ejemplo n.º 28
0
static void dispatch_data(DBusConnection *con)
{
	while (dbus_connection_get_dispatch_status(con) ==
	       DBUS_DISPATCH_DATA_REMAINS)
		dbus_connection_dispatch(con);
}
Ejemplo n.º 29
0
wxThread::ExitCode DBusThread::Entry()
{
	while (!m_exit) {

		EnterCriticalSection();

		while (dbus_connection_get_dispatch_status(m_connection) == DBUS_DISPATCH_DATA_REMAINS)
			dbus_connection_dispatch(m_connection);

		// Prepare list of file descriptors to pull
		struct pollfd *fd_array = new struct pollfd[bus_watches.size() + 1];

		fd_array[0].fd = m_wakeup_pipe[0];
		fd_array[0].events = POLLIN;

		unsigned int nfds = 1;
		for (auto it = bus_watches.begin(); it != bus_watches.end(); ++it) {
			if (dbus_watch_get_enabled(*it))
			{
#if WITH_LIBDBUS >= 2
				fd_array[nfds].fd = dbus_watch_get_unix_fd(*it);
#else
				fd_array[nfds].fd = dbus_watch_get_fd(*it);
#endif
				int flags = dbus_watch_get_flags(*it);
				fd_array[nfds].events = POLLHUP | POLLERR;
				if (flags & DBUS_WATCH_READABLE)
					fd_array[nfds].events |= POLLIN;
				if (flags & DBUS_WATCH_WRITABLE)
					fd_array[nfds].events |= POLLOUT;
				++nfds;
			}
		}
		LeaveCriticalSection();

		if (poll(fd_array, nfds, -1) > 0) {

			EnterCriticalSection();
			m_thread_holds_lock = true;

			char tmp;
			if (read(m_wakeup_pipe[0], &tmp, 1) == 1) {
				m_thread_holds_lock = false;
				LeaveCriticalSection();
				delete [] fd_array;
				continue;
			}

			for (auto it = bus_watches.begin(); it != bus_watches.end(); ++it) {
				if (!dbus_watch_get_enabled(*it))
					continue;
#if WITH_LIBDBUS >= 2
				int fd = dbus_watch_get_unix_fd(*it);
#else
				int fd = dbus_watch_get_fd(*it);
#endif
				unsigned int i;
				for (i = 1; i < nfds; ++i) {
					if (fd_array[i].fd == fd && fd_array[i].revents) {
						int flags = 0;
						if (fd_array[i].revents & POLLIN)
							flags |= DBUS_WATCH_READABLE;
						if (fd_array[i].revents & POLLOUT)
							flags |= DBUS_WATCH_WRITABLE;
						if (fd_array[i].revents & POLLERR)
							flags |= DBUS_WATCH_ERROR;
						if (fd_array[i].revents & POLLHUP)
							flags |= DBUS_WATCH_HANGUP;
						dbus_watch_handle(*it, flags);
						break;
					}
				}

				// Only handle a single watch in each poll iteration, bus_watches could change inside dbus_watch_handle
				if (i != nfds)
					break;
			}
			m_thread_holds_lock = false;
			LeaveCriticalSection();
		}

		delete [] fd_array;
	}

	return 0;
}
Ejemplo n.º 30
0
int tool_cmd_scan(int argc, char *argv[])
{
	int ret = 0;
	int c;
	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusPendingCall *pending = NULL;
	DBusError error;
	int32_t scan_period = 0;
	uint32_t channel_mask = 0;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{"channel", required_argument, 0, 'c'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "hc:t:", long_options,
				&option_index);

		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_arg_list_help(scan_option_list, argv[0],
					    scan_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;

		case 'c':
			channel_mask = strtomask_uint32(optarg);
			break;
		}
	}

	if (optind < argc) {
		if (scan_period == 0) {
			scan_period = strtol(argv[optind], NULL, 0);
			optind++;
		}
	}

	if (optind < argc) {
			fprintf(stderr,
			        "%s: error: Unexpected extra argument: \"%s\"\n",
			argv[0], argv[optind]);
			ret = ERRORCODE_BADARG;
			goto bail;
		}

	if (gInterfaceName[0] == 0) {
		fprintf(stderr,
		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
		        argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);

	if (!connection) {
		dbus_error_free(&error);
		dbus_error_init(&error);
		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
	}

	require_string(connection != NULL, bail, error.message);

	dbus_bus_add_match(connection, gDBusObjectManagerMatchString, &error);

	require_string(error.name == NULL, bail, error.message);

	dbus_connection_add_filter(connection, &dbus_beacon_handler, NULL, NULL);

	{
		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
		DBusMessageIter iter;
		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);

		if (ret != 0) {
			goto bail;
		}

		snprintf(
			path,
			sizeof(path),
			"%s/%s",
			WPANTUND_DBUS_PATH,
			gInterfaceName
		);

		message = dbus_message_new_method_call(
			interface_dbus_name,
			path,
			WPANTUND_DBUS_APIv1_INTERFACE,
			WPANTUND_IF_CMD_NET_SCAN_START
		);

		dbus_message_append_args(
			message,
			DBUS_TYPE_UINT32, &channel_mask,
			DBUS_TYPE_INVALID
		);

		print_scan_header();

		gScannedNetworkCount = 0;

		if(!dbus_connection_send_with_reply(
		    connection,
		    message,
			&pending,
		    timeout
	    )) {
			fprintf(stderr, "%s: error: IPC failure\n", argv[0]);
			ret = ERRORCODE_UNKNOWN;
			goto bail;
		}

		while ((dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS)
			|| dbus_connection_has_messages_to_send(connection)
			|| !dbus_pending_call_get_completed(pending)
		) {
			dbus_connection_read_write_dispatch(connection, 5000 /*ms*/);
		}

		reply = dbus_pending_call_steal_reply(pending);

		require(reply!=NULL, bail);


		dbus_message_iter_init(reply, &iter);

		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
			fprintf(stderr, "%s: error: Server returned a bad response ('%c')\n",
			        argv[0], dbus_message_iter_get_arg_type(&iter));
			ret = ERRORCODE_UNKNOWN;
			goto bail;
		}

		// Get return code
		dbus_message_iter_get_basic(&iter, &ret);

		if (ret) {
			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
			print_error_diagnosis(ret);
			goto bail;
		}
	}


bail:

	if (reply) {
		dbus_message_unref(reply);
	}

	if (pending != NULL) {
		dbus_pending_call_unref(pending);
	}

	if (message) {
		dbus_message_unref(message);
	}

	if (connection) {
		dbus_bus_remove_match(connection, gDBusObjectManagerMatchString, NULL);
		dbus_connection_remove_filter(connection,&dbus_beacon_handler,NULL);
		dbus_connection_unref(connection);
	}

	dbus_error_free(&error);

	return ret;
}