示例#1
0
/** @private */
SR_PRIV int serial_source_add(struct sr_session *session,
		struct sr_serial_dev_inst *serial, int events, int timeout,
		sr_receive_data_callback cb, void *cb_data)
{
	struct sp_event_set *event_set;
	gintptr poll_fd;
	unsigned int poll_events;
	enum sp_event mask = 0;

	if ((events & (G_IO_IN|G_IO_ERR)) && (events & G_IO_OUT)) {
		sr_err("Cannot poll input/error and output simultaneously.");
		return SR_ERR_ARG;
	}

	if (sp_new_event_set(&event_set) != SP_OK)
		return SR_ERR;

	if (events & G_IO_IN)
		mask |= SP_EVENT_RX_READY;
	if (events & G_IO_OUT)
		mask |= SP_EVENT_TX_READY;
	if (events & G_IO_ERR)
		mask |= SP_EVENT_ERROR;

	if (sp_add_port_events(event_set, serial->data, mask) != SP_OK) {
		sp_free_event_set(event_set);
		return SR_ERR;
	}
	if (event_set->count != 1) {
		sr_err("Unexpected number (%u) of event handles to poll.",
			event_set->count);
		sp_free_event_set(event_set);
		return SR_ERR;
	}

	poll_fd = (gintptr) ((event_handle *)event_set->handles)[0];
	mask = event_set->masks[0];

	sp_free_event_set(event_set);

	poll_events = 0;
	if (mask & SP_EVENT_RX_READY)
		poll_events |= G_IO_IN;
	if (mask & SP_EVENT_TX_READY)
		poll_events |= G_IO_OUT;
	if (mask & SP_EVENT_ERROR)
		poll_events |= G_IO_ERR;
	/*
	 * Using serial->data as the key for the event source is not quite
	 * proper, as it makes it impossible to create another event source
	 * for the same serial port. However, these fixed keys will soon be
	 * removed from the API anyway, so this is OK for now.
	 */
	return sr_session_fd_source_add(session, serial->data,
			poll_fd, poll_events, timeout, cb, cb_data);
}
示例#2
0
/**
 * Add an event source for a file descriptor.
 *
 * @param session The session to use. Must not be NULL.
 * @param fd The file descriptor, or a negative value to create a timer source.
 * @param events Events to check for.
 * @param timeout Max time in ms to wait before the callback is called,
 *                or -1 to wait indefinitely.
 * @param cb Callback function to add. Must not be NULL.
 * @param cb_data Data for the callback function. Can be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid argument.
 *
 * @since 0.3.0
 * @private
 */
SR_PRIV int sr_session_source_add(struct sr_session *session, int fd,
		int events, int timeout, sr_receive_data_callback cb, void *cb_data)
{
	if (fd < 0 && timeout < 0) {
		sr_err("Cannot create timer source without timeout.");
		return SR_ERR_ARG;
	}
	return sr_session_fd_source_add(session, GINT_TO_POINTER(fd),
			fd, events, timeout, cb, cb_data);
}
示例#3
0
/**
 * Add an event source for a GPollFD.
 *
 * @param session The session to use. Must not be NULL.
 * @param pollfd The GPollFD. Must not be NULL.
 * @param timeout Max time in ms to wait before the callback is called,
 *                or -1 to wait indefinitely.
 * @param cb Callback function to add. Must not be NULL.
 * @param cb_data Data for the callback function. Can be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid argument.
 *
 * @since 0.3.0
 * @private
 */
SR_PRIV int sr_session_source_add_pollfd(struct sr_session *session,
		GPollFD *pollfd, int timeout, sr_receive_data_callback cb,
		void *cb_data)
{
	if (!pollfd) {
		sr_err("%s: pollfd was NULL", __func__);
		return SR_ERR_ARG;
	}
	return sr_session_fd_source_add(session, pollfd, pollfd->fd,
			pollfd->events, timeout, cb, cb_data);
}
示例#4
0
/**
 * Add an event source for a GIOChannel.
 *
 * @param session The session to use. Must not be NULL.
 * @param channel The GIOChannel.
 * @param events Events to poll on.
 * @param timeout Max time in ms to wait before the callback is called,
 *                or -1 to wait indefinitely.
 * @param cb Callback function to add. Must not be NULL.
 * @param cb_data Data for the callback function. Can be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid argument.
 *
 * @since 0.3.0
 * @private
 */
SR_PRIV int sr_session_source_add_channel(struct sr_session *session,
		GIOChannel *channel, int events, int timeout,
		sr_receive_data_callback cb, void *cb_data)
{
	GPollFD pollfd;

	if (!channel) {
		sr_err("%s: channel was NULL", __func__);
		return SR_ERR_ARG;
	}
	/* We should be using g_io_create_watch(), but can't without
	 * changing the driver API, as the callback signature is different.
	 */
#ifdef G_OS_WIN32
	g_io_channel_win32_make_pollfd(channel, events, &pollfd);
#else
	pollfd.fd = g_io_channel_unix_get_fd(channel);
	pollfd.events = events;
#endif
	return sr_session_fd_source_add(session, channel, pollfd.fd,
			pollfd.events, timeout, cb, cb_data);
}