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 (at) 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 39 SafeList () 40 : _pop_paused (false) 41 {} 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 (); 53 uint32_t size () { 54 SmartLock lock(_mutex); 55 return _obj_list.size(); 56 } 57 bool is_empty () { 58 SmartLock lock(_mutex); 59 return _obj_list.empty(); 60 } 61 void wakeup () { 62 _new_obj_cond.broadcast (); 63 } 64 void pause_pop () { 65 SmartLock lock(_mutex); 66 _pop_paused = true; 67 wakeup (); 68 } 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 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 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 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 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> 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