Replace libuv with aml

aml
Andri Yngvason 2020-03-16 20:09:22 +00:00
parent 3b7839e53b
commit fefaf8060c
9 changed files with 106 additions and 90 deletions

View File

@ -19,7 +19,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#include <aml.h>
#include <assert.h>
#include <pixman.h>
#include <libdrm/drm_fourcc.h>
@ -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);
}

View File

@ -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,
]
)

View File

@ -17,7 +17,7 @@
#include <neatvnc.h>
#include <stdio.h>
#include <uv.h>
#include <aml.h>
#include <assert.h>
#include <pixman.h>
@ -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, &region);
pixman_region_fini(&region);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
aml_run(aml);
nvnc_close(server);
nvnc_fb_unref(fb);

View File

@ -16,7 +16,6 @@
#pragma once
#include <uv.h>
#include <stdbool.h>
#include <pixman.h>
@ -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;

View File

@ -14,8 +14,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <uv.h>
#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;

View File

@ -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()

View File

@ -8,14 +8,14 @@
#include <string.h>
#include <sys/param.h>
#include <libdrm/drm_fourcc.h>
#include <uv.h>
#include <aml.h>
#include <assert.h>
#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

View File

@ -33,10 +33,11 @@
#include <sys/queue.h>
#include <sys/param.h>
#include <assert.h>
#include <uv.h>
#include <aml.h>
#include <libdrm/drm_fourcc.h>
#include <pixman.h>
#include <pthread.h>
#include <errno.h>
#ifdef ENABLE_TLS
#include <gnutls/gnutls.h>
@ -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);

View File

@ -21,38 +21,37 @@
#include <assert.h>
#include <errno.h>
#include <sys/uio.h>
#include <uv.h>
#include <limits.h>
#include <aml.h>
#include <fcntl.h>
#include <poll.h>
#ifdef ENABLE_TLS
#include <gnutls/gnutls.h>
#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;
}