Free Electron
Spool.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __netsignal_Spool_h__
8 #define __netsignal_Spool_h__
9 
10 //#include "boost/thread.hpp"
11 //#include "boost/thread/thread.hpp"
12 //#include "boost/thread/tss.hpp"
13 //#include "boost/thread/condition.hpp"
14 namespace fe
15 {
16 namespace ext
17 {
18 
19 /** Thread safe data queue. Intended for safe communication between threads. */
20 template<class T>
21 class Spool : public Component
22 {
23  public:
24  Spool(void);
25 virtual ~Spool(void);
26 
27  sp<T> poll(void);
28  sp<T> wait(void);
29  /** Argument is a raw pointer instead of a sp<> because it may be
30  unsafe to retain references to an object passed into a Spool. */
31  void put(T *pT);
32  void interrupt(void);
33  unsigned int size(void);
34 
35  private:
36  Mutex::Condition m_readAvailable;
37  std::queue<sp<T> > m_spool;
38  Poison m_poison;
39  Mutex m_monitor;
40 };
41 
42 template<class T>
43 inline Spool<T>::Spool(void)
44 {
45 }
46 
47 template<class T>
48 inline Spool<T>::~Spool(void)
49 {
50 }
51 
52 template<class T>
53 inline sp<T> Spool<T>::poll(void)
54 {
55  Mutex::Guard guard(m_monitor);
56  sp<T> spT;
57 
58  if(!m_spool.empty())
59  {
60  spT = m_spool.front();
61  m_spool.pop();
62  }
63 
64  return spT;
65 }
66 
67 template<class T>
68 inline unsigned int Spool<T>::size(void)
69 {
70  Mutex::Guard guard(m_monitor);
71  return m_spool.size();
72 }
73 
74 template<class T>
75 inline sp<T> Spool<T>::wait(void)
76 {
77  Mutex::Guard guard(m_monitor);
78 
79  while(m_spool.empty())
80  {
81  if(m_poison.active())
82  {
83  m_poison.stop();
84 
85 // feLogGroup("netsignal","Spool throwing poison\n");
86 
87  throw Poisoned();
88  }
89  else
90  {
91  m_readAvailable.wait(guard);
92  }
93  }
94 
95  sp<T> spT = m_spool.front();
96  m_spool.pop();
97  return spT;
98 }
99 
100 template<class T>
101 inline void Spool<T>::interrupt(void)
102 {
103  Mutex::Guard guard(m_monitor);
104 
105  m_poison.start();
106  m_readAvailable.notifyAll();
107 }
108 
109 template<class T>
110 inline void Spool<T>::put(T *pT)
111 {
112  Mutex::Guard guard(m_monitor);
113 
114  sp<T> spT(pT);
115 
116  if(spT->count() > 1)
117  {
118  feX("Spool",
119  "unsafe to retain references to objects put into Spool");
120  }
121 
122  m_spool.push(spT);
123 
124  m_readAvailable.notifyOne();
125 }
126 
127 } /* namespace ext */
128 } /* namespace fe */
129 
130 #endif /* __netsignal_Spool_h__ */
131 
kernel
Definition: namespace.dox:3
Thread safe data queue.
Definition: Spool.h:21
Death pill for threads.
Definition: Poison.h:15
An exception to be thrown when active Poison has been detected.
Definition: Poison.h:30
Base for all interfacable components.
Definition: Component.h:20
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
void put(T *pT)
Argument is a raw pointer instead of a sp<> because it may be unsafe to retain references to an objec...
Definition: Spool.h:110