summaryrefslogtreecommitdiff
path: root/src/liana
diff options
context:
space:
mode:
Diffstat (limited to 'src/liana')
-rw-r--r--src/liana/client.c3
-rw-r--r--src/liana/handlers/cdio_server.c12
-rw-r--r--src/liana/list.c371
-rw-r--r--src/liana/list.h26
-rw-r--r--src/liana/server.c42
-rw-r--r--src/liana/server.h16
6 files changed, 373 insertions, 97 deletions
diff --git a/src/liana/client.c b/src/liana/client.c
index 55a925a..527376a 100644
--- a/src/liana/client.c
+++ b/src/liana/client.c
@@ -60,6 +60,7 @@ static void parse_info_packet(struct lia_client *client, struct aki_packet *pack
break;
case AVMEDIA_TYPE_VIDEO:
client->mask |= 1 << index;
+ //continue;
break;
case AVMEDIA_TYPE_SUBTITLE:
default:
@@ -106,7 +107,7 @@ static void info_packet_callback(void *userdata, struct aki_packet_stream *strea
struct lia_client *client = (struct lia_client *)userdata;
client->connection_id = aki_packet_read_u16(packet);
parse_info_packet(client, packet);
- al_assert(client->mask != 0);
+ //al_assert(client->mask != 0);
aki_packet_free(packet);
stream->packet_callback = data_packet_callback;
struct aki_packet *rpacket = aki_packet_create();
diff --git a/src/liana/handlers/cdio_server.c b/src/liana/handlers/cdio_server.c
index 118f6b5..d271829 100644
--- a/src/liana/handlers/cdio_server.c
+++ b/src/liana/handlers/cdio_server.c
@@ -45,14 +45,20 @@ static void cdio_server_subscribe(struct lia_server_handler *handler, s32 mask)
static u64 cdio_server_get_duration(struct lia_server_handler *handler)
{
- (void)handler;
- return 0;
+ struct lia_cdio_server *cdio = (struct lia_cdio_server *)handler;
+ struct cch_chapter *first = &al_array_at(cdio->handle->entry->chapters, 0);
+ struct cch_chapter *last = &al_array_last(cdio->handle->entry->chapters);
+ f64 seconds = camu_audio_format_bytes_to_sec(&cdio->fmt, (last->end - first->start) * CDIO_CD_FRAMESIZE_RAW);
+ al_log_info("cdio", "Length: %.2fs.", seconds);
+ return (u64)(seconds * 1000000.0);
}
static bool cdio_server_seek(struct lia_server_handler *handler, u64 pos)
{
struct lia_cdio_server *cdio = (struct lia_cdio_server *)handler;
- return cch_handle_seek(cdio->handle, pos, SEEK_SET);
+ (void)cdio;
+ (void)pos;
+ return false;
}
static void cdio_server_step(struct lia_server_handler *handler)
diff --git a/src/liana/list.c b/src/liana/list.c
index 970d247..fc34aca 100644
--- a/src/liana/list.c
+++ b/src/liana/list.c
@@ -6,16 +6,6 @@
#include "list.h"
#include "list_cmp.h"
-void lia_list_init(struct lia_list *list)
-{
- list->current = -1;
- list->previous = -1;
- list->queued = -1;
- list->idle = true;
- al_array_init(list->entries);
- al_array_init(list->sinks);
-}
-
/*
static void buffer_ahead(struct lia_list *list)
{
@@ -33,13 +23,33 @@ static void buffer_ahead(struct lia_list *list)
}
*/
-static void unset_all(struct lia_list *list)
+enum {
+ ADD_SINK = 0,
+ REMOVE_SINK,
+ ADD,
+ UNSET,
+ SKIPTO,
+ SKIP,
+ TOGGLE_PAUSE,
+ SEEK,
+ END,
+ REVERSE,
+ SORT,
+ SHUFFLE,
+ CLEAR
+};
+
+void lia_list_init(struct lia_list *list, str *name)
{
- struct lia_list_sink *sink;
- al_array_foreach(list->sinks, i, sink) {
- sink->set = -1;
- sink->queued = -1;
- }
+ al_str_clone(&list->name, name);
+ list->current = -1;
+ list->previous = -1;
+ list->queued = -1;
+ list->idle = true;
+ al_array_init(list->entries);
+ al_array_init(list->sinks);
+ al_array_init(list->queue);
+ list->cmd = NULL;
}
static bool assume_ended(struct lia_list_entry *entry, u64 at)
@@ -57,15 +67,25 @@ static bool assume_ended(struct lia_list_entry *entry, u64 at)
return false;
}
-void lia_list_add_sink(struct lia_list *list, void (*callback)(void *, u8, struct lia_list_entry *, s32, struct lia_timing *), void *userdata)
+static bool entry_load_and_get_duration(struct lia_list *list, struct lia_list_entry *entry)
+{
+ bool loaded;
+ list->callback(list->userdata, LIANA_LOAD_ENTRY, entry, &loaded);
+ if (loaded) {
+ list->callback(list->userdata, LIANA_GET_DURATION, entry, &entry->duration);
+ return true;
+ }
+ return false;
+}
+
+static bool handle_add_sink(struct lia_list *list, struct lia_list_sink *sink)
{
- struct lia_list_sink *sink = al_alloc_object(struct lia_list_sink);
- sink->callback = callback;
- sink->userdata = userdata;
- al_array_push(list->sinks, sink);
if (list->current >= 0) {
- sink->set = list->current;
struct lia_list_entry *current = al_array_at(list->entries, list->current);
+ if (!entry_load_and_get_duration(list, current)) {
+ return false;
+ }
+ sink->set = list->current;
u64 now = aki_get_timestamp();
u8 pause;
u64 at = LIANA_TIMESTAMP_INVALID;
@@ -92,9 +112,11 @@ void lia_list_add_sink(struct lia_list *list, void (*callback)(void *, u8, struc
sink->set = -1;
}
sink->queued = -1;
+ al_array_push(list->sinks, sink);
+ return true;
}
-void lia_list_remove_sink(struct lia_list *list, void *userdata)
+static void handle_remove_sink(struct lia_list *list, void *userdata)
{
struct lia_list_sink *sink;
al_array_foreach(list->sinks, i, sink) {
@@ -106,18 +128,12 @@ void lia_list_remove_sink(struct lia_list *list, void *userdata)
}
}
-void lia_list_add(struct lia_list *list, void *opaque, u64 duration, str *name)
+static bool handle_add(struct lia_list *list, struct lia_list_entry *entry)
{
- struct lia_list_entry *entry = al_alloc_object(struct lia_list_entry);
- entry->opaque = opaque;
- entry->paused_at = LIANA_TIMESTAMP_INVALID;
- entry->held = false;
- entry->offset = 0;
- entry->ended = false;
- entry->duration = duration;
- al_str_clone(&entry->name, name);
- al_array_push(list->entries, entry);
if (list->idle) {
+ if (!entry_load_and_get_duration(list, entry)) {
+ return false;
+ }
list->current++;
list->idle = false;
entry->start = aki_get_timestamp() + LIANA_BASE_DELAY;
@@ -133,10 +149,11 @@ void lia_list_add(struct lia_list *list, void *opaque, u64 duration, str *name)
sink->set = list->current;
sink->callback(sink->userdata, LIANA_SINK_SET, entry, list->current, &time);
}
- if (list->callback) list->callback(list->userdata, LIANA_META_PLAYING, entry);
+ // meta playing
} else {
/*
if (list->queued == -1) {
+ // TODODODO: this is based on addeding entry to list->entries BEFORE this point.
struct lia_list_entry *current = al_array_at(list->entries, list->current);
list->queued = list->current + 1;
entry->start = current->start + (current->duration - current->offset);
@@ -154,11 +171,22 @@ void lia_list_add(struct lia_list *list, void *opaque, u64 duration, str *name)
*/
entry->start = LIANA_TIMESTAMP_INVALID;
//}
- if (list->callback) list->callback(list->userdata, LIANA_META_QUEUED, entry);
+ // meta queued
}
+ al_array_push(list->entries, entry);
+ return true;
}
-void lia_list_unset(struct lia_list *list)
+static void unset_all(struct lia_list *list)
+{
+ struct lia_list_sink *sink;
+ al_array_foreach(list->sinks, i, sink) {
+ sink->set = -1;
+ sink->queued = -1;
+ }
+}
+
+static void handle_unset(struct lia_list *list)
{
unset_all(list);
list->current = list->entries.size - 1;
@@ -178,39 +206,40 @@ static struct lia_list_entry *get_entry_from_sequence(struct lia_list *list, s32
return al_array_at(list->entries, sequence);
}
+// TODO:
+// - Think about what is means for an entry to be done. never put into a pause state?
+// - clock_end()??
+// - Sink needs to handle case where entry gets queued but the list already expects it to be playing
+// - It's possible to know if sink->current is done during a set command, synchronously.
+// So, check that when queueing an entry.
+// - Can clock be ended during a queue command in any other case?
+// - In the simplest case of our only operation being skip, how could client's become desynced?
+// - Then with toggle pause
+// - Is it safe to assert paused state on the client.
+// - Do queued
+// - Do seek
+//if (current->start != LIANA_TIMESTAMP_INVALID && current->start > ts - LIANA_BASE_PING) {
-void lia_list_skipto(struct lia_list *list, s32 sequence, s32 index)
+static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
{
- if (index == list->current) return;
+ if (index == list->current) return true;
if (sequence == LIANA_SEQUENCE_ANY) sequence = list->current;
if (sequence == list->previous) {
// This can happen but almost certainly won't be expected behavior.
- return;
+ return true;
}
struct lia_list_entry *current = get_entry_from_sequence(list, sequence);
struct lia_list_entry *target = get_entry_from_sequence(list, index);
- if (!current || !target) return;
+ if (!current || !target) return true;
+ if (!entry_load_and_get_duration(list, target)) {
+ return false;
+ }
u64 now = aki_get_timestamp();
u64 at = now + LIANA_BASE_DELAY;
u8 pause;
- // TODO:
- // - Think about what is means for an entry to be done. never put into a pause state?
- // - clock_end()??
- // - Sink needs to handle case where entry gets queued but the list already expects it to be playing
- // - It's possible to know if sink->current is done during a set command, synchronously.
- // So, check that when queueing an entry.
- // - Can clock be ended during a queue command in any other case?
- // - In the simplest case of our only operation being skip, how could client's become desynced?
- // - Then with toggle pause
- // - Is it safe to assert paused state on the client.
- // - Do queued
- // - Do seek
-
- //if (current->start != LIANA_TIMESTAMP_INVALID && current->start > ts - LIANA_BASE_PING) {
-
// This should only happen if `start` has never been set.
if (target->start == LIANA_TIMESTAMP_INVALID && target->paused_at == LIANA_TIMESTAMP_INVALID) {
target->start = at;
@@ -264,16 +293,18 @@ void lia_list_skipto(struct lia_list *list, s32 sequence, s32 index)
sink->callback(sink->userdata, LIANA_SINK_SET, target, index, &time);
}
- list->callback(list->userdata, LIANA_META_PLAYING, target);
+ // meta playing
+
+ return true;
}
-void lia_list_skip(struct lia_list *list, s32 sequence, s32 n)
+static bool handle_skip(struct lia_list *list, s32 sequence, s32 n)
{
if (sequence == LIANA_SEQUENCE_ANY) sequence = list->current;
- lia_list_skipto(list, sequence, sequence + n);
+ return handle_skipto(list, sequence, sequence + n);
}
-void lia_list_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
+static void handle_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
{
if (sequence == LIANA_SEQUENCE_ANY) sequence = list->current;
struct lia_list_entry *current = get_entry_from_sequence(list, sequence);
@@ -284,7 +315,9 @@ void lia_list_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
u64 at;
switch (pause) {
case LIANA_PAUSE_PAUSE:
- al_assert(pts != -1.0);
+ // This assert should exist but the correct behavior for this is unfinished.
+ //al_assert(pts != -1.0);
+ (void)pts;
current->paused_at = now + LIANA_PAUSE_DELAY;
current->offset += current->paused_at - current->start;
current->start = LIANA_TIMESTAMP_INVALID;
@@ -310,9 +343,10 @@ void lia_list_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
}
}
-void lia_list_seek(struct lia_list *list, s32 sequence, f64 percent)
+static void handle_seek(struct lia_list *list, s32 sequence, f64 percent)
{
if (sequence == LIANA_SEQUENCE_ANY) sequence = list->current;
+ if (sequence < 0) return;
list->idle = false;
struct lia_list_entry *current = get_entry_from_sequence(list, sequence);
u64 pos = (u64)(current->duration * percent);
@@ -332,7 +366,7 @@ void lia_list_seek(struct lia_list *list, s32 sequence, f64 percent)
}
}
-void lia_list_end(struct lia_list *list, s32 sequence)
+static void handle_end(struct lia_list *list, s32 sequence)
{
al_assert(sequence != LIANA_SEQUENCE_ANY);
if (sequence != list->current) return;
@@ -353,11 +387,13 @@ void lia_list_end(struct lia_list *list, s32 sequence)
al_array_foreach(list->sinks, i, sink) {
sink->queued = -1;
}
- if (list->callback) {
- list->callback(list->userdata, LIANA_META_PLAYING, al_array_at(list->entries, list->current));
- }
+ // meta playing
} else if (next < size) {
- lia_list_skipto(list, sequence, next);
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = SKIPTO;
+ cmd->sequence = sequence;
+ cmd->i = next;
+ al_array_push(list->queue, cmd);
} else {
list->idle = true;
struct lia_list_sink *sink;
@@ -367,7 +403,7 @@ void lia_list_end(struct lia_list *list, s32 sequence)
}
}
-void lia_list_reverse(struct lia_list *list)
+static void handle_reverse(struct lia_list *list)
{
u32 size = list->entries.size;
for (u32 i = 0; i < size; i++) {
@@ -378,13 +414,13 @@ void lia_list_reverse(struct lia_list *list)
unset_all(list);
}
-void lia_list_sort(struct lia_list *list)
+static void handle_sort(struct lia_list *list)
{
al_array_sort(list->entries, struct lia_list_entry *, camu_db_compare);
unset_all(list);
}
-void lia_list_shuffle(struct lia_list *list)
+static void handle_shuffle(struct lia_list *list)
{
u32 size = list->entries.size;
if (size == 0) return;
@@ -395,7 +431,7 @@ void lia_list_shuffle(struct lia_list *list)
unset_all(list);
}
-void lia_list_clear(struct lia_list *list)
+static void handle_clear(struct lia_list *list)
{
struct lia_list_entry *entry;
al_array_foreach(list->entries, i, entry) {
@@ -409,6 +445,200 @@ void lia_list_clear(struct lia_list *list)
list->idle = true;
}
+static void pump_queue(struct lia_list *list)
+{
+ if (!list->cmd) {
+ if (list->queue.size == 0) return;
+ al_array_pop_at(list->queue, 0, list->cmd);
+ }
+ struct lia_list_cmd *cmd = list->cmd;
+ switch (cmd->op) {
+ case ADD_SINK:
+ if (!handle_add_sink(list, cmd->sink)) {
+ return;
+ }
+ break;
+ case REMOVE_SINK:
+ handle_remove_sink(list, cmd->userdata);
+ break;
+ case ADD:
+ if (!handle_add(list, cmd->entry)) {
+ return;
+ }
+ break;
+ case UNSET:
+ handle_unset(list);
+ break;
+ case SKIPTO:
+ if (!handle_skipto(list, cmd->sequence, cmd->i)) {
+ return;
+ }
+ break;
+ case SKIP:
+ if (!handle_skip(list, cmd->sequence, cmd->i)) {
+ return;
+ }
+ break;
+ case TOGGLE_PAUSE:
+ handle_toggle_pause(list, cmd->sequence, cmd->f);
+ break;
+ case SEEK:
+ handle_seek(list, cmd->sequence, cmd->f);
+ break;
+ case END:
+ handle_end(list, cmd->sequence);
+ break;
+ case REVERSE:
+ handle_reverse(list);
+ break;
+ case SORT:
+ handle_sort(list);
+ break;
+ case SHUFFLE:
+ handle_shuffle(list);
+ break;
+ case CLEAR:
+ handle_clear(list);
+ break;
+ }
+ al_free(cmd);
+ list->cmd = NULL;
+ pump_queue(list);
+}
+
+void lia_list_pump(struct lia_list *list)
+{
+ pump_queue(list);
+}
+
+void lia_list_add_sink(struct lia_list *list, void (*callback)(void *, u8, struct lia_list_entry *, s32, struct lia_timing *), void *userdata)
+{
+ struct lia_list_sink *sink = al_alloc_object(struct lia_list_sink);
+ sink->callback = callback;
+ sink->userdata = userdata;
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = ADD_SINK;
+ cmd->sink = sink;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_remove_sink(struct lia_list *list, void *userdata)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = REMOVE_SINK;
+ cmd->userdata = userdata;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_add(struct lia_list *list, void *opaque, u64 duration, str *name)
+{
+ struct lia_list_entry *entry = al_alloc_object(struct lia_list_entry);
+ entry->opaque = opaque;
+ entry->paused_at = LIANA_TIMESTAMP_INVALID;
+ entry->held = false;
+ entry->offset = 0;
+ entry->ended = false;
+ entry->duration = duration;
+ al_str_clone(&entry->name, name);
+ entry->list = list;
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = ADD;
+ cmd->entry = entry;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_unset(struct lia_list *list)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = UNSET;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_skipto(struct lia_list *list, s32 sequence, s32 index)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = SKIPTO;
+ cmd->sequence = sequence;
+ cmd->i = index;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_skip(struct lia_list *list, s32 sequence, s32 n)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = SKIP;
+ cmd->sequence = sequence;
+ cmd->i = n;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = TOGGLE_PAUSE;
+ cmd->sequence = sequence;
+ cmd->f = pts;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_seek(struct lia_list *list, s32 sequence, f64 percent)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = SEEK;
+ cmd->sequence = sequence;
+ cmd->f = percent;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_end(struct lia_list *list, s32 sequence)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = END;
+ cmd->sequence = sequence;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_reverse(struct lia_list *list)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = REVERSE;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_sort(struct lia_list *list)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = SORT;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_shuffle(struct lia_list *list)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = SHUFFLE;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
+void lia_list_clear(struct lia_list *list)
+{
+ struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
+ cmd->op = CLEAR;
+ al_array_push(list->queue, cmd);
+ pump_queue(list);
+}
+
void lia_list_free(struct lia_list *list)
{
struct lia_list_entry *entry;
@@ -422,4 +652,5 @@ void lia_list_free(struct lia_list *list)
al_free(sink);
}
al_array_free(list->sinks);
+ al_str_free(&list->name);
}
diff --git a/src/liana/list.h b/src/liana/list.h
index 5e3eaec..270ef98 100644
--- a/src/liana/list.h
+++ b/src/liana/list.h
@@ -25,14 +25,10 @@ enum {
enum {
LIANA_LOAD_ENTRY = 0,
+ LIANA_GET_DURATION,
LIANA_UNLOAD_ENTRY
};
-enum {
- LIANA_META_PLAYING = 0,
- LIANA_META_QUEUED
-};
-
// NOTE: To handle an entry being queued right before a skip, keep a global
// "max time until all sinks buffered" and used that instead of LIANA_PAUSE_DELAY (if greater).
@@ -61,6 +57,7 @@ struct lia_list_entry {
bool ended;
u64 duration;
str name;
+ struct lia_list *list;
};
struct lia_list_sink {
@@ -70,18 +67,33 @@ struct lia_list_sink {
void *userdata;
};
+struct lia_list_cmd {
+ u8 op;
+ struct lia_list_sink *sink;
+ void *userdata;
+ struct lia_list_entry *entry;
+ s32 sequence;
+ s32 i;
+ f64 f;
+};
+
struct lia_list {
+ str name;
s32 current;
s32 previous;
s32 queued;
bool idle;
array(struct lia_list_entry *) entries;
array(struct lia_list_sink *) sinks;
- void (*callback)(void *, u8, struct lia_list_entry *);
+ array(struct lia_list_cmd *) queue;
+ struct lia_list_cmd *cmd;
+ void (*callback)(void *, u8, struct lia_list_entry *, void *);
void *userdata;
};
-void lia_list_init(struct lia_list *list);
+void lia_list_init(struct lia_list *list, str *name);
+
+void lia_list_pump(struct lia_list *list);
void lia_list_add_sink(struct lia_list *list, void (*callback)(void *, u8, struct lia_list_entry *, s32, struct lia_timing *), void *userdata);
void lia_list_remove_sink(struct lia_list *list, void *userdata);
diff --git a/src/liana/server.c b/src/liana/server.c
index 3eb303e..ccca0fd 100644
--- a/src/liana/server.c
+++ b/src/liana/server.c
@@ -289,23 +289,35 @@ struct lia_node *lia_server_create_node(struct lia_server *server, struct cch_en
return node;
}
-u64 lia_node_get_duration(struct lia_node *node)
+static aki_thread_result AKI_THREADCALL init_duration_thread(void *userdata)
{
- (void)node;
-#if 0
- return 0;
-#else
- struct cch_handle handle;
- cch_entry_get_handle(node->entry, &handle);
- struct lia_server_handler *handler = lia_handler_by_name(cch_entry_get_liana(node->entry))->create_server_handler();
- if (!handler->init(handler, &handle)) {
- return LIANA_TIMESTAMP_INVALID;
+ struct lia_node *node = (struct lia_node *)userdata;
+ if (!node->handler->init(node->handler, &node->handle)) {
+ node->errored = true;
+ } else {
+ node->duration = node->handler->get_duration(node->handler);
}
- u64 duration = handler->get_duration(handler);
- handler->free(&handler);
- cch_entry_return_handle(node->entry, &handle);
- return duration;
-#endif
+ aki_signal_send(&node->signal);
+ return 0;
+}
+
+static void duration_signal_callback(void *userdata)
+{
+ struct lia_node *node = (struct lia_node *)userdata;
+ aki_signal_stop(&node->signal);
+ aki_thread_join(&node->thread);
+ node->handler->free(&node->handler);
+ cch_entry_return_handle(node->entry, &node->handle);
+ node->callback(node->userdata, LIANA_NODE_DURATION, node->duration);
+}
+
+void lia_node_get_duration(struct lia_node *node)
+{
+ aki_signal_init(&node->signal, duration_signal_callback, node);
+ aki_signal_start(&node->signal, node->server->loop);
+ cch_entry_get_handle(node->entry, &node->handle);
+ node->handler = lia_handler_by_name(cch_entry_get_liana(node->entry))->create_server_handler();
+ aki_thread_create(&node->thread, init_duration_thread, node);
}
void lia_server_close(struct lia_server *server)
diff --git a/src/liana/server.h b/src/liana/server.h
index 3c4c294..2ed7c12 100644
--- a/src/liana/server.h
+++ b/src/liana/server.h
@@ -21,11 +21,25 @@ struct lia_node_connection {
struct lia_node *node;
};
+enum {
+ LIANA_NODE_DURATION = 0
+};
+
struct lia_node {
u16 id;
struct cch_entry *entry;
array(struct lia_node_connection *) connections;
struct lia_server *server;
+ u64 duration;
+ // Temporary copy from node_connection. We need to
+ // figure out a "connection pool" structure.
+ struct lia_server_handler *handler;
+ bool errored;
+ struct cch_handle handle;
+ struct aki_thread thread;
+ struct aki_signal signal;
+ void (*callback)(void *, u8, u64);
+ void *userdata;
};
struct lia_server {
@@ -37,6 +51,6 @@ struct lia_server {
bool lia_server_init(struct lia_server *server, struct aki_event_loop *loop);
void lia_server_add_socket(struct lia_server *server, struct aki_socket *sock);
struct lia_node *lia_server_create_node(struct lia_server *server, struct cch_entry *entry);
-u64 lia_node_get_duration(struct lia_node *node);
+void lia_node_get_duration(struct lia_node *node);
void lia_server_close(struct lia_server *server);
void lia_server_free(struct lia_server *server);