summaryrefslogtreecommitdiff
path: root/src/liana/vcr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/liana/vcr.c')
-rw-r--r--src/liana/vcr.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/liana/vcr.c b/src/liana/vcr.c
index f9dad7b..3a61e32 100644
--- a/src/liana/vcr.c
+++ b/src/liana/vcr.c
@@ -26,6 +26,7 @@ enum {
enum {
VCR_TRACK_RUNNING = 0,
VCR_TRACK_STOPPED,
+ VCR_TRACK_ERRORED,
VCR_TRACK_CLOSED
};
@@ -131,8 +132,8 @@ static nn_thread_result NNWT_THREADCALL vcr_track_thread(void *userdata)
nn_thread_set_priority(NNWT_THREAD_SCHED_FIFO, 32);
struct lia_vcr_track *track = (struct lia_vcr_track *)userdata;
struct lia_vcr *vcr = track->vcr;
- const char thread_name[16] = "\0"; // 16 = limit.
- al_snprintf((char *)thread_name, sizeof(thread_name), "vcr:%hu_%d", vcr->node_id, track->stream->index);
+ char thread_name[16] = "\0"; // 16 = limit.
+ al_snprintf(thread_name, sizeof(thread_name), "vcr:%hu_%d", vcr->node_id, track->stream->index);
nn_thread_set_name(thread_name);
bool corked;
@@ -177,12 +178,13 @@ static nn_thread_result NNWT_THREADCALL vcr_track_thread(void *userdata)
return_entire_cache(track);
track->cache.disabled = true;
nn_packet_cache_unlock(&track->cache);
+ // Let flush()/close() know we forcefully exited the thread.
+ track->state = VCR_TRACK_ERRORED;
nn_mutex_unlock(&track->lock);
return 0;
}
- if (!packet) {
- // Wait on EOF.
+ if (!packet) { // Wait on EOF.
track->state = VCR_TRACK_STOPPED;
}
@@ -410,6 +412,7 @@ void lia_vcr_set_buffered(struct lia_vcr_track *track)
// Meaning track->lock will be held.
void lia_vcr_cork(struct lia_vcr_track *track)
{
+ al_assert(track->state != VCR_TRACK_ERRORED);
track->state = VCR_TRACK_STOPPED;
}
@@ -422,6 +425,9 @@ void lia_vcr_uncork(struct lia_vcr_track *track)
// being held by flush(). flush() sets the state to CLOSED and signals the
// cond. Now nn_cond_is_waiting() is false at the point uncork() acquires the lock.
nn_mutex_lock(&track->lock);
+ // If a buffer is running under MARK_LOW, it will be continuously trying to uncork()
+ // the track. Meaning an erroring handle_packet() could happen at the same time as
+ // an uncork(). Causing track->state to be ERRORED after we acquire the lock here.
if (track->state != VCR_TRACK_STOPPED) {
nn_mutex_unlock(&track->lock);
return;