diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/cli/ipc.h | 46 | ||||
| -rw-r--r-- | include/recorder/recorder.h | 7 |
2 files changed, 53 insertions, 0 deletions
diff --git a/include/cli/ipc.h b/include/cli/ipc.h index 0862c71..6008db9 100644 --- a/include/cli/ipc.h +++ b/include/cli/ipc.h @@ -3,43 +3,82 @@ #include <stdbool.h> #include <stddef.h> +#include <stdint.h> #include <limits.h> #include <pthread.h> #define GSR_IPC_MAX_CLIENTS 8 #define GSR_IPC_MAX_REQUEST_SIZE 4096 #define GSR_IPC_MAX_ERROR_MESSAGE_SIZE 256 +#define GSR_IPC_MAX_ESCAPED_ERROR_MESSAGE_SIZE (GSR_IPC_MAX_ERROR_MESSAGE_SIZE*6) +#define GSR_IPC_MAX_ESCAPED_DATA_SIZE PATH_MAX +#define GSR_IPC_MAX_REPLY_SIZE (GSR_IPC_MAX_ESCAPED_ERROR_MESSAGE_SIZE + GSR_IPC_MAX_ESCAPED_DATA_SIZE + 128) +#define GSR_IPC_CLIENT_SEND_BUFFER_SIZE (GSR_IPC_MAX_REPLY_SIZE*2) /* These are called from the ipc thread while the recording is running. Return false and write a message to |error_message| to reply to the request with an error. + The reply to the requests that match a |gsr_ipc_deferred_request_type| is not sent when the handler + succeeds. It's sent when the matching gsr_ipc_complete_request is called. */ typedef struct { bool (*stop)(char *error_message, size_t error_message_size, void *userdata); bool (*toggle_pause)(char *error_message, size_t error_message_size, void *userdata); + bool (*set_paused)(bool paused, char *error_message, size_t error_message_size, void *userdata); bool (*toggle_replay_recording)(char *error_message, size_t error_message_size, void *userdata); + bool (*start_replay_recording)(char *error_message, size_t error_message_size, void *userdata); + bool (*stop_replay_recording)(char *error_message, size_t error_message_size, void *userdata); /* |seconds| is GSR_SAVE_REPLAY_SECONDS_FULL when the whole replay buffer should be saved */ bool (*save_replay)(int seconds, char *error_message, size_t error_message_size, void *userdata); void *userdata; } gsr_ipc_handlers; +/* Requests that are replied to when the file they save has been saved (see gsr_ipc_complete_request) */ +typedef enum { + GSR_IPC_DEFERRED_REQUEST_STOP, + GSR_IPC_DEFERRED_REQUEST_SAVE_REPLAY, + GSR_IPC_DEFERRED_REQUEST_STOP_REPLAY_RECORDING, + GSR_IPC_DEFERRED_REQUEST_TYPE_COUNT +} gsr_ipc_deferred_request_type; + +typedef enum { + GSR_IPC_DEFERRED_REQUEST_STATE_EMPTY, + GSR_IPC_DEFERRED_REQUEST_STATE_PENDING, + GSR_IPC_DEFERRED_REQUEST_STATE_COMPLETED +} gsr_ipc_deferred_request_state; + +typedef struct { + gsr_ipc_deferred_request_state state; + int client_fd; + int64_t request_id; + bool success; + bool has_filepath; + char filepath[PATH_MAX]; +} gsr_ipc_deferred_request; + typedef struct { int fd; char request[GSR_IPC_MAX_REQUEST_SIZE]; size_t request_size; bool request_too_large; + char send_buffer[GSR_IPC_CLIENT_SEND_BUFFER_SIZE]; + size_t send_buffer_size; } gsr_ipc_client; /* Receives newline terminated json requests on a unix domain socket and replies to every request */ typedef struct { bool initialized; int socket_fd; + int poll_fd; bool socket_bound; char socket_filepath[PATH_MAX]; int wakeup_pipe[2]; gsr_ipc_client clients[GSR_IPC_MAX_CLIENTS]; int num_clients; gsr_ipc_handlers handlers; + gsr_ipc_deferred_request deferred_requests[GSR_IPC_DEFERRED_REQUEST_TYPE_COUNT]; + pthread_mutex_t deferred_requests_mutex; + bool deferred_requests_mutex_created; pthread_t thread; bool thread_running; } gsr_ipc; @@ -53,4 +92,11 @@ int gsr_ipc_start(gsr_ipc *self, const gsr_ipc_handlers *handlers); /* Stops handling requests. Does nothing if the ipc hasn't been started */ void gsr_ipc_stop(gsr_ipc *self); +/* + Sends the reply to the pending request of |type|, or does nothing when there is no pending request of that type. + |filepath| is the path of the saved file and it can be NULL when nothing was saved. + This is safe to call from any thread. Does nothing if |self| hasn't been initialized. +*/ +void gsr_ipc_complete_request(gsr_ipc *self, gsr_ipc_deferred_request_type type, bool success, const char *filepath); + #endif /* GSR_CLI_IPC_H */ diff --git a/include/recorder/recorder.h b/include/recorder/recorder.h index bbd37e1..887b4fe 100644 --- a/include/recorder/recorder.h +++ b/include/recorder/recorder.h @@ -47,7 +47,14 @@ int gsr_recorder_run(gsr_recorder *self); /* These are safe to call from a signal handler or from another thread */ void gsr_recorder_stop(gsr_recorder *self); void gsr_recorder_toggle_pause(gsr_recorder *self); +/* Does nothing when the recording is already paused/unpaused */ +void gsr_recorder_set_paused(gsr_recorder *self, bool paused); void gsr_recorder_toggle_replay_recording(gsr_recorder *self); +/* Does nothing when a recording is already running */ +void gsr_recorder_start_replay_recording(gsr_recorder *self); +/* Does nothing when no recording is running */ +void gsr_recorder_stop_replay_recording(gsr_recorder *self); +bool gsr_recorder_is_replay_recording(const gsr_recorder *self); /* |seconds| can be GSR_SAVE_REPLAY_SECONDS_FULL to save the whole replay buffer */ void gsr_recorder_save_replay(gsr_recorder *self, int seconds); |
