Пример #1
0
void check_dbus_listeners(struct daemon *daemon,
			  fd_set *rset, fd_set *wset, fd_set *eset)
{
  DBusConnection *connection = (DBusConnection *)daemon->dbus;
  struct watch *w;

  for (w = daemon->watches; w; w = w->next)
    if (dbus_watch_get_enabled(w->watch))
      {
	unsigned int flags = 0;
	int fd = dbus_watch_get_fd(w->watch);
	
	if (FD_ISSET(fd, rset))
	  flags |= DBUS_WATCH_READABLE;
	
	if (FD_ISSET(fd, wset))
	  flags |= DBUS_WATCH_WRITABLE;
	
	if (FD_ISSET(fd, eset))
	  flags |= DBUS_WATCH_ERROR;

	if (flags != 0)
	  dbus_watch_handle(w->watch, flags);
      }

  if (connection)
    {
      dbus_connection_ref (connection);
      while (dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS);
      dbus_connection_unref (connection);
    }
}
Пример #2
0
static dbus_bool_t
handle_watch (DBusWatch       *watch,
              unsigned int     condition,
              void            *data)
{
  DBusBabysitter *sitter = data;
  int revents;
  int fd;
  
  revents = 0;
  if (condition & DBUS_WATCH_READABLE)
    revents |= _DBUS_POLLIN;
  if (condition & DBUS_WATCH_ERROR)
    revents |= _DBUS_POLLERR;
  if (condition & DBUS_WATCH_HANGUP)
    revents |= _DBUS_POLLHUP;

  fd = dbus_watch_get_fd (watch);

  if (fd == sitter->error_pipe_from_child)
    handle_error_pipe (sitter, revents);
  else if (fd == sitter->socket_to_babysitter)
    handle_babysitter_socket (sitter, revents);

  while (LIVE_CHILDREN (sitter) &&
         babysitter_iteration (sitter, FALSE))
    ;
  
  return TRUE;
}
Пример #3
0
static void read_watch_cb(int fd, void* d) { 
	/* E_DEBUG(E_STRLOC ": read_watch_cb()\n"); */

	EdbusConnImpl* dc = (EdbusConnImpl*)d;
	E_ASSERT(dc != NULL);
	E_ASSERT(dc->watch_list != NULL);

	WatchListIter it = dc->watch_list->begin(), it_end = dc->watch_list->end();
	while(it != it_end) {
		if(dbus_watch_get_fd(*it) == fd && dbus_watch_get_enabled(*it)) {
			if(!dbus_watch_handle(*it, DBUS_WATCH_READABLE))
				E_WARNING(E_STRLOC ": Out of memory\n");
			break;
		}
		++it;
	}

	/*
	 * Check if there are more incomming data and process them. Note that 
	 * dbus_connection_dispatch() call will also remove data from queue. 
	 * This means that (here) timer will not be installed if only one unprocessed
	 * message is in queue; opposite, after installment it will process the rest
	 * of the messages without interrupting read_watch_cb() flow.
	 *
	 * If this is not set (e.g. all data are processed here), we can miss initial
	 * (or later) messages that are sent to us. Also, timer will be triggered faster
	 * as it can (seems that 0.5 as timer value misses some data...).
	 */
	if(dbus_connection_dispatch(dc->conn) == DBUS_DISPATCH_DATA_REMAINS)
		Fl::add_timeout(0.2, dispatch_cb, dc);
}
static void connection_setup_add_watch(struct ctrl_iface_dbus_priv *iface,
				       DBusWatch *watch)
{
	unsigned int flags;
	int fd;

	if (!dbus_watch_get_enabled(watch))
		return;

	flags = dbus_watch_get_flags(watch);
	fd = dbus_watch_get_fd(watch);

	eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception,
			    iface, watch);

	if (flags & DBUS_WATCH_READABLE) {
		eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read,
				    iface, watch);
	}
	if (flags & DBUS_WATCH_WRITABLE) {
		eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write,
				    iface, watch);
	}

	dbus_watch_set_data(watch, iface, NULL);
}
Пример #5
0
static dbus_bool_t virDBusAddWatch(DBusWatch *watch,
                                   void *data)
{
    int flags = 0;
    int fd;
    struct virDBusWatch *info;

    if (VIR_ALLOC(info) < 0)
        return 0;

    if (dbus_watch_get_enabled(watch))
        flags = virDBusTranslateWatchFlags(dbus_watch_get_flags(watch));

# if HAVE_DBUS_WATCH_GET_UNIX_FD
    fd = dbus_watch_get_unix_fd(watch);
# else
    fd = dbus_watch_get_fd(watch);
# endif
    info->bus = (DBusConnection *)data;
    info->watch = virEventAddHandle(fd, flags,
                                    virDBusWatchCallback,
                                    watch, NULL);
    if (info->watch < 0) {
        VIR_FREE(info);
        return 0;
    }
    dbus_watch_set_data(watch, info, virDBusWatchFree);

    return 1;
}
Пример #6
0
/*
 * add_watch
 * Set up hooks into the libevents mainloop for
 * D-BUS to add file descriptor-based events
 */
