Crypto++  5.6.3
Free C++ class library of cryptographic schemes
wait.h
1 #ifndef CRYPTOPP_WAIT_H
2 #define CRYPTOPP_WAIT_H
3 
4 #include "config.h"
5 
6 #ifdef SOCKETS_AVAILABLE
7 
8 #include "misc.h"
9 #include "cryptlib.h"
10 #include <vector>
11 
12 #ifdef USE_WINDOWS_STYLE_SOCKETS
13 #include <winsock2.h>
14 #else
15 #include <sys/types.h>
16 #include <sys/select.h>
17 #endif
18 
19 #include "hrtimer.h"
20 
21 #if defined(__has_feature)
22 # if __has_feature(memory_sanitizer)
23 # define CRYPTOPP_MSAN 1
24 # endif
25 #endif
26 
27 NAMESPACE_BEGIN(CryptoPP)
28 
29 class Tracer
30 {
31 public:
32  Tracer(unsigned int level) : m_level(level) {}
33  virtual ~Tracer() {}
34 
35 protected:
36  //! Override this in your most-derived tracer to do the actual tracing.
37  virtual void Trace(unsigned int n, std::string const& s) = 0;
38 
39  /*! By default, tracers will decide which trace messages to trace according to a trace level
40  mechanism. If your most-derived tracer uses a different mechanism, override this to
41  return false. If this method returns false, the default TraceXxxx(void) methods will all
42  return 0 and must be overridden explicitly by your tracer for trace messages you want. */
43  virtual bool UsingDefaults() const { return true; }
44 
45 protected:
46  unsigned int m_level;
47 
48  void TraceIf(unsigned int n, std::string const&s)
49  { if (n) Trace(n, s); }
50 
51  /*! Returns nr if, according to the default log settings mechanism (using log levels),
52  the message should be traced. Returns 0 if the default trace level mechanism is not
53  in use, or if it is in use but the event should not be traced. Provided as a utility
54  method for easier and shorter coding of default TraceXxxx(void) implementations. */
55  unsigned int Tracing(unsigned int nr, unsigned int minLevel) const
56  { return (UsingDefaults() && m_level >= minLevel) ? nr : 0; }
57 };
58 
59 // Your Tracer-derived class should inherit as virtual public from Tracer or another
60 // Tracer-derived class, and should pass the log level in its constructor. You can use the
61 // following methods to begin and end your Tracer definition.
62 
63 // This constructor macro initializes Tracer directly even if not derived directly from it;
64 // this is intended, virtual base classes are always initialized by the most derived class.
65 #define CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) \
66  public: DERIVED(unsigned int level = 0) : Tracer(level) {}
67 
68 #define CRYPTOPP_BEGIN_TRACER_CLASS_1(DERIVED, BASE1) \
69  class DERIVED : virtual public BASE1, public NotCopyable { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED)
70 
71 #define CRYPTOPP_BEGIN_TRACER_CLASS_2(DERIVED, BASE1, BASE2) \
72  class DERIVED : virtual public BASE1, virtual public BASE2, public NotCopyable { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED)
73 
74 #define CRYPTOPP_END_TRACER_CLASS };
75 
76 // In your Tracer-derived class, you should define a globally unique event number for each
77 // new event defined. This can be done using the following macros.
78 
79 #define CRYPTOPP_BEGIN_TRACER_EVENTS(UNIQUENR) enum { EVENTBASE = UNIQUENR,
80 #define CRYPTOPP_TRACER_EVENT(EVENTNAME) EventNr_##EVENTNAME,
81 #define CRYPTOPP_END_TRACER_EVENTS };
82 
83 // In your own Tracer-derived class, you must define two methods per new trace event type:
84 // - unsigned int TraceXxxx() const
85 // Your default implementation of this method should return the event number if according
86 // to the default trace level system the event should be traced, or 0 if it should not.
87 // - void TraceXxxx(string const& s)
88 // This method should call TraceIf(TraceXxxx(), s); to do the tracing.
89 // For your convenience, a macro to define these two types of methods are defined below.
90 // If you use this macro, you should also use the TRACER_EVENTS macros above to associate
91 // event names with numbers.
92 
93 #define CRYPTOPP_TRACER_EVENT_METHODS(EVENTNAME, LOGLEVEL) \
94  virtual unsigned int Trace##EVENTNAME() const { return Tracing(EventNr_##EVENTNAME, LOGLEVEL); } \
95  virtual void Trace##EVENTNAME(std::string const& s) { TraceIf(Trace##EVENTNAME(), s); }
96 
97 
98 /*! A simple unidirectional linked list with m_prev == 0 to indicate the final entry.
99  The aim of this implementation is to provide a very lightweight and practical
100  tracing mechanism with a low performance impact. Functions and methods supporting
101  this call-stack mechanism would take a parameter of the form "CallStack const& callStack",
102  and would pass this parameter to subsequent functions they call using the construct:
103 
104  SubFunc(arg1, arg2, CallStack("my func at place such and such", &callStack));
105 
106  The advantage of this approach is that it is easy to use and should be very efficient,
107  involving no allocation from the heap, just a linked list of stack objects containing
108  pointers to static ASCIIZ strings (or possibly additional but simple data if derived). */
110 {
111 public:
112  CallStack(char const* i, CallStack const* p) : m_info(i), m_prev(p) {}
113  CallStack const* Prev() const { return m_prev; }
114  virtual std::string Format() const;
115 
116 protected:
117  char const* m_info;
118  CallStack const* m_prev;
119 };
120 
121 /*! An extended CallStack entry type with an additional numeric parameter. */
123 {
124 public:
125  CallStackWithNr(char const* i, word32 n, CallStack const* p) : CallStack(i, p), m_nr(n) {}
126  std::string Format() const;
127 
128 protected:
129  word32 m_nr;
130 };
131 
132 /*! An extended CallStack entry type with an additional string parameter. */
134 {
135 public:
136  CallStackWithStr(char const* i, char const* z, CallStack const* p) : CallStack(i, p), m_z(z) {}
137  std::string Format() const;
138 
139 protected:
140  char const* m_z;
141 };
142 
143 // Thanks to Maximilian Zamorsky for help with http://connect.microsoft.com/VisualStudio/feedback/details/1570496/
144 CRYPTOPP_BEGIN_TRACER_CLASS_1(WaitObjectsTracer, Tracer)
145  CRYPTOPP_BEGIN_TRACER_EVENTS(0x48752841)
146  CRYPTOPP_TRACER_EVENT(NoWaitLoop)
147  CRYPTOPP_END_TRACER_EVENTS
148  CRYPTOPP_TRACER_EVENT_METHODS(NoWaitLoop, 1)
149 CRYPTOPP_END_TRACER_CLASS
150 
151 struct WaitingThreadData;
152 
153 //! container of wait objects
155 {
156 public:
157  //! exception thrown by WaitObjectContainer
158  class Err : public Exception
159  {
160  public:
161  Err(const std::string& s) : Exception(IO_ERROR, s) {}
162  };
163 
164  static unsigned int MaxWaitObjects();
165 
167 
168  void Clear();
169  void SetNoWait(CallStack const& callStack);
170  void ScheduleEvent(double milliseconds, CallStack const& callStack);
171  // returns false if timed out
172  bool Wait(unsigned long milliseconds);
173 
174 #ifdef USE_WINDOWS_STYLE_SOCKETS
175 # ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
176  virtual ~WaitObjectContainer();
177 # else
179 #endif
180  void AddHandle(HANDLE handle, CallStack const& callStack);
181 #else
182  void AddReadFd(int fd, CallStack const& callStack);
183  void AddWriteFd(int fd, CallStack const& callStack);
184 #endif
185 
186 private:
187  WaitObjectsTracer* m_tracer;
188 
189 #ifdef USE_WINDOWS_STYLE_SOCKETS
190  void CreateThreads(unsigned int count);
191  std::vector<HANDLE> m_handles;
192  std::vector<WaitingThreadData *> m_threads;
193  HANDLE m_startWaiting;
194  HANDLE m_stopWaiting;
195 #else
196  fd_set m_readfds, m_writefds;
197  int m_maxFd;
198 #endif
199  bool m_noWait;
200  double m_firstEventTime;
201  Timer m_eventTimer;
202 
203 #ifdef USE_WINDOWS_STYLE_SOCKETS
204  typedef size_t LastResultType;
205 #else
206  typedef int LastResultType;
207 #endif
208  enum { LASTRESULT_NOWAIT = -1, LASTRESULT_SCHEDULED = -2, LASTRESULT_TIMEOUT = -3 };
209  LastResultType m_lastResult;
210  unsigned int m_sameResultCount;
211  Timer m_noWaitTimer;
212  void SetLastResult(LastResultType result);
213  void DetectNoWait(LastResultType result, CallStack const& callStack);
214 };
215 
216 NAMESPACE_END
217 
218 #endif
219 
220 #endif
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:139
container of wait objects
Definition: wait.h:154
high resolution timer
Definition: hrtimer.h:53
Utility functions for the Crypto++ library.
Abstract base classes that provide a uniform interface to this library.
Library configuration file.
Definition: wait.h:29
exception thrown by WaitObjectContainer
Definition: wait.h:158
Crypto++ library namespace.
Ensures an object is not copyable.
Definition: misc.h:189