Skip to content

Commit b042ada

Browse files
committed
fix: race condition in native library
1 parent e582486 commit b042ada

File tree

5 files changed

+65
-24
lines changed

5 files changed

+65
-24
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"cva",
44
"cx"
55
],
6-
"cmake.sourceDirectory": "/Users/aveline/Projects/JetKVM/ymjk/internal/native/cgo"
6+
"cmake.sourceDirectory": "/Users/aveline/Projects/JetKVM/ymjk/internal/native/cgo",
7+
"git.ignoreLimitWarning": true
78
}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ BUILDDATE := $(shell date -u +%FT%T%z)
33
BUILDTS := $(shell date -u +%s)
44
REVISION := $(shell git rev-parse HEAD)
55
VERSION_DEV := 0.4.8-dev$(shell date +%Y%m%d%H%M)
6-
VERSION := 0.4.7
6+
VERSION := 0.4.9
77

88
PROMETHEUS_TAG := github.com/prometheus/common/version
99
KVM_PKG_NAME := github.com/jetkvm/kvm

internal/native/cgo/video.c

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ uint32_t detected_width, detected_height;
304304
bool detected_signal = false, streaming_flag = false;
305305

306306
pthread_t *streaming_thread = NULL;
307+
pthread_mutex_t streaming_mutex = PTHREAD_MUTEX_INITIALIZER;
307308

308309
void write_buffer_to_file(const uint8_t *buffer, size_t length, const char *filename)
309310
{
@@ -388,28 +389,28 @@ void *run_video_stream(void *arg)
388389
req.count = i;
389390
return errno;
390391
}
391-
printf("VIDIOC_QUERYBUF successful for buffer %d\n", i);
392+
log_info("VIDIOC_QUERYBUF successful for buffer %d\n", i);
392393

393-
printf("plane: length = %d\n", planes_buffer->length);
394-
printf("plane: offset = %d\n", planes_buffer->m.mem_offset);
394+
log_info("plane: length = %d\n", planes_buffer->length);
395+
log_info("plane: offset = %d\n", planes_buffer->m.mem_offset);
395396

396397
MB_BLK blk = RK_MPI_MB_GetMB(memPool, (planes_buffer)->length, RK_TRUE);
397398
if (blk == NULL)
398399
{
399-
RK_LOGE("get mb blk failed!");
400+
log_error("get mb blk failed!");
400401
return -1;
401402
}
402-
printf("Got memory block for buffer %d\n", i);
403+
log_info("Got memory block for buffer %d\n", i);
403404

404405
buffers[i].mb_blk = blk;
405406

406407
RK_S32 buf_fd = (RK_MPI_MB_Handle2Fd(blk));
407408
if (buf_fd < 0)
408409
{
409-
RK_LOGE("RK_MPI_MB_Handle2Fd failed!");
410+
log_error("RK_MPI_MB_Handle2Fd failed!");
410411
return -1;
411412
}
412-
printf("Converted memory block to file descriptor for buffer %d\n", i);
413+
log_info("Converted memory block to file descriptor for buffer %d\n", i);
413414
planes_buffer->m.fd = buf_fd;
414415
}
415416

@@ -427,7 +428,7 @@ void *run_video_stream(void *arg)
427428
perror("VIDIOC_QBUF failed");
428429
return errno;
429430
}
430-
printf("VIDIOC_QBUF successful for buffer %d\n", i);
431+
log_info("VIDIOC_QBUF successful for buffer %d\n", i);
431432
}
432433