dbus_bool_t sbus_add_watch(DBusWatch *dbus_watch, void *data)
{
    unsigned int flags;
    uint16_t event_flags;
    struct sbus_connection *conn;
    struct sbus_watch_ctx *watch;
    dbus_bool_t enabled;
    int fd;

    conn = talloc_get_type(data, struct sbus_connection);

#ifdef HAVE_DBUS_WATCH_GET_UNIX_FD
    fd = dbus_watch_get_unix_fd(dbus_watch);
#else
    fd = dbus_watch_get_fd(dbus_watch);
#endif

    watch = fd_to_watch(conn->watch_list, fd);
    if (!watch) {
        /* does not exist, allocate new one */
        watch = talloc_zero(conn, struct sbus_watch_ctx);
        if (!watch) {
            DEBUG(0, ("Out of Memory!\n"));
            return FALSE;
        }
        watch->conn = conn;
        watch->fd = fd;
    }
Пример #7
0
/* pa_io_event_cb_t IO event handler */
static void handle_io_event(pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
    unsigned int flags = 0;
    DBusWatch *watch = userdata;

#if HAVE_DBUS_WATCH_GET_UNIX_FD
    pa_assert(fd == dbus_watch_get_unix_fd(watch));
#else
    pa_assert(fd == dbus_watch_get_fd(watch));
#endif

    if (!dbus_watch_get_enabled(watch)) {
        pa_log_warn("Asked to handle disabled watch: %p %i", (void*) watch, fd);
        return;
    }

    if (events & PA_IO_EVENT_INPUT)
        flags |= DBUS_WATCH_READABLE;
    if (events & PA_IO_EVENT_OUTPUT)
        flags |= DBUS_WATCH_WRITABLE;
    if (events & PA_IO_EVENT_HANGUP)
        flags |= DBUS_WATCH_HANGUP;
    if (events & PA_IO_EVENT_ERROR)
        flags |= DBUS_WATCH_ERROR;

    dbus_watch_handle(watch, flags);
}
Пример #8
0
void set_dbus_listeners(int *maxfdp,
			fd_set *rset, fd_set *wset, fd_set *eset)
{
  struct watch *w;
  
  for (w = daemon->watches; w; w = w->next)
    if (dbus_watch_get_enabled(w->watch))
      {
	unsigned int flags = dbus_watch_get_flags(w->watch);
#if (DBUS_MINOR > 0)
	int fd = dbus_watch_get_unix_fd(w->watch);
#else
	int fd = dbus_watch_get_fd(w->watch);
#endif
	
	bump_maxfd(fd, maxfdp);
	
	if (flags & DBUS_WATCH_READABLE)
	  FD_SET(fd, rset);
	
	if (flags & DBUS_WATCH_WRITABLE)
	  FD_SET(fd, wset);
	
	FD_SET(fd, eset);
      }
}
Пример #9
0
static void edbus_remove_watch(DBusWatch* watch, void* d) {
	E_ASSERT(watch != NULL);

	EdbusConnImpl* dc = (EdbusConnImpl*)d;
	E_ASSERT(dc != NULL);
	E_ASSERT(dc->watch_list != NULL);

	/* E_DEBUG(E_STRLOC ": removing watch\n"); */

	int fd = dbus_watch_get_fd(watch);
	int flags = dbus_watch_get_flags(watch);

	if(flags & DBUS_WATCH_READABLE)
		Fl::remove_fd(fd, FL_READ);

	if(flags & DBUS_WATCH_WRITABLE)
		Fl::remove_fd(fd, FL_WRITE);

	WatchListIter it = dc->watch_list->begin(), it_end = dc->watch_list->end();
	while(it != it_end) {
		if(*it == watch) {
			dc->watch_list->erase(it);
			break;
		}
		++it;
	}
}
Пример #10
0
static dbus_bool_t edbus_add_watch(DBusWatch* watch, void* d) {
	E_ASSERT(watch != NULL);

	/* 
	 * check if watch is enabled since dbus_watch_handle() can't be used
	 * on as connection will not be ready to handle this watch yet
	 */
 	if(!dbus_watch_get_enabled(watch))
		return 1;

	EdbusConnImpl* dc = (EdbusConnImpl*)d;
	E_ASSERT(dc != NULL);
	E_ASSERT(dc->watch_list != NULL);

	int fd = dbus_watch_get_fd(watch);
	int flags = dbus_watch_get_flags(watch);

	dc->watch_list->push_back(watch);

	if(flags & DBUS_WATCH_READABLE)
		Fl::add_fd(fd, FL_READ, read_watch_cb, d);

	if(flags & DBUS_WATCH_WRITABLE)
		Fl::add_fd(fd, FL_WRITE, write_watch_cb, d);

	return 1;
}
/**
 * Handles a watch by reading data, writing data, or disconnecting
 * the transport, as appropriate for the given condition.
 *
 * @param transport the transport.
 * @param watch the watch.
 * @param condition the current state of the watched file descriptor.
 * @returns #FALSE if not enough memory to fully handle the watch
 */
dbus_bool_t
_dbus_transport_handle_watch (DBusTransport           *transport,
                              DBusWatch               *watch,
                              unsigned int             condition)
{
  dbus_bool_t retval;
  
  _dbus_assert (transport->vtable->handle_watch != NULL);

  if (transport->disconnected)
    return TRUE;

  if (dbus_watch_get_fd (watch) < 0)
    {
      _dbus_warn ("Tried to handle an invalidated watch; this watch should have been removed\n");
      return TRUE;
    }
  
  _dbus_watch_sanitize_condition (watch, &condition);

  _dbus_transport_ref (transport);
  _dbus_watch_ref (watch);
  retval = (* transport->vtable->handle_watch) (transport, watch, condition);
  _dbus_watch_unref (watch);
  _dbus_transport_unref (transport);

  return retval;
}
Пример #12
0
static void MainLoop() {
  struct ConnectionData* c = (struct ConnectionData*) FindTask(NULL)->tc_UserData;
  kprintf("MainLoop started %08lx (cd %08lx)\n", FindTask(NULL), c);

  c->signal = AllocSignal(-1);

  if (c->signal == -1) {
    goto exit;
  }
  
  Signal(c->creator, SIGF_SINGLE);
  
  while(TRUE) {
    ULONG signals = Wait(SIGBREAKF_CTRL_C | (1UL << c->signal));

    kprintf("MainLoop got a signal %lx\n", signals);

    if (signals & SIGBREAKF_CTRL_C) {
      break;
    }

    if (signals & (1UL << c->signal)) {
      struct WatchData* w;
      
//      dbus_connection_ref(c->connection);

      kprintf("Checking watches\n");
      for(w = (struct WatchData*) c->watches.mlh_Head;
	  w->node.mln_Succ != NULL;
	  w = (struct WatchData*) w->node.mln_Succ) {
	kprintf("%s watch on fd %ld, flags %lx\n",
		w->enabled ? "Enabled" : "Disabled",
		dbus_watch_get_fd(w->watch), dbus_watch_get_flags(w->watch));
	if (w->enabled) {
	  dbus_watch_handle(w->watch, dbus_watch_get_flags(w->watch));
	}
      }
      
      kprintf("Dispatching messages\n");
      /* Dispatch messages */
      while (dbus_connection_dispatch(c->connection) == DBUS_DISPATCH_DATA_REMAINS) {
	kprintf("More messages available\n");
      }

//      dbus_connection_unref(c->connection);
    }
  }

exit:
  c->main = NULL;
  Signal(c->creator, SIGF_SINGLE);
  kprintf("MainLoop terminating\n");
}
void Integrator::addWatch( DBusWatch *watch )
{
  if ( !dbus_watch_get_enabled( watch ) )
    return;

  Watch *qtwatch = new Watch;
  qtwatch->watch = watch;

  int flags = dbus_watch_get_flags( watch );
  int fd = dbus_watch_get_fd( watch );

  if ( flags & DBUS_WATCH_READABLE ) {
    qtwatch->readSocket = new QSocketNotifier( fd, QSocketNotifier::Read, this );
    QObject::connect( qtwatch->readSocket, SIGNAL(activated(int)), SLOT(slotRead(int)) );
  }
Пример #14
0
bool EdbusConnection::disconnect(void) {
	/* only non-shared connections are allowed to be closed */
	if(dc->conn)
		dbus_connection_unref(dc->conn);

	dc->conn = NULL;

	/* TODO: does this needs to be nulled ? */
	dc->signal_cb = NULL;
	dc->signal_cb_data = NULL;

	dc->method_call_cb = NULL;
	dc->method_call_cb_data = NULL;

	dc->object_list.clear();

	dc->signal_table = NULL;
	dc->signal_table_sz = 0;

	dc->method_table = NULL;
	dc->method_table_sz = 0;

	dc->signal_matches = dc->method_matches = 0;

	/* remove all FLTK notifiers so we can reuse EdbusConnection object again */
	if(dc->watch_list) {
		int fd;
		WatchListIter it = dc->watch_list->begin(), it_end = dc->watch_list->end();

		while(it != it_end) {
			fd = dbus_watch_get_fd(*it);
			Fl::remove_fd(fd);
			++it;
		}

		dc->watch_list->clear();
		delete dc->watch_list;
		dc->watch_list = NULL;
	}

	if(dc->timeout) {
		Fl::remove_timeout(timeout_cb);
		dc->timeout = NULL;
	}

	return true;
}
Пример #15
0
static void write_watch_cb(int fd, void* d) { 
	/* E_DEBUG(E_STRLOC ": write_watch_cb()\n"); */

	EdbusConnImpl* dc = (EdbusConnImpl*)d;
	E_ASSERT(dc != NULL);
	E_ASSERT(dc->watch_list != NULL);

	WatchListIter it = dc->watch_list->begin(), it_end = dc->watch_list->end();
	while(it != it_end) { 
		if(dbus_watch_get_fd(*it) == fd && dbus_watch_get_enabled(*it)) {
			if(!dbus_watch_handle(*it, DBUS_WATCH_WRITABLE))
				E_WARNING(E_STRLOC ": Out of memory\n");
			break;
		}
		++it;
	}
}
static void connection_setup_remove_watch(struct ctrl_iface_dbus_priv *iface,
					  DBusWatch *watch)
{
	unsigned int flags;
	int fd;

	flags = dbus_watch_get_flags(watch);
	fd = dbus_watch_get_fd(watch);

	eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION);

	if (flags & DBUS_WATCH_READABLE)
		eloop_unregister_sock(fd, EVENT_TYPE_READ);
	if (flags & DBUS_WATCH_WRITABLE)
		eloop_unregister_sock(fd, EVENT_TYPE_WRITE);

	dbus_watch_set_data(watch, NULL, NULL);
}
Пример #17
0
/* DBusAddWatchFunction callback for pa mainloop */
static dbus_bool_t add_watch(DBusWatch *watch, void *data) {
    pa_dbus_wrap_connection *c = data;
    pa_io_event *ev;

    pa_assert(watch);
    pa_assert(c);

    ev = c->mainloop->io_new(
            c->mainloop,
#if HAVE_DBUS_WATCH_GET_UNIX_FD
            dbus_watch_get_unix_fd(watch),
#else
            dbus_watch_get_fd(watch),
#endif
            get_watch_flags(watch), handle_io_event, watch);

    dbus_watch_set_data(watch, ev, NULL);

    return TRUE;
}
Пример #18
0
static dbus_bool_t update_watch(const AvahiPoll *poll_api, DBusWatch *dbus_watch) {
    AvahiWatch *avahi_watch;
    dbus_bool_t b;

    assert(dbus_watch);

    avahi_watch = dbus_watch_get_data(dbus_watch);

    b = dbus_watch_get_enabled(dbus_watch);

    if (b && !avahi_watch) {

        if (!(avahi_watch = poll_api->watch_new(
                  poll_api,
#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR > 1) || (DBUS_VERSION_MAJOR > 1)
                  dbus_watch_get_unix_fd(dbus_watch),
#else
                  dbus_watch_get_fd(dbus_watch),
#endif
                  translate_dbus_to_avahi(dbus_watch_get_flags(dbus_watch)),
                  watch_callback,
                  dbus_watch)))
            return FALSE;

        dbus_watch_set_data(dbus_watch, avahi_watch, NULL);

    } else if (!b && avahi_watch) {

        poll_api->watch_free(avahi_watch);
        dbus_watch_set_data(dbus_watch, NULL, NULL);

    } else if (avahi_watch) {

        /* Update flags */
        poll_api->watch_update(avahi_watch, dbus_watch_get_flags(dbus_watch));
    }

    return TRUE;
}
Пример #19
0
dbus_bool_t add_watch(DBusWatch *watch, void *data)
{
	GIOCondition cond = G_IO_HUP | G_IO_ERR;
	GIOChannel *io;
	guint id;
	int fd, flags;

	if (!dbus_watch_get_enabled(watch))
		return TRUE;

	fd = dbus_watch_get_fd(watch);
	io = g_io_channel_unix_new(fd);
	flags = dbus_watch_get_flags(watch);

	if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN;
	if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT;

	id = g_io_add_watch(io, cond, watch_func, watch);

	dbus_watch_set_data(watch, (void *) id, NULL);

	return TRUE;
}
Пример #20
0
static dbus_bool_t
watch_add (DBusWatch * dbus_watch, void *data) {
    IOWatchHandler *handler;
    int fd;
    unsigned int pcb_condition;
    unsigned int dbus_flags;
    hidval temp;

    // We won't create a watch until it becomes enabled.
    if (!dbus_watch_get_enabled (dbus_watch)) {
        return TRUE;
    }

    dbus_flags = dbus_watch_get_flags (dbus_watch);
    pcb_condition = PCB_WATCH_ERROR | PCB_WATCH_HANGUP;

    if (dbus_flags & DBUS_WATCH_READABLE) {
        pcb_condition |= PCB_WATCH_READABLE;
    }

    if (dbus_flags & DBUS_WATCH_WRITABLE) {
        pcb_condition |= PCB_WATCH_READABLE;
    }

#if HAVE_DBUS_WATCH_GET_UNIX_FD
    fd = dbus_watch_get_unix_fd (dbus_watch);
#else
    fd = dbus_watch_get_fd (dbus_watch);
#endif
    handler = (IOWatchHandler *)malloc (sizeof (IOWatchHandler));
    temp.ptr = (void *)handler;
    handler->dbus_watch = dbus_watch;
    handler->pcb_watch =
        gui->watch_file (fd, pcb_condition, io_watch_handler_cb, temp);
    dbus_watch_set_data (dbus_watch, handler, io_watch_handler_dbus_freed);
    return TRUE;
}
Пример #21
0
static dbus_bool_t
AddWatch(DBusWatch *aWatch, void *aData)
{
  DBusThread *dbt = (DBusThread *)aData;

  if (dbus_watch_get_enabled(aWatch)) {
    // note that we can't just send the watch and inspect it later
    // because we may get a removeWatch call before this data is reacted
    // to by our eventloop and remove this watch..  reading the add first
    // and then inspecting the recently deceased watch would be bad.
    char control = DBUS_EVENT_LOOP_ADD;
    if (write(dbt->mControlFdW.get(), &control, sizeof(char)) < 0) {
      LOG("Cannot write DBus add watch control data to socket!\n");
      return false;
    }

    // TODO change this to dbus_watch_get_unix_fd once we move to ics
    int fd = dbus_watch_get_fd(aWatch);
    if (write(dbt->mControlFdW.get(), &fd, sizeof(int)) < 0) {
      LOG("Cannot write DBus add watch descriptor data to socket!\n");
      return false;
    }

    unsigned int flags = dbus_watch_get_flags(aWatch);
    if (write(dbt->mControlFdW.get(), &flags, sizeof(unsigned int)) < 0) {
      LOG("Cannot write DBus add watch flag data to socket!\n");
      return false;
    }

    if (write(dbt->mControlFdW.get(), &aWatch, sizeof(DBusWatch*)) < 0) {
      LOG("Cannot write DBus add watch struct data to socket!\n");
      return false;
    }
  }
  return true;
}
Пример #22
0
static void
RemoveWatch(DBusWatch *aWatch, void *aData)
{
  DBusThread *dbt = (DBusThread *)aData;

  char control = DBUS_EVENT_LOOP_REMOVE;
  if (write(dbt->mControlFdW.get(), &control, sizeof(char)) < 0) {
    LOG("Cannot write DBus remove watch control data to socket!\n");
    return;
  }

  // TODO change this to dbus_watch_get_unix_fd once we move to ics
  int fd = dbus_watch_get_fd(aWatch);
  if (write(dbt->mControlFdW.get(), &fd, sizeof(int)) < 0) {
    LOG("Cannot write DBus remove watch descriptor data to socket!\n");
    return;
  }

  unsigned int flags = dbus_watch_get_flags(aWatch);
  if (write(dbt->mControlFdW.get(), &flags, sizeof(unsigned int)) < 0) {
    LOG("Cannot write DBus remove watch flag data to socket!\n");
    return;
  }
}
Пример #23
0
int set_dbus_listeners(struct daemon *daemon, int maxfd,
		       fd_set *rset, fd_set *wset, fd_set *eset)
{
  struct watch *w;
  
  for (w = daemon->watches; w; w = w->next)
    if (dbus_watch_get_enabled(w->watch))
      {
	unsigned int flags = dbus_watch_get_flags(w->watch);
	int fd = dbus_watch_get_fd(w->watch);
	
	if (fd > maxfd)
	  maxfd = fd;
	
	if (flags & DBUS_WATCH_READABLE)
	  FD_SET(fd, rset);
	
	if (flags & DBUS_WATCH_WRITABLE)
	  FD_SET(fd, wset);
	
	FD_SET(fd, eset);
      }
  return maxfd;
}
Пример #24
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;
}