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
00030 virtual void Trace(unsigned int n, std::string const& s) = 0;
00031
00032
00033
00034
00035
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
00045
00046
00047
00048 unsigned int Tracing(unsigned int nr, unsigned int minLevel) const
00049 { return (UsingDefaults() && m_level >= minLevel) ? nr : 0; }
00050 };
00051
00052
00053
00054
00055
00056
00057
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
00070
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
00077
00078
00079
00080
00081
00082
00083
00084
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
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
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
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
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
00146 class WaitObjectContainer : public NotCopyable
00147 {
00148 public:
00149
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
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