433434
if (ioctl(video_dev_fd, VIDIOC_STREAMON, &type) < 0)
@@ -472,7 +473,7 @@ void *run_video_stream(void *arg)
472473
{
473474
continue;
474475
}
475-
perror("select in video streaming");
476+
log_error("select in video streaming");
476477
break;
477478
}
478479
memset(&buf, 0, sizeof(buf));
@@ -482,7 +483,7 @@ void *run_video_stream(void *arg)
482483
buf.length = 1;
483484
if (ioctl(video_dev_fd, VIDIOC_DQBUF, &buf) < 0)
484485
{
485-
perror("VIDIOC_DQBUF failed");
486+
log_error("VIDIOC_DQBUF failed");
486487
break;
487488
}
488489
// printf("got frame, bytesused = %d\n", tmp_plane.bytesused);
@@ -518,11 +519,11 @@ void *run_video_stream(void *arg)
518519
{
519520
if (retried == true)
520521
{
521-
RK_LOGE("RK_MPI_VENC_SendFrame retry failed");
522+
log_error("RK_MPI_VENC_SendFrame retry failed");
522523
}
523524
else
524525
{
525-
RK_LOGE("RK_MPI_VENC_SendFrame failed,retrying");
526+
log_error("RK_MPI_VENC_SendFrame failed,retrying");
526527
retried = true;
527528
usleep(1000llu);
528529
goto retry_send_frame;
@@ -532,12 +533,12 @@ void *run_video_stream(void *arg)
532533
num++;
533534

534535
if (ioctl(video_dev_fd, VIDIOC_QBUF, &buf) < 0)
535-
printf("failture VIDIOC_QBUF\n");
536+
log_error("failture VIDIOC_QBUF\n");
536537
}
537538
cleanup:
538539
if (ioctl(video_dev_fd, VIDIOC_STREAMOFF, &type) < 0)
539540
{
540-
perror("VIDIOC_STREAMOFF failed");
541+
log_error("VIDIOC_STREAMOFF failed");
541542
}
542543

543544
venc_stop();
@@ -560,7 +561,7 @@ void video_shutdown()
560561
{
561562
if (should_exit == true)
562563
{
563-
printf("shutting down in progress already\n");
564+
log_info("shutting down in progress already\n");
564565
return;
565566
}
566567
video_stop_streaming();
@@ -578,14 +579,17 @@ void video_shutdown()
578579
{
579580
shutdown(sub_dev_fd, SHUT_RDWR);
580581
// close(sub_dev_fd);
581-
printf("Closed sub_dev_fd\n");
582+
log_info("Closed sub_dev_fd\n");
582583
}
583584

584585
if (memPool != MB_INVALID_POOLID)
585586
{
586587
RK_MPI_MB_DestroyPool(memPool);
587588
}
588-
printf("Destroyed memory pool\n");
589+
log_info("Destroyed memory pool\n");
590+
591+
pthread_mutex_destroy(&streaming_mutex);
592+
log_info("Destroyed streaming mutex\n");
589593
// if (format_thread != NULL) {
590594
// pthread_join(*format_thread, NULL);
591595
// free(format_thread);
@@ -594,23 +598,26 @@ void video_shutdown()
594598
// printf("Joined format detection thread\n");
595599
}
596600

597-
// TODO: mutex?
598601

599602
void video_start_streaming()
600603
{
604+
pthread_mutex_lock(&streaming_mutex);
601605
if (streaming_thread != NULL)
602606
{
603607
log_info("video streaming already started");
608+
pthread_mutex_unlock(&streaming_mutex);
604609
return;
605610
}
606611
streaming_thread = malloc(sizeof(pthread_t));
607612
assert(streaming_thread != NULL);
608613
streaming_flag = true;
609614
pthread_create(streaming_thread, NULL, run_video_stream, NULL);
615+
pthread_mutex_unlock(&streaming_mutex);
610616
}
611617

612618
void video_stop_streaming()
613619
{
620+
pthread_mutex_lock(&streaming_mutex);
614621
if (streaming_thread != NULL)
615622
{
616623
streaming_flag = false;
@@ -619,6 +626,7 @@ void video_stop_streaming()
619626
streaming_thread = NULL;
620627
log_info("video streaming stopped");
621628
}
629+
pthread_mutex_unlock(&streaming_mutex);
622630
}
623631

624632
void *run_detect_format(void *arg)
@@ -632,7 +640,7 @@ void *run_detect_format(void *arg)
632640
if (ioctl(sub_dev_fd, VIDIOC_SUBSCRIBE_EVENT, &sub) == -1)
633641
{
634642
log_error("cannot subscribe to event");
635-
perror("Cannot subscribe to event");
643+
log_error("Cannot subscribe to event");
636644
goto exit;
637645
}
638646

@@ -657,12 +665,12 @@ void *run_detect_format(void *arg)
657665
else if (errno == ERANGE)
658666
{
659667
// Timings were found, but they are out of range of the hardware capabilities.
660-
printf("HDMI status: out of range\n");
668+
log_warn("HDMI status: out of range\n");
661669
video_report_format(false, "out_of_range", 0, 0, 0);
662670
}
663671
else
664672
{
665-
perror("error VIDIOC_QUERY_DV_TIMINGS");
673+
log_error("error VIDIOC_QUERY_DV_TIMINGS");
666674
sleep(1);
667675
continue;
668676
}
@@ -681,19 +689,24 @@ void *run_detect_format(void *arg)
681689
detected_height = dv_timings.bt.height;
682690
detected_signal = true;
683691
video_report_format(true, NULL, detected_width, detected_height, frames_per_second);
692+
pthread_mutex_lock(&streaming_mutex);
684693
if (streaming_flag == true)
685694
{
695+
pthread_mutex_unlock(&streaming_mutex);
686696
log_info("restarting on going video streaming");
687697
video_stop_streaming();
688698
video_start_streaming();
689699
}
700+
else
701+
{
702+
pthread_mutex_unlock(&streaming_mutex);
703+
}
690704
}
691705

