• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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