diff --git a/examples/draw.c b/examples/draw.c index da35b80..b91c667 100644 --- a/examples/draw.c +++ b/examples/draw.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -66,6 +66,9 @@ int main(int argc, char* argv[]) memset(addr, 0xff, width * height * 4); + struct aml* aml = aml_new(NULL, 0); + aml_set_default(aml); + struct nvnc* server = nvnc_open("127.0.0.1", 5900); nvnc_set_dimensions(server, width, height, format); @@ -73,7 +76,7 @@ int main(int argc, char* argv[]) nvnc_set_pointer_fn(server, on_pointer_event); nvnc_set_userdata(server, &draw); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); + aml_run(aml); nvnc_close(server); } diff --git a/examples/meson.build b/examples/meson.build index 7e8980c..ddab518 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -8,7 +8,7 @@ executable( dependencies: [ neatvnc_dep, pixman, - libuv, + aml, ] ) @@ -22,7 +22,7 @@ if libpng.found() dependencies: [ neatvnc_dep, pixman, - libuv, + aml, libpng, ] ) diff --git a/examples/png-server.c b/examples/png-server.c index 79705e6..c113022 100644 --- a/examples/png-server.c +++ b/examples/png-server.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -38,6 +38,9 @@ int main(int argc, char* argv[]) return 1; } + struct aml* aml = aml_new(NULL, 0); + aml_set_default(aml); + struct nvnc* server = nvnc_open("127.0.0.1", 5900); int width = nvnc_fb_get_width(fb); @@ -53,7 +56,7 @@ int main(int argc, char* argv[]) nvnc_feed_frame(server, fb, ®ion); pixman_region_fini(®ion); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); + aml_run(aml); nvnc_close(server); nvnc_fb_unref(fb); diff --git a/include/common.h b/include/common.h index 0afcb14..51debeb 100644 --- a/include/common.h +++ b/include/common.h @@ -16,7 +16,6 @@ #pragma once -#include #include #include @@ -50,6 +49,7 @@ enum nvnc_client_state { struct nvnc; struct stream; +struct aml_handler; struct nvnc_common { void* userdata; @@ -88,7 +88,7 @@ struct vnc_display { struct nvnc { struct nvnc_common common; int fd; - uv_poll_t poll_handle; + struct aml_handler* poll_handle; struct nvnc_client_list clients; struct vnc_display display; void* userdata; diff --git a/include/stream.h b/include/stream.h index 0103078..05a3883 100644 --- a/include/stream.h +++ b/include/stream.h @@ -14,8 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "config.h" #include "sys/queue.h" #include "rcbuf.h" @@ -66,7 +64,7 @@ struct stream { enum stream_state state; int fd; - uv_poll_t uv_poll; + struct aml_handler* handler; stream_event_fn on_event; void* userdata; diff --git a/meson.build b/meson.build index 31dd8b8..fbd1d9e 100644 --- a/meson.build +++ b/meson.build @@ -34,10 +34,16 @@ cc = meson.get_compiler('c') libm = cc.find_library('m', required: false) pixman = dependency('pixman-1') -libuv = dependency('libuv') libturbojpeg = dependency('libturbojpeg', required: get_option('tight-encoding')) gnutls = dependency('gnutls', required: get_option('tls')) +aml_project = subproject('aml', required: false) +if aml_project.found() + aml = aml_project.get_variable('aml_dep') +else + aml = dependency('aml') +endif + inc = include_directories('include', 'contrib/miniz') sources = [ @@ -56,7 +62,7 @@ sources = [ dependencies = [ libm, pixman, - libuv, + aml, ] config = configuration_data() diff --git a/src/damage.c b/src/damage.c index a419fd9..b1ef6be 100644 --- a/src/damage.c +++ b/src/damage.c @@ -8,14 +8,14 @@ #include #include #include -#include +#include #include #define EXPORT __attribute__((visibility("default"))) #define ALIGN_DOWN(a, b) (((a) / (b)) * (b)) struct damage_check { - uv_work_t work; + struct aml_work* work; struct nvnc_fb* fb0; struct nvnc_fb* fb1; int x_hint; @@ -86,20 +86,18 @@ int check_damage_linear(struct pixman_region16* damage, } #undef TILE_SIDE_LENGTH -void do_damage_check_linear(uv_work_t* work) +void do_damage_check_linear(void* work) { - struct damage_check* check = (void*)work; + struct damage_check* check = aml_get_userdata(work); check_damage_linear(&check->damage, check->fb0, check->fb1, check->x_hint, check->y_hint, check->width_hint, check->height_hint); } -void on_damage_check_done_linear(uv_work_t* work, int status) +void on_damage_check_done_linear(void* work) { - (void)status; - - struct damage_check* check = (void*)work; + struct damage_check* check = aml_get_userdata(work); check->on_done(&check->damage, check->userdata); @@ -130,17 +128,25 @@ int check_damage_linear_threaded(struct nvnc_fb* fb0, struct nvnc_fb* fb1, pixman_region_init(&work->damage); /* TODO: Spread the work into more tasks */ - int rc = uv_queue_work(uv_default_loop(), &work->work, - do_damage_check_linear, - on_damage_check_done_linear); - if (rc >= 0) { - nvnc_fb_ref(fb0); - nvnc_fb_ref(fb1); - } else { + struct aml_work* obj = + aml_work_new(do_damage_check_linear, on_damage_check_done_linear, + work, free); + if (!obj) { free(work); + return -1; } - return rc; + int rc = aml_start(aml_get_default(), obj); + aml_unref(obj); + if (rc < 0) + return -1; + + work->work = obj; + + nvnc_fb_ref(fb0); + nvnc_fb_ref(fb1); + + return 0; } EXPORT diff --git a/src/server.c b/src/server.c index 19f70e8..906ddc0 100644 --- a/src/server.c +++ b/src/server.c @@ -33,10 +33,11 @@ #include #include #include -#include +#include #include #include #include +#include #ifdef ENABLE_TLS #include @@ -55,7 +56,7 @@ #define EXPORT __attribute__((visibility("default"))) struct fb_update_work { - uv_work_t work; + struct aml_work* work; struct nvnc_client* client; struct pixman_region16 region; struct rfb_pixel_format server_fmt; @@ -65,19 +66,6 @@ struct fb_update_work { int schedule_client_update_fb(struct nvnc_client* client); -static const char* fourcc_to_string(uint32_t fourcc) -{ - static char buffer[5]; - - buffer[0] = (fourcc >> 0) & 0xff; - buffer[1] = (fourcc >> 8) & 0xff; - buffer[2] = (fourcc >> 16) & 0xff; - buffer[3] = (fourcc >> 24) & 0xff; - buffer[4] = '\0'; - - return buffer; -} - static void client_close(struct nvnc_client* client) { log_debug("client_close(%p): ref %d\n", client, client->ref); @@ -688,10 +676,9 @@ static void on_client_event(struct stream* stream, enum stream_event event) client->buffer_index = 0; } -static void on_connection(uv_poll_t* poll_handle, int status, int events) +static void on_connection(void* obj) { - struct nvnc* server = - container_of(poll_handle, struct nvnc, poll_handle); + struct nvnc* server = aml_get_userdata(obj); struct nvnc_client* client = calloc(1, sizeof(*client)); if (!client) @@ -749,6 +736,8 @@ accept_failure: EXPORT struct nvnc* nvnc_open(const char* address, uint16_t port) { + aml_require_workers(aml_get_default(), 4); + struct nvnc* self = calloc(1, sizeof(*self)); if (!self) return NULL; @@ -776,11 +765,17 @@ struct nvnc* nvnc_open(const char* address, uint16_t port) if (listen(self->fd, 16) < 0) goto failure; - uv_poll_init(uv_default_loop(), &self->poll_handle, self->fd); - uv_poll_start(&self->poll_handle, UV_READABLE, on_connection); + self->poll_handle = aml_handler_new(self->fd, on_connection, self, NULL); + if (!self->poll_handle) + goto failure; + + if (aml_start(aml_get_default(), self->poll_handle) < 0) + goto start_failure; return self; +start_failure: + aml_unref(self->poll_handle); failure: close(self->fd); return NULL; @@ -798,7 +793,7 @@ void nvnc_close(struct nvnc* self) LIST_FOREACH_SAFE (client, &self->clients, link, tmp) client_unref(client); - uv_poll_stop(&self->poll_handle); + aml_stop(aml_get_default(), self->poll_handle); close(self->fd); #ifdef ENABLE_TLS @@ -808,6 +803,7 @@ void nvnc_close(struct nvnc* self) } #endif + aml_unref(self->poll_handle); free(self); } @@ -835,9 +831,9 @@ enum rfb_encodings choose_frame_encoding(struct nvnc_client* client) return -1; } -void do_client_update_fb(uv_work_t* work) +void do_client_update_fb(void* work) { - struct fb_update_work* update = (void*)work; + struct fb_update_work* update = aml_get_userdata(work); struct nvnc_client* client = update->client; const struct nvnc_fb* fb = update->fb; @@ -873,11 +869,9 @@ void do_client_update_fb(uv_work_t* work) } } -void on_client_update_fb_done(uv_work_t* work, int status) +void on_client_update_fb_done(void* work) { - (void)status; - - struct fb_update_work* update = (void*)work; + struct fb_update_work* update = aml_get_userdata(work); struct nvnc_client* client = update->client; struct vec* frame = &update->frame; @@ -901,7 +895,6 @@ void on_client_update_fb_done(uv_work_t* work, int status) pixman_region_fini(&update->region); client_unref(client); - free(update); } int schedule_client_update_fb(struct nvnc_client* client) @@ -930,14 +923,25 @@ int schedule_client_update_fb(struct nvnc_client* client) client_ref(client); nvnc_fb_ref(fb); - rc = uv_queue_work(uv_default_loop(), &work->work, do_client_update_fb, - on_client_update_fb_done); + struct aml_work* obj = + aml_work_new(do_client_update_fb, on_client_update_fb_done, + work, free); + if (!obj) { + goto oom_failure; + } + + rc = aml_start(aml_get_default(), obj); + aml_unref(obj); if (rc < 0) - goto queue_failure; + goto start_failure; + + work->work = obj; return 0; -queue_failure: +start_failure: + work = NULL; /* handled in unref */ +oom_failure: nvnc_fb_unref(fb); client_unref(client); vec_destroy(&work->frame); diff --git a/src/stream.c b/src/stream.c index 94ecb99..557a5b4 100644 --- a/src/stream.c +++ b/src/stream.c @@ -21,38 +21,37 @@ #include #include #include -#include +#include +#include +#include +#include #ifdef ENABLE_TLS #include #endif -#include "type-macros.h" #include "rcbuf.h" #include "stream.h" #include "sys/queue.h" -static void stream__on_event(uv_poll_t* uv_poll, int status, int events); +static void stream__on_event(void* obj); #ifdef ENABLE_TLS static int stream__try_tls_accept(struct stream* self); #endif static inline void stream__poll_r(struct stream* self) { - uv_poll_start(&self->uv_poll, UV_READABLE | UV_DISCONNECT, - stream__on_event); + aml_set_event_mask(self->handler, POLLIN); } static inline void stream__poll_w(struct stream* self) { - uv_poll_start(&self->uv_poll, UV_WRITABLE | UV_DISCONNECT, - stream__on_event); + aml_set_event_mask(self->handler, POLLOUT); } static inline void stream__poll_rw(struct stream* self) { - uv_poll_start(&self->uv_poll, UV_READABLE | UV_DISCONNECT | UV_WRITABLE, - stream__on_event); + aml_set_event_mask(self->handler, POLLIN | POLLOUT); } static void stream_req__finish(struct stream_req* req, enum stream_req_status status) @@ -83,24 +82,18 @@ int stream_close(struct stream* self) self->tls_session = NULL; #endif - uv_poll_stop(&self->uv_poll); + // TODO: Maybe use explicit loop object instead of the default one? + aml_stop(aml_get_default(), self->handler); close(self->fd); self->fd = -1; return 0; } -void stream__free_poll_handle(uv_handle_t* handle) -{ - uv_poll_t* uv_poll = (uv_poll_t*)handle; - struct stream* self = container_of(uv_poll, struct stream, uv_poll); - free(self); -} - void stream_destroy(struct stream* self) { stream_close(self); - uv_close((uv_handle_t*)&self->uv_poll, stream__free_poll_handle); + aml_unref(self->handler); } static void stream__remote_closed(struct stream* self) @@ -268,19 +261,15 @@ static void stream__on_writable(struct stream* self) } } -static void stream__on_event(uv_poll_t* uv_poll, int status, int events) +static void stream__on_event(void* obj) { - struct stream* self = container_of(uv_poll, struct stream, uv_poll); + struct stream* self = aml_get_userdata(obj); + uint32_t events = aml_get_revents(obj); - if (events & UV_DISCONNECT) { - stream__remote_closed(self); - return; - } - - if (events & UV_READABLE) + if (events & POLLIN) stream__on_readable(self); - if (events & UV_WRITABLE) + if (events & POLLOUT) stream__on_writable(self); } @@ -298,13 +287,20 @@ struct stream* stream_new(int fd, stream_event_fn on_event, void* userdata) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); - if (uv_poll_init(uv_default_loop(), &self->uv_poll, fd) < 0) + self->handler = aml_handler_new(fd, stream__on_event, self, free); + if (!self->handler) goto failure; + if (aml_start(aml_get_default(), self->handler) < 0) + goto start_failure; + stream__poll_r(self); return self; +start_failure: + aml_unref(self->handler); + self = NULL; /* Handled in unref */ failure: free(self); return NULL; @@ -393,7 +389,7 @@ static int stream__try_tls_accept(struct stream* self) } if (gnutls_error_is_fatal(rc)) { - uv_poll_stop(&self->uv_poll); + aml_stop(aml_get_default(), &self->handler); return -1; }