power_play/src/host.h

145 lines
3.7 KiB
C

#ifndef HOST_H
#define HOST_H
#include "sys.h"
#include "sock.h"
#define HOST_CHANNEL_ID_NIL (struct host_channel_id) { .gen = 0, .idx = 0 }
#define HOST_CHANNEL_ID_ALL (struct host_channel_id) { .gen = U32_MAX, .idx = U32_MAX }
struct buddy_ctx;
struct host_snd_packet;
struct host_channel_lookup_bin;
struct host_rcv_buffer;
enum host_cmd_kind {
HOST_CMD_KIND_NONE,
HOST_CMD_KIND_TRY_CONNECT,
HOST_CMD_KIND_CONNECT_SUCCESS,
HOST_CMD_KIND_DISCONNECT,
HOST_CMD_KIND_HEARTBEAT,
HOST_CMD_KIND_WRITE
};
enum host_event_kind {
HOST_EVENT_KIND_NONE,
HOST_EVENT_KIND_CHANNEL_OPENED,
HOST_EVENT_KIND_CHANNEL_CLOSED,
HOST_EVENT_KIND_MSG
};
enum host_write_flag {
HOST_WRITE_FLAG_NONE = 0,
HOST_WRITE_FLAG_RELIABLE = (1 << 0)
};
struct host_cmd {
enum host_cmd_kind kind;
struct host_channel_id channel_id;
u16 heartbeat_id;
u16 heartbeat_ack_id;
b32 write_reliable;
struct string write_msg;
struct host_cmd *next;
};
struct host_event {
enum host_event_kind kind;
struct host_channel_id channel_id;
struct string msg;
struct host_event *next;
};
struct host_event_list {
struct host_event *first;
struct host_event *last;
};
struct host {
struct arena *arena;
struct sock *sock;
struct buddy_ctx *buddy; /* For storing msg assembler data */
struct arena *cmd_arena;
struct host_cmd *first_cmd;
struct host_cmd *last_cmd;
struct host_cmd *first_free_cmd;
struct arena *channel_arena;
struct host_channel *channels;
struct host_channel *first_free_channel;
u64 num_channels_reserved;
struct host_snd_packet *first_free_packet; /* Allocated in `arena` */
struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */
struct host_channel_lookup_bin *channel_lookup_bins; /* Allocated in `arena` */
u64 num_channel_lookup_bins;
struct host_msg_assembler_lookup_bin *msg_assembler_lookup_bins; /* Allocated in `arena` */
u64 num_msg_assembler_lookup_bins;
/* Double buffer for incoming data */
struct sys_mutex *rcv_buffer_write_mutex;
struct host_rcv_buffer *rcv_buffer_read;
struct host_rcv_buffer *rcv_buffer_write;
u64 bytes_received;
u64 bytes_sent;
struct atomic_i32 receiver_thread_shutdown_flag;
struct sys_thread *receiver_thread;
};
/* ========================== *
* Startup
* ========================== */
struct host_startup_receipt { i32 _; };
struct host_startup_receipt host_startup(struct sock_startup_receipt *sock_sr);
/* ========================== *
* Host
* ========================== */
struct host *host_alloc(u16 listen_port);
void host_release(struct host *host);
/* ========================== *
* Queue
* ========================== */
void host_queue_connect_to_address(struct host *host, struct sock_address connect_address);
void host_queue_disconnect(struct host *host, struct host_channel_id channel_id);
void host_queue_write(struct host *host, struct host_channel_id channel_id, struct string msg, u32 flags);
/* ========================== *
* Info
* ========================== */
i64 host_get_channel_last_rtt_ns(struct host *host, struct host_channel_id channel_id);
INLINE b32 host_channel_id_eq(struct host_channel_id a, struct host_channel_id b) { return a.idx == b.idx && a.gen == b.gen; }
INLINE b32 host_channel_id_is_nil(struct host_channel_id id) { return id.gen == 0 && id.idx == 0; }
/* ========================== *
* Update
* ========================== */
struct host_event_list host_update_begin(struct arena *arena, struct host *host);
void host_update_end(struct host *host);
#endif