FFmpeg
safe_queue.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdio.h>
22 #include "queue.h"
23 #include "safe_queue.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/avassert.h"
26 #include "libavutil/thread.h"
27 
28 #if HAVE_PTHREAD_CANCEL
29 #define DNNCond pthread_cond_t
30 #define dnn_cond_init pthread_cond_init
31 #define dnn_cond_destroy pthread_cond_destroy
32 #define dnn_cond_signal pthread_cond_signal
33 #define dnn_cond_wait pthread_cond_wait
34 #else
35 #define DNNCond char
36 static inline int dnn_cond_init(DNNCond *cond, const void *attr) { return 0; }
37 static inline int dnn_cond_destroy(DNNCond *cond) { return 0; }
38 static inline int dnn_cond_signal(DNNCond *cond) { return 0; }
39 static inline int dnn_cond_wait(DNNCond *cond, AVMutex *mutex)
40 {
41  av_assert0(!"should not reach here");
42  return 0;
43 }
44 #endif
45 
46 struct SafeQueue {
47  Queue *q;
50 };
51 
53 {
54  SafeQueue *sq = av_malloc(sizeof(*sq));
55  if (!sq)
56  return NULL;
57 
58  sq->q = ff_queue_create();
59  if (!sq->q) {
60  av_freep(&sq);
61  return NULL;
62  }
63 
64  ff_mutex_init(&sq->mutex, NULL);
65  dnn_cond_init(&sq->cond, NULL);
66  return sq;
67 }
68 
70 {
71  if (!sq)
72  return;
73 
74  ff_queue_destroy(sq->q);
75  ff_mutex_destroy(&sq->mutex);
76  dnn_cond_destroy(&sq->cond);
77  av_freep(&sq);
78 }
79 
81 {
82  return sq ? ff_queue_size(sq->q) : 0;
83 }
84 
86 {
87  int ret;
88  ff_mutex_lock(&sq->mutex);
89  ret = ff_queue_push_front(sq->q, v);
90  dnn_cond_signal(&sq->cond);
91  ff_mutex_unlock(&sq->mutex);
92  return ret;
93 }
94 
96 {
97  int ret;
98  ff_mutex_lock(&sq->mutex);
99  ret = ff_queue_push_back(sq->q, v);
100  dnn_cond_signal(&sq->cond);
101  ff_mutex_unlock(&sq->mutex);
102  return ret;
103 }
104 
106 {
107  void *value;
108  ff_mutex_lock(&sq->mutex);
109  while (ff_queue_size(sq->q) == 0) {
110  dnn_cond_wait(&sq->cond, &sq->mutex);
111  }
112  value = ff_queue_pop_front(sq->q);
113  dnn_cond_signal(&sq->cond);
114  ff_mutex_unlock(&sq->mutex);
115  return value;
116 }
ff_mutex_init
static int ff_mutex_init(AVMutex *mutex, const void *attr)
Definition: thread.h:187
ff_queue_push_front
int ff_queue_push_front(Queue *q, void *v)
Add data to the head of the queue.
Definition: queue.c:109
ff_safe_queue_pop_front
void * ff_safe_queue_pop_front(SafeQueue *sq)
Remove and free first element from the queue in SafeQueue.
Definition: safe_queue.c:105
thread.h
ff_queue_pop_front
void * ff_queue_pop_front(Queue *q)
Remove and free first element from the Queue.
Definition: queue.c:151
ff_queue_size
size_t ff_queue_size(Queue *q)
Return the length of the Queue.
Definition: queue.c:88
SafeQueue
Double-ended queue with mutex locks ensuring data consistency while multithreading.
Definition: safe_queue.c:46
ff_safe_queue_push_front
int ff_safe_queue_push_front(SafeQueue *sq, void *v)
Add data to the head of queue in the SafeQueue after locking mutex.
Definition: safe_queue.c:85
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
dnn_cond_wait
static int dnn_cond_wait(DNNCond *cond, AVMutex *mutex)
Definition: safe_queue.c:39
ff_mutex_unlock
static int ff_mutex_unlock(AVMutex *mutex)
Definition: thread.h:189
ff_queue_create
Queue * ff_queue_create(void)
Create a Queue instance.
Definition: queue.c:47
Queue
Linear double-ended data structure.
Definition: queue.c:33
ff_queue_push_back
int ff_queue_push_back(Queue *q, void *v)
Add data to the tail of the queue.
Definition: queue.c:130
avassert.h
DNNCond
#define DNNCond
Definition: safe_queue.c:35
SafeQueue::mutex
AVMutex mutex
Definition: safe_queue.c:48
AVMutex
#define AVMutex
Definition: thread.h:184
ff_queue_destroy
void ff_queue_destroy(Queue *q)
Destroy the Queue instance.
Definition: queue.c:72
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
ff_safe_queue_size
size_t ff_safe_queue_size(SafeQueue *sq)
Return the length of the SafeQueue.
Definition: safe_queue.c:80
NULL
#define NULL
Definition: coverity.c:32
ff_safe_queue_create
SafeQueue * ff_safe_queue_create(void)
Create and initialize a SafeQueue instance.
Definition: safe_queue.c:52
dnn_cond_signal
static int dnn_cond_signal(DNNCond *cond)
Definition: safe_queue.c:38
dnn_cond_destroy
static int dnn_cond_destroy(DNNCond *cond)
Definition: safe_queue.c:37
ff_mutex_destroy
static int ff_mutex_destroy(AVMutex *mutex)
Definition: thread.h:190
dnn_cond_init
static int dnn_cond_init(DNNCond *cond, const void *attr)
Definition: safe_queue.c:36
queue.h
SafeQueue::q
Queue * q
Definition: safe_queue.c:47
ff_safe_queue_destroy
void ff_safe_queue_destroy(SafeQueue *sq)
Destroy the SafeQueue instance.
Definition: safe_queue.c:69
ff_mutex_lock
static int ff_mutex_lock(AVMutex *mutex)
Definition: thread.h:188
ff_safe_queue_push_back
int ff_safe_queue_push_back(SafeQueue *sq, void *v)
Add data to the tail of queue in the SafeQueue after locking mutex.
Definition: safe_queue.c:95
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
safe_queue.h
ret
ret
Definition: filter_design.txt:187
mem.h
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
SafeQueue::cond
DNNCond cond
Definition: safe_queue.c:49
cond
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28
mutex
static AVMutex mutex
Definition: log.c:46