692706
memset(&ev, 0, sizeof(ev));
693707
if (ioctl(sub_dev_fd, VIDIOC_DQEVENT, &ev) != 0)
694708
{
695709
log_error("failed to VIDIOC_DQEVENT");
696-
perror("failed to VIDIOC_DQEVENT");
697710
break;
698711
}
699712
log_info("New event of type %u", ev.type);
@@ -715,12 +728,18 @@ void video_set_quality_factor(float factor)
715728

716729
// TODO: update venc bitrate without stopping streaming
717730

731+
pthread_mutex_lock(&streaming_mutex);
718732
if (streaming_flag == true)
719733
{
734+
pthread_mutex_unlock(&streaming_mutex);
720735
log_info("restarting on going video streaming due to quality factor change");
721736
video_stop_streaming();
722737
video_start_streaming();
723738
}
739+
else
740+
{
741+
pthread_mutex_unlock(&streaming_mutex);
742+
}
724743
}
725744

726745
float video_get_quality_factor() {

internal/native/native.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package native
22

33
import (
4+
"sync"
45
"time"
56

67
"github.com/Masterminds/semver/v3"
@@ -17,6 +18,7 @@ type Native struct {
1718
onVideoStateChange func(state VideoState)
1819
onVideoFrameReceived func(frame []byte, duration time.Duration)
1920
onIndevEvent func(event string)
21+
videoLock sync.Mutex
2022
}
2123

2224
type NativeOptions struct {
@@ -60,6 +62,7 @@ func NewNative(opts NativeOptions) *Native {
6062
onVideoStateChange: opts.OnVideoStateChange,
6163
onVideoFrameReceived: opts.OnVideoFrameReceived,
6264
onIndevEvent: opts.OnIndevEvent,
65+
videoLock: sync.Mutex{},
6366
}
6467
}
6568

internal/native/video.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,45 @@ type VideoState struct {
99
}
1010

1111
func (n *Native) VideoSetQualityFactor(factor float64) error {
12+
n.videoLock.Lock()
13+
defer n.videoLock.Unlock()
14+
1215
return videoSetStreamQualityFactor(factor)
1316
}
1417

1518
func (n *Native) VideoGetQualityFactor() (float64, error) {
19+
n.videoLock.Lock()
20+
defer n.videoLock.Unlock()
21+
1622
return videoGetStreamQualityFactor()
1723
}
1824

1925
func (n *Native) VideoSetEDID(edid string) error {
26+
n.videoLock.Lock()
27+
defer n.videoLock.Unlock()
28+
2029
return videoSetEDID(edid)
2130
}
2231

2332
func (n *Native) VideoGetEDID() (string, error) {
33+
n.videoLock.Lock()
34+
defer n.videoLock.Unlock()
35+
2436
return videoGetEDID()
2537
}
2638

2739
func (n *Native) VideoStop() error {
40+
n.videoLock.Lock()
41+
defer n.videoLock.Unlock()
42+
2843
videoStop()
2944
return nil
3045
}
3146

3247
func (n *Native) VideoStart() error {
48+
n.videoLock.Lock()
49+
defer n.videoLock.Unlock()
50+
3351
videoStart()
3452
return nil
3553
}

0 commit comments

Comments
 (0)