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 #if defined(__ANDROID__)
00019 #include <sys/select.h>
00020 #endif
00021
00022 #include "hrtimer.h"
00023
00024 NAMESPACE_BEGIN(CryptoPP)
00025
00026 class Tracer
00027 {
00028 public:
00029 Tracer(unsigned int level) : m_level(level) {}
00030 virtual ~Tracer() {}
00031
00032 protected:
00033
00034 virtual void Trace(unsigned int n, std::string const& s) = 0;
00035
00036
00037
00038
00039
00040 virtual bool UsingDefaults() const { return true; }
00041
00042 protected:
00043 unsigned int m_level;
00044
00045 void TraceIf(unsigned int n, std::string const&s)
00046 { if (n) Trace(n, s); }
00047
00048
00049
00050
00051
00052 unsigned int Tracing(unsigned int nr, unsigned int minLevel) const
00053 { return (UsingDefaults() && m_level >= minLevel) ? nr : 0; }
00054 };
00055
00056
00057
00058
00059
00060
00061
00062 #define CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) \
00063 public: DERIVED(unsigned int level = 0) : Tracer(level) {}
00064
00065 #define CRYPTOPP_BEGIN_TRACER_CLASS_1(DERIVED, BASE1) \
00066 class DERIVED : virtual public BASE1, public NotCopyable { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED)
00067
00068 #define CRYPTOPP_BEGIN_TRACER_CLASS_2(DERIVED, BASE1, BASE2) \
00069 class DERIVED : virtual public BASE1, virtual public BASE2, public NotCopyable { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED)
00070
00071 #define CRYPTOPP_END_TRACER_CLASS };
00072
00073
00074
00075
00076 #define CRYPTOPP_BEGIN_TRACER_EVENTS(UNIQUENR) enum { EVENTBASE = UNIQUENR,
00077 #define CRYPTOPP_TRACER_EVENT(EVENTNAME) EventNr_##EVENTNAME,
00078 #define CRYPTOPP_END_TRACER_EVENTS };
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #define CRYPTOPP_TRACER_EVENT_METHODS(EVENTNAME, LOGLEVEL) \
00091 virtual unsigned int Trace##EVENTNAME() const { return Tracing(EventNr_##EVENTNAME, LOGLEVEL); } \
00092 virtual void Trace##EVENTNAME(std::string const& s) { TraceIf(Trace##EVENTNAME(), s); }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 class CallStack
00107 {
00108 public:
00109 CallStack(char const* i, CallStack const* p) : m_info(i), m_prev(p) {}
00110 CallStack const* Prev() const { return m_prev; }
00111 virtual std::string Format() const;
00112
00113 protected:
00114 char const* m_info;
00115 CallStack const* m_prev;
00116 };
00117
00118
00119 class CallStackWithNr : public CallStack
00120 {
00121 public:
00122 CallStackWithNr(char const* i, word32 n, CallStack const* p) : CallStack(i, p), m_nr(n) {}
00123 std::string Format() const;
00124
00125 protected:
00126 word32 m_nr;
00127 };
00128
00129
00130 class CallStackWithStr : public CallStack
00131 {
00132 public:
00133 CallStackWithStr(char const* i, char const* z, CallStack const* p) : CallStack(i, p), m_z(z) {}
00134 std::string Format() const;
00135
00136 protected:
00137 char const* m_z;
00138 };
00139
00140
00141 CRYPTOPP_BEGIN_TRACER_CLASS_1(WaitObjectsTracer, Tracer)
00142 CRYPTOPP_BEGIN_TRACER_EVENTS(0x48752841)
00143 CRYPTOPP_TRACER_EVENT(NoWaitLoop)
00144 CRYPTOPP_END_TRACER_EVENTS
00145 CRYPTOPP_TRACER_EVENT_METHODS(NoWaitLoop, 1)
00146 CRYPTOPP_END_TRACER_CLASS
00147
00148 struct WaitingThreadData;
00149
00150
00151 class WaitObjectContainer : public NotCopyable
00152 {
00153 public:
00154
00155 class Err : public Exception
00156 {
00157 public:
00158 Err(const std::string& s) : Exception(IO_ERROR, s) {}
00159 };
00160
00161 static unsigned int MaxWaitObjects();
00162
00163 WaitObjectContainer(WaitObjectsTracer* tracer = 0);
00164
00165 void Clear();
00166 void SetNoWait(CallStack const& callStack);
00167 void ScheduleEvent(double milliseconds, CallStack const& callStack);
00168
00169 bool Wait(unsigned long milliseconds);
00170
00171 #ifdef USE_WINDOWS_STYLE_SOCKETS
00172 # ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00173 virtual ~WaitObjectContainer();
00174 # else
00175 ~WaitObjectContainer();
00176 #endif
00177 void AddHandle(HANDLE handle, CallStack const& callStack);
00178 #else
00179 void AddReadFd(int fd, CallStack const& callStack);
00180 void AddWriteFd(int fd, CallStack const& callStack);
00181 #endif
00182
00183 private:
00184 WaitObjectsTracer* m_tracer;
00185
00186 #ifdef USE_WINDOWS_STYLE_SOCKETS
00187 void CreateThreads(unsigned int count);
00188 std::vector<HANDLE> m_handles;
00189 std::vector<WaitingThreadData *> m_threads;
00190 HANDLE m_startWaiting;
00191 HANDLE m_stopWaiting;
00192 #else
00193 fd_set m_readfds, m_writefds;
00194 int m_maxFd;
00195 #endif
00196 bool m_noWait;
00197 double m_firstEventTime;
00198 Timer m_eventTimer;
00199
00200 #ifdef USE_WINDOWS_STYLE_SOCKETS
00201 typedef size_t LastResultType;
00202 #else
00203 typedef int LastResultType;
00204 #endif
00205 enum { LASTRESULT_NOWAIT = -1, LASTRESULT_SCHEDULED = -2, LASTRESULT_TIMEOUT = -3 };
00206 LastResultType m_lastResult;
00207 unsigned int m_sameResultCount;
00208 Timer m_noWaitTimer;
00209 void SetLastResult(LastResultType result);
00210 void DetectNoWait(LastResultType result, CallStack const& callStack);
00211 };
00212
00213 NAMESPACE_END
00214
00215 #endif
00216
00217 #endif