From d24297abf4390e88a972e67ba3fb35fe688d831f Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 12 Apr 2016 01:07:39 -0400 Subject: multipart-replace: use condition variables instead of polling --- src/multipart-replace.c | 22 ++++++++-------------- src/multipart-replace.h | 3 ++- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/multipart-replace.c b/src/multipart-replace.c index facca62..1f7a75c 100644 --- a/src/multipart-replace.c +++ b/src/multipart-replace.c @@ -127,7 +127,7 @@ int multipart_replace_reader(struct multipart_replace_stream *s, int fd, const c struct frame *tmp = s->front; s->front = s->back; s->back = tmp; - s->framecount++; + pthread_cond_broadcast(&s->newframe); pthread_rwlock_unlock(&s->frontlock); } end: @@ -141,17 +141,17 @@ int multipart_replace_writer(struct multipart_replace_stream *s, int fd, const c int ret = 0; FILE *stream = fdopen(fd, "w"); struct frame myframe = { 0 }; - long lastframe = 0; char *boundary = boundary_line(_boundary); size_t boundary_len = strlen(boundary); - pthread_rwlock_rdlock(&s->frontlock); while (running) { + pthread_cond_wait(&s->newframe, &s->newframe_lock); + /* get the most recent frame (copy `s->front` to `myframe`) */ + pthread_rwlock_rdlock(&s->frontlock); if (myframe.cap < (size_t)s->front->len) myframe.buf = xrealloc(myframe.buf, myframe.cap = s->front->len); memcpy(myframe.buf, s->front->buf, myframe.len = s->front->len); - lastframe = s->framecount; pthread_rwlock_unlock(&s->frontlock); @@ -166,16 +166,7 @@ int multipart_replace_writer(struct multipart_replace_stream *s, int fd, const c stdioerror(stream, "dst <- nl"); fflush(stream); } - - /* poll until there's a new frame */ - pthread_rwlock_rdlock(&s->frontlock); - while (s->framecount == lastframe && running) { - pthread_rwlock_unlock(&s->frontlock); - usleep(30000); /* a bit over 30 FPS */ - pthread_rwlock_rdlock(&s->frontlock); - } } - pthread_rwlock_unlock(&s->frontlock); end: free(boundary); free(myframe.buf); @@ -189,11 +180,14 @@ void init_multipart_replace_stream(struct multipart_replace_stream *s) { s->front = &s->a; s->back = &s->b; pthread_rwlock_init(&s->frontlock, NULL); - s->framecount = 0; + pthread_cond_init(&s->newframe, NULL); + pthread_mutex_init(&s->newframe_lock, NULL); } void destroy_multipart_replace_stream(struct multipart_replace_stream *s) { free(s->a.buf); free(s->b.buf); pthread_rwlock_destroy(&s->frontlock); + pthread_cond_destroy(&s->newframe); + pthread_mutex_destroy(&s->newframe_lock); } diff --git a/src/multipart-replace.h b/src/multipart-replace.h index e4cced0..d302c5f 100644 --- a/src/multipart-replace.h +++ b/src/multipart-replace.h @@ -31,7 +31,8 @@ struct multipart_replace_stream { struct frame a, b; struct frame *front, *back; pthread_rwlock_t frontlock; - long framecount; + pthread_cond_t newframe; + pthread_mutex_t newframe_lock; }; int multipart_replace_reader(struct multipart_replace_stream *s, int fd, const char *boundary); -- cgit v1.2.3