1 /*
2 * safe_list.h - safe list template
3 *
4 * Copyright (c) 2014 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20
21 #ifndef XCAM_SAFE_LIST_H
22 #define XCAM_SAFE_LIST_H
23
24 #include <base/xcam_defs.h>
25 #include <base/xcam_common.h>
26 #include <errno.h>
27 #include <list>
28 #include <xcam_mutex.h>
29
30 namespace XCam {
31
32 template<class OBj>
33 class SafeList {
34 public:
35 typedef SmartPtr<OBj> ObjPtr;
36 typedef std::list<ObjPtr> ObjList;
37 typedef typename std::list<typename SafeList<OBj>::ObjPtr>::iterator ObjIter;
38
SafeList()39 SafeList ()
40 : _pop_paused (false)
41 {}
~SafeList()42 ~SafeList () {
43 }
44
45 /*
46 * timeout, -1, wait until wakeup
47 * >=0, wait for @timeout microsseconds
48 */
49 inline ObjPtr pop (int32_t timeout = -1);
50 inline bool push (const ObjPtr &obj);
51 inline bool erase (const ObjPtr &obj);
52 inline ObjPtr front ();
size()53 uint32_t size () {
54 SmartLock lock(_mutex);
55 return _obj_list.size();
56 }
is_empty()57 bool is_empty () {
58 SmartLock lock(_mutex);
59 return _obj_list.empty();
60 }
wakeup()61 void wakeup () {
62 _new_obj_cond.broadcast ();
63 }
pause_pop()64 void pause_pop () {
65 SmartLock lock(_mutex);
66 _pop_paused = true;
67 wakeup ();
68 }
resume_pop()69 void resume_pop () {
70 SmartLock lock(_mutex);
71 _pop_paused = false;
72 }
73 inline void clear ();
74
75 protected:
76 ObjList _obj_list;
77 Mutex _mutex;
78 XCam::Cond _new_obj_cond;
79 volatile bool _pop_paused;
80 };
81
82
83 template<class OBj>
84 typename SafeList<OBj>::ObjPtr
pop(int32_t timeout)85 SafeList<OBj>::pop (int32_t timeout)
86 {
87 SmartLock lock (_mutex);
88 int code = 0;
89
90 while (!_pop_paused && _obj_list.empty() && code == 0) {
91 if (timeout < 0)
92 code = _new_obj_cond.wait(_mutex);
93 else
94 code = _new_obj_cond.timedwait(_mutex, timeout);
95 }
96
97 if (_pop_paused)
98 return NULL;
99
100 if (_obj_list.empty()) {
101 if (code == ETIMEDOUT) {
102 XCAM_LOG_DEBUG ("safe list pop timeout");
103 } else {
104 XCAM_LOG_ERROR ("safe list pop failed, code:%d", code);
105 }
106 return NULL;
107 }
108
109 SafeList<OBj>::ObjPtr obj = *_obj_list.begin ();
110 _obj_list.erase (_obj_list.begin ());
111 return obj;
112 }
113
114 template<class OBj>
115 bool
push(const SafeList<OBj>::ObjPtr & obj)116 SafeList<OBj>::push (const SafeList<OBj>::ObjPtr &obj)
117 {
118 SmartLock lock (_mutex);
119 _obj_list.push_back (obj);
120 _new_obj_cond.signal ();
121 return true;
122 }
123
124 template<class OBj>
125 bool
erase(const SafeList<OBj>::ObjPtr & obj)126 SafeList<OBj>::erase (const SafeList<OBj>::ObjPtr &obj)
127 {
128 XCAM_ASSERT (obj.ptr ());
129 SmartLock lock (_mutex);
130 for (SafeList<OBj>::ObjIter i_obj = _obj_list.begin ();
131 i_obj != _obj_list.end (); ++i_obj) {
132 if ((*i_obj).ptr () == obj.ptr ()) {
133 _obj_list.erase (i_obj);
134 return true;
135 }
136 }
137 return false;
138 }
139
140 template<class OBj>
141 typename SafeList<OBj>::ObjPtr
front()142 SafeList<OBj>::front ()
143 {
144 SmartLock lock (_mutex);
145 SafeList<OBj>::ObjIter i = _obj_list.begin ();
146 if (i == _obj_list.end ())
147 return NULL;
148 return *i;
149 }
150
151 template<class OBj>
clear()152 void SafeList<OBj>::clear ()
153 {
154 SmartLock lock (_mutex);
155 SafeList<OBj>::ObjIter i_obj = _obj_list.begin ();
156 while (i_obj != _obj_list.end ()) {
157 _obj_list.erase (i_obj++);
158 }
159 }
160
161 };
162 #endif //XCAM_SAFE_LIST_H
163