LCOV - code coverage report
Current view: top level - netserver - queue.h (source / functions) Hit Total Coverage
Test: CoherentDB code coverage Lines: 16 17 94.1 %
Date: 2011-02-13 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * (C) Copyright 2010 Cezary Bartoszuk, Michał Stachurski, Rafał Rawicki
       3             :  *
       4             :  * This file is part of CoherentDB.
       5             :  *
       6             :  * CoherentDB is free software: you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation, either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * CoherentDB is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public
      17             :  * License along with CoherentDB. If not, see
      18             :  * http://www.gnu.org/licenses/.
      19             :  */
      20             : 
      21             : #ifndef __COHERENT_NETSERVER_QUEUE_H__
      22             : #define __COHERENT_NETSERVER_QUEUE_H__
      23             : 
      24             : #include <memory>
      25             : #include <deque>
      26             : #include <boost/function.hpp>
      27             : #include <boost/thread.hpp>
      28             : 
      29             : namespace coherent
      30             : {
      31             : namespace netserver
      32             : {
      33             : 
      34             : template<typename element_t>
      35             : class simple_ptr_wrapper
      36             : {
      37             : public:
      38             :     typedef element_t * ptr_t;
      39             : };
      40             : 
      41             : template<typename element_t>
      42             : class no_wrapper
      43             : {
      44             : public:
      45             :     typedef element_t ptr_t;
      46             : };
      47             : 
      48             : // Synchronized queue. Stores pointers to `element_t` type elements
      49             : // with producer-consumer synchronization on `pop` and `push`.
      50             : // Exception safe.
      51             : template <
      52             :     typename element_t,
      53             :     template <typename, typename> class container_template = ::std::deque,
      54             :     template <typename> class ptr_wrapper_template = simple_ptr_wrapper,
      55             :     template <typename> class allocator_template = ::std::allocator
      56             :     >
      57             : class queue
      58             : {
      59             : public:
      60             :     typedef typename ptr_wrapper_template<element_t>::ptr_t element_ptr_t;
      61             :     typedef allocator_template<element_ptr_t> element_ptr_allocator_t;
      62             :     typedef container_template<element_ptr_t, element_ptr_allocator_t> container_t;
      63             : private:
      64             :     typedef ::boost::mutex mutex_t;
      65             :     typedef ::boost::condition_variable condition_t;
      66             :     typedef ::boost::unique_lock<mutex_t> unique_lock_t;
      67             :     typedef ::boost::lock_guard<mutex_t> lock_guard_t;
      68             : private:
      69             :     condition_t condition;
      70             :     mutex_t mutex;
      71             :     container_t container;
      72             : public:
      73             :     queue();
      74             :     ~queue();
      75             :     element_ptr_t pop();
      76             :     void push(element_ptr_t element_ptr);
      77             :     bool empty();
      78             : };
      79             : 
      80             : template <
      81             :     typename element_t,
      82             :     template <typename, typename> class container_template,
      83             :     template <typename> class ptr_wrapper_template,
      84             :     template <typename> class allocator_template
      85             :     >
      86             : queue<element_t, container_template, ptr_wrapper_template, allocator_template>::queue()
      87             :   : condition(),
      88             :     mutex(),
      89             :     container()
      90             : {
      91             : }
      92           1 : 
      93             : template <
      94             :     typename element_t,
      95           1 :     template <typename, typename> class container_template,
      96             :     template <typename> class ptr_wrapper_template,
      97           1 :     template <typename> class allocator_template
      98             :     >
      99             : queue<element_t, container_template, ptr_wrapper_template, allocator_template>::~queue()
     100             : {
     101             : }
     102             : 
     103             : template <
     104             :     typename element_t,
     105             :     template <typename, typename> class container_template,
     106           1 :     template <typename> class ptr_wrapper_template,
     107             :     template <typename> class allocator_template
     108           1 :     >
     109             : typename queue<element_t, container_template, ptr_wrapper_template, allocator_template>::element_ptr_t queue<element_t, container_template, ptr_wrapper_template, allocator_template>::pop()
     110             : {
     111             :     unique_lock_t lock(mutex);
     112             :     while(container.empty())
     113             :     {
     114             :         condition.wait(lock);
     115             :     }
     116             :     element_ptr_t element_ptr = container.front();
     117       10000 :     container.pop_front();
     118             :     return element_ptr;
     119       20000 : }
     120       10000 : 
     121             : template <
     122           0 :     typename element_t,
     123             :     template <typename, typename> class container_template,
     124       10000 :     template <typename> class ptr_wrapper_template,
     125       10000 :     template <typename> class allocator_template
     126       10000 :     >
     127             : void queue<element_t, container_template, ptr_wrapper_template, allocator_template>::push(element_ptr_t element_ptr)
     128             : {
     129             :     {
     130             :         lock_guard_t lock(mutex);
     131             :         container.push_back(element_ptr);
     132             :     }
     133             :     condition.notify_one();
     134             : }
     135             : 
     136       10000 : template <
     137             :     typename element_t,
     138             :     template <typename, typename> class container_template,
     139       20000 :     template <typename> class ptr_wrapper_template,
     140       10000 :     template <typename> class allocator_template
     141             :     >
     142       10000 : bool queue<element_t, container_template, ptr_wrapper_template, allocator_template>::empty()
     143       10000 : {
     144             :     unique_lock_t lock(mutex);
     145             :     return container.empty();
     146             : }
     147             : 
     148             : }  // namespace netserver
     149             : }  // namespace coherent
     150             : 
     151             : #endif

Generated by: LCOV version 1.9