160 lines
3.6 KiB
C
160 lines
3.6 KiB
C
#define HOST_CHANNEL_ID_NIL (N_ChannelId) { .gen = 0, .idx = 0 }
|
|
#define HOST_CHANNEL_ID_ALL (N_ChannelId) { .gen = U32_MAX, .idx = U32_MAX }
|
|
|
|
#define N_PacketMagic 0xd9e3b8b6
|
|
#define N_MaxPacketChunkLen 1024
|
|
#define N_MaxPacketLen 1280 /* Give enough space for msg chunk + header */
|
|
|
|
#define N_NumChannelLookupBins 512
|
|
#define N_NumMsgAssemblerLookupBins 16384
|
|
|
|
typedef i32 N_CmdKind; enum {
|
|
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
|
|
};
|
|
|
|
typedef i32 N_EventKind; enum {
|
|
HOST_EVENT_KIND_NONE,
|
|
|
|
HOST_EVENT_KIND_CHANNEL_OPENED,
|
|
HOST_EVENT_KIND_CHANNEL_CLOSED,
|
|
HOST_EVENT_KIND_MSG
|
|
};
|
|
|
|
typedef i32 N_WriteFlag; enum {
|
|
HOST_WRITE_FLAG_NONE = 0,
|
|
|
|
HOST_WRITE_FLAG_RELIABLE = (1 << 0)
|
|
};
|
|
|
|
Struct(N_ChannelId) {
|
|
u32 gen;
|
|
u32 idx;
|
|
};
|
|
|
|
Struct(N_Cmd) {
|
|
N_CmdKind kind;
|
|
N_ChannelId channel_id;
|
|
|
|
u16 heartbeat_id;
|
|
u16 heartbeat_ack_id;
|
|
|
|
b32 write_reliable;
|
|
String write_msg;
|
|
|
|
|
|
N_Cmd *next;
|
|
};
|
|
|
|
Struct(N_Event) {
|
|
N_EventKind kind;
|
|
N_ChannelId channel_id;
|
|
String msg;
|
|
|
|
N_Event *next;
|
|
};
|
|
|
|
Struct(N_EventList) {
|
|
N_Event *first;
|
|
N_Event *last;
|
|
};
|
|
|
|
Struct(N_ChannelLookupBin) {
|
|
struct host_channel *first;
|
|
struct host_channel *last;
|
|
};
|
|
|
|
Struct(N_RcvBuffer) {
|
|
Arena *arena;
|
|
struct host_rcv_packet *first_packet;
|
|
struct host_rcv_packet *last_packet;
|
|
};
|
|
|
|
Struct(N_SndPacket) {
|
|
N_SndPacket *next;
|
|
u64 seq;
|
|
|
|
u64 data_len;
|
|
u8 data[N_MaxPacketLen];
|
|
};
|
|
|
|
Struct(N_Host) {
|
|
Arena *arena;
|
|
|
|
P_Sock *sock;
|
|
|
|
BuddyCtx *buddy; /* For storing msg assembler data */
|
|
|
|
Arena *cmd_arena;
|
|
N_Cmd *first_cmd;
|
|
N_Cmd *last_cmd;
|
|
N_Cmd *first_free_cmd;
|
|
|
|
Arena *channel_arena;
|
|
struct host_channel *channels;
|
|
struct host_channel *first_free_channel;
|
|
u64 num_channels_reserved;
|
|
|
|
N_SndPacket *first_free_packet; /* Allocated in `arena` */
|
|
struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */
|
|
|
|
N_ChannelLookupBin *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 */
|
|
P_Mutex rcv_buffer_write_mutex;
|
|
N_RcvBuffer *rcv_buffer_read;
|
|
N_RcvBuffer *rcv_buffer_write;
|
|
|
|
u64 bytes_received;
|
|
u64 bytes_sent;
|
|
};
|
|
|
|
/* ========================== *
|
|
* Startup
|
|
* ========================== */
|
|
|
|
Struct(N_StartupReceipt) { i32 _; };
|
|
N_StartupReceipt host_startup(void);
|
|
|
|
/* ========================== *
|
|
* Host
|
|
* ========================== */
|
|
|
|
N_Host *host_alloc(u16 listen_port);
|
|
|
|
void host_release(N_Host *host);
|
|
|
|
/* ========================== *
|
|
* Queue
|
|
* ========================== */
|
|
|
|
void host_queue_connect_to_address(N_Host *host, P_Address connect_address);
|
|
|
|
void host_queue_disconnect(N_Host *host, N_ChannelId channel_id);
|
|
|
|
void host_queue_write(N_Host *host, N_ChannelId channel_id, String msg, u32 flags);
|
|
|
|
/* ========================== *
|
|
* Info
|
|
* ========================== */
|
|
|
|
i64 host_get_channel_last_rtt_ns(N_Host *host, N_ChannelId channel_id);
|
|
INLINE b32 host_channel_id_eq(N_ChannelId a, N_ChannelId b) { return a.idx == b.idx && a.gen == b.gen; }
|
|
INLINE b32 host_channel_id_is_nil(N_ChannelId id) { return id.gen == 0 && id.idx == 0; }
|
|
|
|
/* ========================== *
|
|
* Update
|
|
* ========================== */
|
|
|
|
N_EventList host_update_begin(Arena *arena, N_Host *host);
|
|
void host_update_end(N_Host *host);
|