event loop for darwin

This commit is contained in:
pantonshire committed 2025-12-22 16:08:31 +00:00
1 parent 45284910cc
commit 9a00a29af6
7 files changed
+218 -26

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <stddef.h>
#include "typecheck.h"
#define CONTAINER_OF(PTR, TYPE, MEMBER) ({ \
CHECK_TYPE(__typeof__(((TYPE *)NULL)->MEMBER), *(PTR)); \
(TYPE *)((char *)(PTR) - offsetof(TYPE, MEMBER)); \
})
+44 -3
View File
@@ -1,6 +1,47 @@
#pragma once
struct eventloop;
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
struct eventloop *eventloop_new(void);
void eventloop_free(struct eventloop *el);
#include "list.h"
#define OWD_EVENT_READABLE (1 << 0)
#define OWD_EVENT_WRITABLE (1 << 1)
enum owd_event_source {
OWD_EVENT_SOURCE_FD,
OWD_EVENT_SOURCE_TIMER,
};
typedef struct {
uintptr_t obj;
enum owd_event_source source;
} owd_event_id_t;
struct owd_event {
owd_event_id_t id;
struct intrusive_list list;
uintptr_t kqueue_ident;
short kqueue_filter;
};
struct owd_eventloop {
struct intrusive_list event_list;
uintptr_t kqueue_timer_next;
int kqueue_fd;
};
static inline bool owd_event_id_eq(owd_event_id_t eid1, owd_event_id_t eid2) {
return (eid1.obj == eid2.obj) && (eid1.source == eid2.source);
}
int owd_eventloop_init(struct owd_eventloop *el);
void owd_eventloop_cleanup(struct owd_eventloop *el);
int owd_eventloop_wait(struct owd_eventloop *el, owd_event_id_t *id_out, const struct timespec *timeout);
int owd_eventloop_clear(struct owd_eventloop *el, struct owd_event *e);
void owd_eventloop_remove(struct owd_eventloop *el, struct owd_event *e);
int owd_eventloop_add_timer(struct owd_eventloop *el, struct owd_event *e, uint64_t millis, bool oneshot);
+46
View File
@@ -0,0 +1,46 @@
#pragma once
#include "typecheck.h"
struct intrusive_list {
struct intrusive_list *next;
struct intrusive_list *prev;
};
static inline void intrusive_list_init_empty(struct intrusive_list *head) {
head->next = head;
head->prev = head;
}
static inline void intrusive_list_del(struct intrusive_list *node) {
struct intrusive_list old_node;
old_node = *node;
node->prev->next = old_node.next;
node->next->prev = old_node.prev;
}
static inline void intrusive_list_add(
struct intrusive_list *add_after,
struct intrusive_list *new_node)
{
new_node->prev = add_after;
new_node->next = add_after->next;
new_node->prev->next = new_node;
new_node->next->prev = new_node;
}
#define INTRUSIVE_LIST_FOR_EACH(ITER, NEXT, HEAD) \
for ( \
CHECK_TYPE(struct intrusive_list *, HEAD), \
(ITER) = (HEAD)->next, \
(NEXT) = (ITER)->next; \
(ITER) != (HEAD); \
(ITER) = (NEXT), (NEXT) = (ITER)->next)
#define INTRUSIVE_LIST_FOR_EACH_NO_REMOVE(ITER, HEAD) \
for ( \
CHECK_TYPE(struct intrusive_list *, HEAD), \
(ITER) = (HEAD)->next; \
(ITER) != (HEAD); \
(ITER) = (ITER)->next)
+1
View File
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include "scoped.h"
#include "typecheck.h"
DEF_SCOPED_TYPE(mem, void *, NULL, free)
-8
View File
@@ -1,13 +1,5 @@
#pragma once
#define CHECK_TYPE(TYPE, VAL) ({ \
typedef void (*_check_type_dummy_fn_t)(TYPE); \
_check_type_dummy_fn_t _check_type_dummy_fn = (_check_type_dummy_fn_t)NULL; \
if (0) \
_check_type_dummy_fn(VAL); \
1; \
})
#define DEF_SCOPED_TYPE(NAME, TYPE, UNOCCUPIED, CLEANUP_FN) \
static inline TYPE _scoped_##NAME##_unoccupied(void) { \
return (UNOCCUPIED); \
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#define CHECK_TYPE(TYPE, VAL) ({ \
typedef void (*_check_type_dummy_fn_t)(TYPE); \
_check_type_dummy_fn_t _check_type_dummy_fn = (_check_type_dummy_fn_t)NULL; \
if (0) \
_check_type_dummy_fn(VAL); \
1; \
})