• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

wait.h

00001 #ifndef CRYPTOPP_WAIT_H
00002 #define CRYPTOPP_WAIT_H
00003 
00004 #include "config.h"
00005 
00006 #ifdef SOCKETS_AVAILABLE
00007 
00008 #include "misc.h"
00009 #include "cryptlib.h"
00010 #include <vector>
00011 
00012 #ifdef USE_WINDOWS_STYLE_SOCKETS
00013 #include <winsock2.h>
00014 #else
00015 #include <sys/types.h>
00016 #endif
00017 
00018 #include "hrtimer.h"
00019 
00020 NAMESPACE_BEGIN(CryptoPP)
00021 
00022 class Tracer
00023 {
00024 public:
00025     Tracer(unsigned int level) : m_level(level) {}
00026     virtual ~Tracer() {}
00027 
00028 protected:
00029     //! Override this in your most-derived tracer to do the actual tracing.
00030     virtual void Trace(unsigned int n, std::string const& s) = 0;
00031 
00032     /*! By default, tracers will decide which trace messages to trace according to a trace level
00033         mechanism. If your most-derived tracer uses a different mechanism, override this to
00034         return false. If this method returns false, the default TraceXxxx(void) methods will all
00035         return 0 and must be overridden explicitly by your tracer for trace messages you want. */
00036     virtual bool UsingDefaults() const { return true; }
00037 
00038 protected:
00039     unsigned int m_level;
00040 
00041     void TraceIf(unsigned int n, std::string const&s)
00042         { if (n) Trace(n, s); }
00043 
00044     /*! Returns nr if, according to the default log settings mechanism (using log levels),
00045         the message should be traced. Returns 0 if the default trace level mechanism is not
00046         in use, or if it is in use but the event should not be traced. Provided as a utility
00047         method for easier and shorter coding of default TraceXxxx(void) implementations. */
00048     unsigned int Tracing(unsigned int nr, unsigned int minLevel) const
00049         { return (UsingDefaults() && m_level >= minLevel) ? nr : 0; }
00050 };
00051 
00052 // Your Tracer-derived class should inherit as virtual public from Tracer or another
00053 // Tracer-derived class, and should pass the log level in its constructor. You can use the
00054 // following methods to begin and end your Tracer definition.
00055 
00056 // This constructor macro initializes Tracer directly even if not derived directly from it;
00057 // this is intended, virtual base classes are always initialized by the most derived class.
00058 #define CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) \
00059     public: DERIVED(unsigned int level = 0) : Tracer(level) {}
00060 
00061 #define CRYPTOPP_BEGIN_TRACER_CLASS_1(DERIVED, BASE1) \
00062     class DERIVED : virtual public BASE1 { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED)
00063 
00064 #define CRYPTOPP_BEGIN_TRACER_CLASS_2(DERIVED, BASE1, BASE2) \
00065     class DERIVED : virtual public BASE1, virtual public BASE2 { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED)
00066 
00067 #define CRYPTOPP_END_TRACER_CLASS };
00068 
00069 // In your Tracer-derived class, you should define a globally unique event number for each
00070 // new event defined. This can be done using the following macros.
00071 
00072 #define CRYPTOPP_BEGIN_TRACER_EVENTS(UNIQUENR)  enum { EVENTBASE = UNIQUENR,
00073 #define CRYPTOPP_TRACER_EVENT(EVENTNAME)                EventNr_##EVENTNAME,
00074 #define CRYPTOPP_END_TRACER_EVENTS              };
00075 
00076 // In your own Tracer-derived class, you must define two methods per new trace event type:
00077 // - unsigned int TraceXxxx() const
00078 //   Your default implementation of this method should return the event number if according
00079 //   to the default trace level system the event should be traced, or 0 if it should not.
00080 // - void TraceXxxx(string const& s)
00081 //   This method should call TraceIf(TraceXxxx(), s); to do the tracing.
00082 // For your convenience, a macro to define these two types of methods are defined below.
00083 // If you use this macro, you should also use the TRACER_EVENTS macros above to associate
00084 // event names with numbers.
00085 
00086 #define CRYPTOPP_TRACER_EVENT_METHODS(EVENTNAME, LOGLEVEL) \
00087     virtual unsigned int Trace##EVENTNAME() const { return Tracing(EventNr_##EVENTNAME, LOGLEVEL); } \
00088     virtual void Trace##EVENTNAME(std::string const& s) { TraceIf(Trace##EVENTNAME(), s); }
00089 
00090 
00091 /*! A simple unidirectional linked list with m_prev == 0 to indicate the final entry.
00092     The aim of this implementation is to provide a very lightweight and practical
00093     tracing mechanism with a low performance impact. Functions and methods supporting
00094     this call-stack mechanism would take a parameter of the form "CallStack const& callStack",
00095     and would pass this parameter to subsequent functions they call using the construct:
00096 
00097     SubFunc(arg1, arg2, CallStack("my func at place such and such", &callStack));
00098     
00099     The advantage of this approach is that it is easy to use and should be very efficient,
00100     involving no allocation from the heap, just a linked list of stack objects containing
00101     pointers to static ASCIIZ strings (or possibly additional but simple data if derived). */
00102 class CallStack
00103 {
00104 public:
00105     CallStack(char const* i, CallStack const* p) : m_info(i), m_prev(p) {}
00106     CallStack const* Prev() const { return m_prev; }
00107     virtual std::string Format() const;
00108 
00109 protected:
00110     char const* m_info;
00111     CallStack const* m_prev;
00112 };
00113 
00114 /*! An extended CallStack entry type with an additional numeric parameter. */
00115 class CallStackWithNr : public CallStack
00116 {
00117 public:
00118     CallStackWithNr(char const* i, word32 n, CallStack const* p) : CallStack(i, p), m_nr(n) {}
00119     std::string Format() const;
00120 
00121 protected:
00122     word32 m_nr;
00123 };
00124 
00125 /*! An extended CallStack entry type with an additional string parameter. */
00126 class CallStackWithStr : public CallStack
00127 {
00128 public:
00129     CallStackWithStr(char const* i, char const* z, CallStack const* p) : CallStack(i, p), m_z(z) {}
00130     std::string Format() const;
00131 
00132 protected:
00133     char const* m_z;
00134 };
00135 
00136 CRYPTOPP_BEGIN_TRACER_CLASS_1(WaitObjectsTracer, Tracer)
00137     CRYPTOPP_BEGIN_TRACER_EVENTS(0x48752841)
00138         CRYPTOPP_TRACER_EVENT(NoWaitLoop)
00139     CRYPTOPP_END_TRACER_EVENTS
00140     CRYPTOPP_TRACER_EVENT_METHODS(NoWaitLoop, 1)
00141 CRYPTOPP_END_TRACER_CLASS
00142 
00143 struct WaitingThreadData;
00144 
00145 //! container of wait objects
00146 class WaitObjectContainer : public NotCopyable
00147 {
00148 public:
00149     //! exception thrown by WaitObjectContainer
00150     class Err : public Exception
00151     {
00152     public:
00153         Err(const std::string& s) : Exception(IO_ERROR, s) {}
00154     };
00155 
00156     static unsigned int MaxWaitObjects();
00157 
00158     WaitObjectContainer(WaitObjectsTracer* tracer = 0);
00159 
00160     void Clear();
00161     void SetNoWait(CallStack const& callStack);
00162     void ScheduleEvent(double milliseconds, CallStack const& callStack);
00163     // returns false if timed out
00164     bool Wait(unsigned long milliseconds);
00165 
00166 #ifdef USE_WINDOWS_STYLE_SOCKETS
00167     ~WaitObjectContainer();
00168     void AddHandle(HANDLE handle, CallStack const& callStack);
00169 #else
00170     void AddReadFd(int fd, CallStack const& callStack);
00171     void AddWriteFd(int fd, CallStack const& callStack);
00172 #endif
00173 
00174 private:
00175     WaitObjectsTracer* m_tracer;
00176 
00177 #ifdef USE_WINDOWS_STYLE_SOCKETS
00178     void CreateThreads(unsigned int count);
00179     std::vector<HANDLE> m_handles;
00180     std::vector<WaitingThreadData *> m_threads;
00181     HANDLE m_startWaiting;
00182     HANDLE m_stopWaiting;
00183 #else
00184     fd_set m_readfds, m_writefds;
00185     int m_maxFd;
00186 #endif
00187     bool m_noWait;
00188     double m_firstEventTime;
00189     Timer m_eventTimer;
00190 
00191 #ifdef USE_WINDOWS_STYLE_SOCKETS
00192     typedef size_t LastResultType;
00193 #else
00194     typedef int LastResultType;
00195 #endif
00196     enum { LASTRESULT_NOWAIT = -1, LASTRESULT_SCHEDULED = -2, LASTRESULT_TIMEOUT = -3 };
00197     LastResultType m_lastResult;
00198     unsigned int m_sameResultCount;
00199     Timer m_noWaitTimer;
00200     void SetLastResult(LastResultType result);
00201     void DetectNoWait(LastResultType result, CallStack const& callStack);
00202 };
00203 
00204 NAMESPACE_END
00205 
00206 #endif
00207 
00208 #endif

Generated on Tue Jun 30 2015 19:07:05 for Crypto++ by  doxygen 1.7.1