[backend] message queue

This commit is contained in:
Milo Turner 2020-02-18 16:53:31 -05:00
parent ea96f494ca
commit 174e57e51d
4 changed files with 128 additions and 12 deletions

View File

@ -4,9 +4,7 @@
#include <stdint.h> #include <stdint.h>
struct rgn; struct rgn;
struct ax_backend; struct ax_backend;
struct ax_font_h;
extern const char* ax__backend_impl_name; extern const char* ax__backend_impl_name;
@ -15,5 +13,7 @@ int ax__backend_new(
struct ax_backend** out_bac, struct ax_backend** out_bac,
const char** out_err); const char** out_err);
const char* ax__backend_get_error( void ax__backend_enqueue_font(
struct ax_backend* bac); struct ax_backend* bac,
const char* font_path,
size_t font_size);

View File

@ -1,14 +1,34 @@
#include "../backend.h" #include "../backend.h"
#include "../util/region.h" #include "../util/region.h"
#include "../concurrent/msgq.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_ttf.h>
struct ax_backend { /* --- Backend data type --- */
};
const char* ax__backend_impl_name = "SDL"; const char* ax__backend_impl_name = "SDL";
static void shutdown_backend(struct ax_backend* bac); struct ax_backend {
struct msgq* mq;
};
/* --- Async messages --- */
enum {
msg_close_TAG,
msg_load_font_TAG,
};
struct msg_close {};
struct msg_load_font {
const char* path;
size_t size;
};
/* --- Functions --- */
static void backend_cleanup(struct ax_backend* bac);
int ax__backend_new( int ax__backend_new(
struct rgn* init_rgn, struct rgn* init_rgn,
@ -26,7 +46,9 @@ int ax__backend_new(
} }
struct ax_backend* bac = ralloc_typed(init_rgn, struct ax_backend, 1); struct ax_backend* bac = ralloc_typed(init_rgn, struct ax_backend, 1);
rgn_pin(init_rgn, bac, (void*) shutdown_backend); rgn_pin(init_rgn, bac, (void*) backend_cleanup);
bac->mq = msgq_new(init_rgn);
if (out_bac != NULL) { if (out_bac != NULL) {
*out_bac = bac; *out_bac = bac;
@ -40,15 +62,23 @@ fail:
return 1; return 1;
} }
static void shutdown_backend(struct ax_backend* bac) static void backend_cleanup(struct ax_backend* bac)
{ {
msgq_begin_send_typed(bac->mq, msg_close);
msgq_end_send(bac->mq);
// printf("bye, from SDL\n"); // printf("bye, from SDL\n");
TTF_Quit(); TTF_Quit();
SDL_Quit(); SDL_Quit();
} }
const char* ax__backend_get_error(struct ax_backend* bac) void ax__backend_enqueue_font(
struct ax_backend* bac,
const char* font_path,
size_t font_size)
{ {
(void) bac; struct msg_load_font* m = msgq_begin_send_typed(bac->mq, msg_load_font);
return NULL; m->path = rstrdup(&bac->mq->rgn, font_path);
m->size = font_size;
msgq_end_send(bac->mq);
} }

57
src/concurrent/msgq.c Normal file
View File

@ -0,0 +1,57 @@
#include "msgq.h"
static void msgq_cleanup(struct msgq* mq);
struct msgq* msgq_new(struct rgn* init_rgn)
{
struct msgq* mq = ralloc_typed(init_rgn, struct msgq, 1);
rgn_init(&mq->rgn, SMALL);
mq->head = mq->tail = NULL;
rgn_pin(init_rgn, mq, (void*) msgq_cleanup);
return mq;
}
static void msgq_cleanup(struct msgq* mq)
{
msgq_begin_recv(mq);
rgn_cleanup(&mq->rgn);
}
void* msgq_begin_send(struct msgq* mq, int type, size_t payload_size)
{
struct msgq_msg* msg = ralloc(&mq->rgn, sizeof(struct msgq_msg) + payload_size);
msg->next = NULL;
msg->type = type;
if (mq->head == NULL) {
mq->head = mq->tail = msg;
} else {
mq->tail->next = msg;
mq->tail = msg;
}
return msg->payload;
}
void msgq_end_send(struct msgq* mq)
{
}
void msgq_begin_recv(struct msgq* mq)
{
}
void* msgq_recv1(struct msgq* mq, int* out_type)
{
if (mq->head == NULL) {
return NULL;
} else {
void* pl = mq->head->payload;
mq->head = mq->head->next;
return pl;
}
}
void msgq_end_recv(struct msgq* mq)
{
mq->head = mq->tail = NULL;
rgn_clear(&mq->rgn);
}

29
src/concurrent/msgq.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include "../util/region.h"
struct msgq_msg;
struct msgq {
struct rgn rgn;
struct msgq_msg* head;
struct msgq_msg* tail;
};
struct msgq_msg {
struct msgq_msg* next;
int type;
char payload[0];
};
struct msgq* msgq_new(struct rgn* init_rgn);
void* msgq_begin_send(struct msgq* mq, int type, size_t payload_size);
void msgq_end_send(struct msgq* mq);
#define msgq_begin_send_typed(_mq, _ty) \
((struct _ty*) msgq_begin_send(_mq, _ty ## _TAG, sizeof(struct _ty)))
void msgq_begin_recv(struct msgq* mq);
void* msgq_recv1(struct msgq* mq, int* out_type);
void msgq_end_recv(struct msgq* mq);