• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
dnn_cond_init(DNNCond * cond,const void * attr)36 static inline int dnn_cond_init(DNNCond *cond, const void *attr) { return 0; }
dnn_cond_destroy(DNNCond * cond)37 static inline int dnn_cond_destroy(DNNCond *cond) { return 0; }
dnn_cond_signal(DNNCond * cond)38 static inline int dnn_cond_signal(DNNCond *cond) { return 0; }
dnn_cond_wait(DNNCond * cond,AVMutex * mutex)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;
48     AVMutex mutex;
49     DNNCond cond;
50 };
51 
ff_safe_queue_create(void)52 SafeQueue *ff_safe_queue_create(void)
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 
ff_safe_queue_destroy(SafeQueue * sq)69 void ff_safe_queue_destroy(SafeQueue *sq)
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 
ff_safe_queue_size(SafeQueue * sq)80 size_t ff_safe_queue_size(SafeQueue *sq)
81 {
82     return sq ? ff_queue_size(sq->q) : 0;
83 }
84 
ff_safe_queue_push_front(SafeQueue * sq,void * v)85 int ff_safe_queue_push_front(SafeQueue *sq, void *v)
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 
ff_safe_queue_push_back(SafeQueue * sq,void * v)95 int ff_safe_queue_push_back(SafeQueue *sq, void *v)
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 
ff_safe_queue_pop_front(SafeQueue * sq)105 void *ff_safe_queue_pop_front(SafeQueue *sq)
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 }
117