Home | History | Annotate | Download | only in xcore
      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