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