Clone
ixen <ixen@copyhandler.com>
committed
on 20 Nov 16
Buggy prototype of reader parallelization (CH-307).
ParallelizeReaderWriter + 3 more
src/libchcore/TBufferList.cpp (+33 -13)
2 2 //  Copyright (C) 2001-2016 by Jozef Starosczyk
3 3 //  ixen@copyhandler.com
4 4 //
5 5 //  This program is free software; you can redistribute it and/or modify
6 6 //  it under the terms of the GNU Library General Public License
7 7 //  (version 2) as published by the Free Software Foundation;
8 8 //
9 9 //  This program is distributed in the hope that it will be useful,
10 10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 12 //  GNU General Public License for more details.
13 13 //
14 14 //  You should have received a copy of the GNU Library General Public
15 15 //  License along with this program; if not, write to the
16 16 //  Free Software Foundation, Inc.,
17 17 //  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 18 // ============================================================================
19 19 #include "stdafx.h"
20 20 #include "TBufferList.h"
21 21 #include "TCoreException.h"
  22 #include <boost/thread/locks.hpp>
22 23
23 24 namespace chcore
24 25 {
25 26         TBufferList::TBufferList() :
26 27                 m_eventAllBuffersAccountedFor(true, true)
27 28         {
28 29         }
29 30
30 31         void TBufferList::Push(TOverlappedDataBuffer* pBuffer)
31 32         {
32 33                 if(!pBuffer)
33 34                         throw TCoreException(eErr_InvalidArgument, L"pBuffer", LOCATION);
34 35
  36                 {
  37                         boost::unique_lock<boost::shared_mutex> lock(m_mutex);
  38
35 39                         m_listBuffers.push_front(pBuffer);
36 40                         UpdateEvent();
  41                 }
  42
37 43                 m_notifier();
38 44         }
39 45
40 46         TOverlappedDataBuffer* TBufferList::Pop()
41 47         {
  48                 TOverlappedDataBuffer* pBuffer = nullptr;
  49
  50                 {
  51                         boost::unique_lock<boost::shared_mutex> lock(m_mutex);
  52
42 53                         if(m_listBuffers.empty())
43 54                                 return nullptr;
44 55
45                   TOverlappedDataBuffer* pBuffer = m_listBuffers.front();
  56                         pBuffer = m_listBuffers.front();
46 57                         m_listBuffers.pop_front();
47 58
48 59                         UpdateEvent();
  60                 }
49 61
50 62                 m_notifier();
51 63
52 64                 return pBuffer;
53 65         }
54 66
55 67         void TBufferList::Clear()
56 68         {
57                   bool bRemoved = !m_listBuffers.empty();
  69                 bool bRemoved = false;
  70                 {
  71                         boost::unique_lock<boost::shared_mutex> lock(m_mutex);
  72
  73                         bRemoved = !m_listBuffers.empty();
58 74                         m_listBuffers.clear();
59 75
60 76                         if(bRemoved)
61                   {
62 77                                 UpdateEvent();
  78                 }
  79
  80                 if(bRemoved)
63 81                         m_notifier();
64 82         }
65           }
66 83
67 84         size_t TBufferList::GetCount() const
68 85         {
  86                 boost::shared_lock<boost::shared_mutex> lock(m_mutex);
69 87                 return m_listBuffers.size();
70 88         }
71 89
72 90         bool TBufferList::IsEmpty() const
73 91         {
  92                 boost::shared_lock<boost::shared_mutex> lock(m_mutex);
74 93                 return m_listBuffers.empty();
75 94         }
76 95
77 96         void TBufferList::SetExpectedBuffersCount(size_t stExpectedBuffers)
78 97         {
  98                 boost::shared_lock<boost::shared_mutex> lock(m_mutex);
79 99                 m_stExpectedBuffers = stExpectedBuffers;
80 100                 UpdateEvent();
81 101         }
82 102
83 103         HANDLE TBufferList::GetAllBuffersAccountedForEvent() const
84 104         {
85 105                 return m_eventAllBuffersAccountedFor.Handle();
86 106         }
87 107
88 108         boost::signals2::signal<void()>& TBufferList::GetNotifier()
89 109         {
90 110                 return m_notifier;
91 111         }
92 112
93 113         void TBufferList::UpdateEvent()
94 114         {
95 115                 m_eventAllBuffersAccountedFor.SetEvent(m_listBuffers.size() == m_stExpectedBuffers);
96 116         }
97 117 }