00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00026 #ifndef OW32_AsyncResolverServer_h
00027 #define OW32_AsyncResolverServer_h
00028
00029 #include <OW32/windows.h>
00030 #include <OW32/auto_array_ptr.h>
00031 #include <OW32/SyncObjects.h>
00032 #include <OW32/auto_buf.h>
00033 #include <OW32/XSOCKET.h>
00034
00035 #include <list>
00036
00037 namespace OW32
00038 {
00039
00040 class OW32_LIB_EXPORT CAsyncResolver;
00041
00042 #ifdef _MSC_VER
00043 #pragma warning(disable: 4251)
00044 #endif
00045
00049 class OW32_LIB_EXPORT CAsyncResolverServer
00050 {
00051 public:
00059 CAsyncResolverServer(CAsyncResolver *pParent, size_t serverIndex, in_addr addr);
00060
00064 AsyncResolverError sendQuery(CAsyncResolverQuery *query);
00065
00070 AsyncResolverError destroy();
00071
00075 const size_t getServerIndex() const { return m_serverIndex; }
00076
00077 private:
00079 CAsyncResolverServer(const CAsyncResolverServer &);
00080 CAsyncResolverServer& operator=(const CAsyncResolverServer &);
00081
00087 class OW32_LIB_EXPORT CUDPConnection : public CIoCompletion
00088 {
00089 public:
00091 CUDPConnection();
00092
00094 typedef void (CUDPConnection::*CompletionFn)(BOOL bRet, DWORD dwBytes, LPOVERLAPPED lpOS);
00095
00097 struct OW32_LIB_EXPORT OVERLAPPEDPLUS : public OVERLAPPED
00098 {
00100 CompletionFn lpCompletion;
00101 };
00102
00107 struct SENDOVERLAPPED : public OVERLAPPEDPLUS
00108 {
00109 SENDOVERLAPPED(CAsyncResolverQuery *query_) :
00110 query(query_)
00111 {
00112 }
00113
00115 CAsyncResolverQueryPtr query;
00116 };
00117
00121 virtual void OnIoCompletion(BOOL bRet, DWORD dwBytes, LPOVERLAPPED lpOS)
00122 {
00123 OVERLAPPEDPLUS* lpOSPlus = (OVERLAPPEDPLUS*)lpOS;
00124 (this->*(lpOSPlus->lpCompletion))(bRet, dwBytes, lpOS);
00125 }
00126
00130 void onSendCompletion(BOOL bRet, DWORD cbBytesSent, LPOVERLAPPED lpOS);
00131
00135 void onReadCompletion(BOOL bRet, DWORD cbBytesReceived, LPOVERLAPPED lpOS);
00136
00140 void onAllNotificationsProcessed();
00141
00145 AsyncResolverError sendQuery(CAsyncResolverQuery *query);
00146
00151 AsyncResolverError destroy();
00152
00153 private:
00155 void expectNotification()
00156 {
00157 InterlockedIncrement(&m_outstandingNotifications);
00158 }
00159
00161 void receivedNotification()
00162 {
00163 if (InterlockedDecrement(&m_outstandingNotifications) == 0)
00164 onAllNotificationsProcessed();
00165 }
00166
00168 OVERLAPPEDPLUS m_osRead;
00170 auto_array_ptr<BYTE> m_answer;
00172 XSOCKET m_socket;
00174 CCriticalSection m_lock;
00176 LONG m_outstandingNotifications;
00178 bool m_fInDestruction;
00180 CEvent m_evDestruction;
00181 };
00182 CUDPConnection m_udpConnection;
00183
00184 class OW32_LIB_EXPORT CTCPConnection : public CAsyncSocketCallback
00185 {
00186 public:
00187 CTCPConnection();
00188
00189
00190 virtual void onConnectCompletion(BOOL bRet);
00191 virtual void onReadCompletion(BOOL bRet, DWORD dwBytes);
00192 virtual void onSendCompletion(BOOL bRet, DWORD dwBytes);
00193 virtual void onAllNotificationsProcessed();
00194
00198 AsyncResolverError sendQuery(CAsyncResolverQuery *query);
00199
00204 AsyncResolverError destroy();
00205
00206 private:
00210 AsyncResolverError makeConnection();
00211
00215 bool sendQueuedItem(CSingleLock &lock);
00216
00225 void handleError(CSingleLock &lock, AsyncResolverError status);
00226
00228 bool m_fOkToSend;
00230 CCriticalSection m_lock;
00232 std::list<CAsyncResolverQueryPtr> m_queue;
00234 size_t m_length;
00236 size_t m_sendPos;
00238 auto_byte_buf m_answer;
00240 std::auto_ptr<CAsyncIoCompletionSocket> m_pSocket;
00242 bool m_fInDestruction;
00244 CEvent m_evDestruction;
00245 };
00246 CTCPConnection m_tcpConnection;
00247
00249 in_addr m_addr;
00251 CAsyncResolver *m_pParent;
00253 size_t m_serverIndex;
00254 };
00255
00256 #ifdef _MSC_VER
00257 #pragma warning(default: 4251)
00258 #endif
00259
00260 }
00261
00262 #endif // OW32_AsyncResolverServer_h