typedef struct
{
int fd;
- ply_event_handler_t new_data_handler;
+ ply_event_loop_fd_status_t status;
+ ply_event_handler_t status_met_handler;
ply_event_handler_t disconnected_handler;
void *user_data;
ply_event_loop_free_handler_t free_function;
static void ply_event_loop_process_pending_events (ply_event_loop_t *loop);
static void ply_event_loop_remove_source (ply_event_loop_t *loop,
ply_event_source_t *source);
-ply_list_node_t *ply_event_loop_find_source_node (ply_event_loop_t *loop,
- int fd);
+static ply_list_node_t *ply_event_loop_find_source_node (ply_event_loop_t *loop,
+ int fd,
+ ply_event_loop_fd_status_t status);
-ply_list_node_t *
+static ply_list_node_t *
ply_signal_dispatcher_find_source_node (ply_signal_dispatcher_t *dispatcher,
int signal_number);
}
static ply_event_source_t *
-ply_event_source_new (int fd,
- ply_event_handler_t new_data_handler,
- ply_event_handler_t disconnected_handler,
- void *user_data,
+ply_event_source_new (int fd,
+ ply_event_loop_fd_status_t status,
+ ply_event_handler_t status_met_handler,
+ ply_event_handler_t disconnected_handler,
+ void *user_data,
ply_event_loop_free_handler_t free_function)
{
ply_event_source_t *source;
source = calloc (1, sizeof (ply_event_source_t));
source->fd = fd;
- source->new_data_handler = new_data_handler;
+ source->status = status;
+ source->status_met_handler = status_met_handler;
source->disconnected_handler = disconnected_handler;
source->user_data = user_data;
source->free_function = free_function;
ply_event_loop_watch_fd (loop,
ply_signal_dispatcher_receiver_fd,
+ PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t)
ply_signal_dispatcher_dispatch_signal,
(ply_event_handler_t)
struct epoll_event event = { 0 };
int status;
- event.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
+ event.events = EPOLLERR | EPOLLHUP;
+
+ if (source->status & PLY_EVENT_LOOP_FD_STATUS_HAS_DATA)
+ event.events |= EPOLLIN;
+
+ if (source->status & PLY_EVENT_LOOP_FD_STATUS_HAS_CONTROL_DATA)
+ event.events |= EPOLLPRI;
+
+ if (source->status & PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA)
+ event.events |= EPOLLOUT;
+
event.data.ptr = source;
status = epoll_ctl (loop->epoll_fd, EPOLL_CTL_ADD, source->fd, &event);
ply_event_loop_remove_source_node (loop, source_node);
}
-ply_list_node_t *
+static ply_list_node_t *
ply_event_loop_find_source_node (ply_event_loop_t *loop,
- int fd)
+ int fd,
+ ply_event_loop_fd_status_t status)
{
ply_list_node_t *node;
source = (ply_event_source_t *) ply_list_node_get_data (node);
- if (source->fd == fd)
+ if ((source->fd == fd) && (source->status == status))
break;
node = ply_list_get_next_node (loop->sources, node);
return node;
}
+static bool
+ply_event_loop_fd_status_is_valid (ply_event_loop_fd_status_t status)
+{
+ return (status & ~(PLY_EVENT_LOOP_FD_STATUS_HAS_DATA
+ | PLY_EVENT_LOOP_FD_STATUS_HAS_CONTROL_DATA
+ | PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA)) == 0;
+
+}
+
void
-ply_event_loop_watch_fd (ply_event_loop_t *loop,
- int fd,
- ply_event_handler_t new_data_handler,
- ply_event_handler_t disconnected_handler,
- void *user_data)
+ply_event_loop_watch_fd (ply_event_loop_t *loop,
+ int fd,
+ ply_event_loop_fd_status_t status,
+ ply_event_handler_t status_met_handler,
+ ply_event_handler_t disconnected_handler,
+ void *user_data)
{
ply_list_node_t *node;
ply_event_source_t *source;
- node = ply_event_loop_find_source_node (loop, fd);
+ assert (loop != NULL);
+ assert (fd >= 0);
+ assert (ply_event_loop_fd_status_is_valid (status));
+
+ node = ply_event_loop_find_source_node (loop, fd, status);
assert (node == NULL);
source = ply_event_source_new (fd,
- new_data_handler,
+ status,
+ status_met_handler,
disconnected_handler,
user_data, NULL);
}
void
-ply_event_loop_stop_watching_fd (ply_event_loop_t *loop,
- int fd)
+ply_event_loop_stop_watching_fd (ply_event_loop_t *loop,
+ int fd,
+ ply_event_loop_fd_status_t status)
{
ply_list_node_t *node;
ply_event_source_t *source;
- node = ply_event_loop_find_source_node (loop, fd);
+ node = ply_event_loop_find_source_node (loop, fd, status);
assert (node != NULL);
ply_event_source_free (source);
}
-ply_list_node_t *
+static ply_list_node_t *
ply_signal_dispatcher_find_source_node (ply_signal_dispatcher_t *dispatcher,
int signal_number)
{
for (i = 0; i < number_of_received_events; i++)
{
ply_event_source_t *source;
+ ply_event_loop_fd_status_t status;
source = (ply_event_source_t *) (events[i].data.ptr);
- if ((events[i].events & EPOLLIN) || (events[i].events & EPOLLPRI))
- {
- if (source->new_data_handler != NULL)
- source->new_data_handler (source->user_data, source->fd);
- }
- else if ((events[i].events & EPOLLHUP) || (events[i].events & EPOLLERR))
+ status = PLY_EVENT_LOOP_FD_STATUS_NONE;
+
+ if (events[i].events & EPOLLIN)
+ status |= PLY_EVENT_LOOP_FD_STATUS_HAS_DATA;
+
+ if (events[i].events & EPOLLPRI)
+ status |= PLY_EVENT_LOOP_FD_STATUS_HAS_CONTROL_DATA;
+
+ if (events[i].events & EPOLLOUT)
+ status |= PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA;
+
+ if (((source->status & status) != 0)
+ && (source->status_met_handler != NULL))
+ source->status_met_handler (source->user_data, source->fd);
+
+ if ((events[i].events & EPOLLHUP) || (events[i].events & EPOLLERR))
{
if (source->disconnected_handler != NULL)
source->disconnected_handler (source->user_data, source->fd);
(ply_event_handler_t)
usr1_signal_handler, NULL);
- ply_event_loop_watch_fd (loop, 0,
+ ply_event_loop_watch_fd (loop, 0, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t) line_received_handler,
(ply_event_handler_t) line_received_handler,
NULL);
typedef struct _ply_event_loop ply_event_loop_t;
+typedef enum {
+ PLY_EVENT_LOOP_FD_STATUS_NONE = 0,
+ PLY_EVENT_LOOP_FD_STATUS_HAS_DATA = 0x1,
+ PLY_EVENT_LOOP_FD_STATUS_HAS_CONTROL_DATA = 0x2,
+ PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA = 0x4,
+} ply_event_loop_fd_status_t;
+
typedef void (* ply_event_handler_t) (void *user_data,
int source_fd);
typedef void (* ply_event_loop_exit_handler_t) (void *user_data,
int exit_code,
- ply_event_loop_t *loop);
+ ply_event_loop_t *loop);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_event_loop_t *ply_event_loop_new (void);
void ply_event_loop_free (ply_event_loop_t *loop);
void ply_event_loop_watch_fd (ply_event_loop_t *loop,
int fd,
- ply_event_handler_t new_data_handler,
+ ply_event_loop_fd_status_t status,
+ ply_event_handler_t status_met_handler,
ply_event_handler_t disconnected_handler,
- void *user_data);
+ void *user_data);
void ply_event_loop_stop_watching_fd (ply_event_loop_t *loop,
- int fd);
+ int fd,
+ ply_event_loop_fd_status_t status);
void ply_event_loop_watch_signal (ply_event_loop_t *loop,
int signal_number,
ply_event_handler_t signal_handler,
- void *user_data);
+ void *user_data);
void ply_event_loop_stop_watching_signal (ply_event_loop_t *loop,
int signal_number);
void ply_event_loop_watch_for_exit (ply_event_loop_t *loop,
- ply_event_loop_exit_handler_t exit_handler,
- void *user_data);
+ ply_event_loop_exit_handler_t exit_handler,
+ void *user_data);
int ply_event_loop_run (ply_event_loop_t *loop);
void ply_event_loop_exit (ply_event_loop_t *loop,
#endif
#endif
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
return ply_terminal_get_fd (session->terminal);
}
+static void
+ply_terminal_session_log_bytes (ply_terminal_session_t *session,
+ const uint8_t *bytes,
+ size_t number_of_bytes)
+{
+ assert (session != NULL);
+ assert (session->logger != NULL);
+ assert (bytes != NULL);
+ assert (number_of_bytes != 0);
+
+ ply_logger_inject_bytes (session->logger, bytes, number_of_bytes);
+}
+
static void
ply_terminal_session_on_new_data (ply_terminal_session_t *session,
int session_fd)
{
- char buffer[4096];
+ uint8_t buffer[4096];
ssize_t bytes_read;
assert (session != NULL);
bytes_read = read (session_fd, buffer, sizeof (buffer));
-#if 0
if (bytes_read > 0)
- {
- int i;
- for (i = 0; i < bytes_read; i++)
- buffer[i] = (char) toupper ((uint8_t) buffer[i]);
- ply_logger_inject_bytes (session->logger, buffer, bytes_read);
- }
-#endif
+ ply_terminal_session_log_bytes (session, buffer, bytes_read);
ply_logger_flush (session->logger);
}
assert (session_fd >= 0);
ply_event_loop_watch_fd (session->loop, session_fd,
+ PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t)
ply_terminal_session_on_new_data,
(ply_event_handler_t)