casynnet.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:21k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: casynnet.cpp,v 1.4.2.3 2004/07/09 01:46:44 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxtypes.h"
  50. #include <windows.h> // For Window-isms
  51. #include "hxcom.h"
  52. #include "hxslist.h"
  53. #include "platform/win/sock.h"
  54. #include "platform/win/hxsock.h"   // For Socket related constants and macros
  55. #include "platform/win/casynnet.h" // Our definition
  56. #include "hxmap.h" // Map object
  57. #include "debugout.h" // DEBUGOUTSTR()
  58. #include "hxassert.h" // HX_ASSERT()
  59. #include "hxstrutl.h"
  60. #include "hxheap.h"
  61. #ifdef _DEBUG
  62. #undef HX_THIS_FILE
  63. static const char HX_THIS_FILE[] = __FILE__;
  64. #endif  
  65. /* Constant Definitions */
  66. #define WND_CLASS_BASE "HX_Internal_Sock_Async"
  67. #define MAX_WND_CLASS_LENGTH 50
  68. #define OFFSET_THIS 0
  69. /* Class Static Definitions */
  70. BOOL CAsyncSockN::zm_bClassRegistered    = FALSE;
  71. CAsyncSockN* CAsyncSockN::zm_pSockNotifiers     = NULL;
  72. SockGlobals sockGlobals;
  73. /* Class Public Methods */
  74. // Either creates a socket notifier, or returns a pointer
  75. // to the socket notifier that should be used for this instance.
  76. CAsyncSockN *CAsyncSockN::GetCAsyncSockNotifier( HINSTANCE hInst , BOOL Create)
  77. {
  78.     CAsyncSockN*    pThis = 0;
  79.     // Does our current session already have a net notifier?
  80.     if (!(pThis = FindSockNotifier()) && Create)
  81.     {
  82. // No, then create one
  83. pThis = new CAsyncSockN(hInst);
  84. if (pThis && !pThis->IsValid())
  85. {
  86.     // If creation failed then delete the pointer
  87.     delete pThis;
  88.     pThis = NULL;
  89. }
  90. if (pThis)
  91. {
  92.     LinkUs(pThis);
  93. }
  94.     }
  95.     // return the results of our labor
  96.     return (pThis);
  97. }
  98. // Our client win_net object calls this method to
  99. // start an async DNS request.
  100. BOOL CAsyncSockN::DoAsyncDNS( win_net *fpSock, LPCSTR lpHostName, LPSTR pBuff, int cbBuffSize )
  101. {
  102.     // Preliminary checks
  103.     HX_ASSERT(this);
  104.     HX_ASSERT(fpSock);
  105.     HX_ASSERT(m_hWnd);
  106.     HX_ASSERT(lpHostName && *lpHostName);
  107.     // Bail on bad input
  108.     if (!this || !fpSock || !lpHostName || !*lpHostName)
  109.     {
  110. return(FALSE);
  111.     }
  112.     DNS_REQUEST* pDNSRequest = new DNS_REQUEST;
  113.     pDNSRequest->fpSock = fpSock;
  114.     if (lpHostName)
  115.     {
  116. pDNSRequest->lpHostName = new CHAR[strlen(lpHostName)+1];
  117. memset(pDNSRequest->lpHostName, 0, strlen(lpHostName)+1);
  118. strcpy(pDNSRequest->lpHostName, lpHostName); /* Flawfinder: ignore */
  119.     }
  120.     
  121.     pDNSRequest->lpBuffer = pBuff;
  122.     pDNSRequest->cbBufferSize = cbBuffSize;
  123.     sockGlobals.m_DNSQueue.AddTail(pDNSRequest);
  124.     
  125.     return ProcessDNSQueue();
  126. }
  127. BOOL CAsyncSockN::ProcessDNSQueue(void)
  128. {
  129.     BOOL     bResult = TRUE;
  130.     DNS_REQUEST*    pDNSRequest = NULL;
  131.     HANDLE     hAsyncHandle = NULL;
  132.     int     nCount = 0;
  133.     if (sockGlobals.m_DNSQueue.GetCount())
  134.     {
  135. if (sockGlobals.m_bWinSock2Suck)
  136. {
  137.     nCount = m_ClientHandlesMap->GetCount();
  138.     if (!nCount)
  139.     {
  140. pDNSRequest = (DNS_REQUEST*)sockGlobals.m_DNSQueue.GetHead();
  141.     }
  142.     else
  143.     {
  144. goto cleanup;
  145.     }
  146. }
  147. else
  148. {
  149.     pDNSRequest = (DNS_REQUEST*)sockGlobals.m_DNSQueue.RemoveHead();
  150. }
  151. // Start the async DNS
  152. hAsyncHandle = sockObj->HXWSAAsyncGetHostByName(m_hWnd, 
  153. PWM_ASYNC_DNS, 
  154. pDNSRequest->lpHostName, 
  155. pDNSRequest->lpBuffer, 
  156. pDNSRequest->cbBufferSize);
  157. // Create a mapping from the async handle to the win_net object pointer
  158. m_ClientHandlesMap->SetAt((void*)hAsyncHandle, pDNSRequest->fpSock);
  159. // You shouldn't already have an async operation active on this socket!
  160. HX_ASSERT(pDNSRequest->fpSock->m_hAsyncHandle == NULL);
  161. // Remember this in case we need to cancel!
  162. pDNSRequest->fpSock->m_hAsyncHandle = hAsyncHandle;
  163. // Bump our client count up
  164. IncrementHandlesClientCount();
  165.     }
  166. cleanup:
  167.     if (!sockGlobals.m_bWinSock2Suck)
  168.     {
  169. HX_DELETE(pDNSRequest);
  170.     }
  171.     return bResult;
  172. }
  173.    
  174. // Our client win_net object calls this method to 
  175. // start receiving async select notifications
  176. // on a socket.
  177. BOOL CAsyncSockN::DoAsyncSelect(win_net* fpSock)
  178. {
  179.     SOCKET theSocket;
  180.     // Preliminary checks
  181.     HX_ASSERT(this);
  182.     HX_ASSERT(fpSock);
  183.     // Bail on bad input
  184.     if (!this || !fpSock)
  185.     {
  186. return(FALSE);
  187.     }
  188.     // Get and verify we have a good socket handle
  189.     theSocket = fpSock->get_sock();
  190.     HX_ASSERT(theSocket != INVALID_SOCKET);
  191.     // Request async Notifications on the socket
  192.     long lEvent = (FD_CONNECT | FD_READ | FD_CLOSE) ;
  193. #ifndef HELIX_FEATURE_NETWORK_USE_SELECT
  194.     lEvent |= (FD_WRITE | FD_ACCEPT);
  195. #endif
  196.     sockObj->HXWSAAsyncSelect(theSocket, m_hWnd, PWM_ASYNC_SELECT, lEvent);
  197.     // Create a mapping from socket handle to win_net object pointer
  198.     m_ClientSocketsMap->SetAt((void*)theSocket, fpSock);
  199.     // Bump our client count up
  200.     IncrementSocketsClientCount();
  201.     return (TRUE);
  202. }
  203. // Our client win_net object calls this method to 
  204. // stop receiving async select notifications
  205. // on a socket.
  206. BOOL CAsyncSockN::CancelSelect(win_net* fpSock)
  207. {
  208.     SOCKET     theSocket;
  209.     DNS_REQUEST*    pDNSRequest = NULL;
  210.     LISTPOSITION    lPos;
  211.     // Preliminary checks
  212.     HX_ASSERT(this);
  213.     HX_ASSERT(fpSock);
  214.     // Bail on bad input
  215.     if (!this || !fpSock)
  216.     {
  217. return(FALSE);
  218.     }
  219.     m_bInCancelMode = TRUE;
  220.     // If we haven't returned from an Asyn operation like GetHostByName
  221.     // then we need to tell Winsock to cancel the opertation!
  222.     HANDLE hAsyncHandle = fpSock->m_hAsyncHandle;
  223.     if (hAsyncHandle)
  224.     {
  225. sockObj->HXWSACancelAsyncRequest(hAsyncHandle);
  226. fpSock->m_hAsyncHandle = NULL;
  227. // If we've canceled the async DNS is done, 
  228. // then we can forget the Async handle
  229. if (m_ClientHandlesMap->RemoveKey((void*)hAsyncHandle))
  230. {
  231.     DecrementHandlesClientCount();
  232. }
  233.     }
  234.     if (sockGlobals.m_bWinSock2Suck)
  235.     {
  236. lPos = sockGlobals.m_DNSQueue.GetHeadPosition();
  237. while (lPos)
  238. {
  239.     pDNSRequest = (DNS_REQUEST *)sockGlobals.m_DNSQueue.GetAt(lPos);
  240.     if (pDNSRequest->fpSock == fpSock)
  241.     {
  242. sockGlobals.m_DNSQueue.RemoveAt(lPos);
  243. HX_DELETE(pDNSRequest);
  244. break;
  245.     }
  246.     sockGlobals.m_DNSQueue.GetNext(lPos);
  247. }
  248.     }
  249.     // Get and verify we have a good socket handle
  250.     theSocket = fpSock->get_sock();
  251.     
  252. //    HX_ASSERT(theSocket != INVALID_SOCKET);
  253.     /* This may actually happen since we do not check for CONN_CLOSED
  254.      * condition in win_net any more
  255.      */
  256.     if (theSocket == INVALID_SOCKET)
  257.     {
  258. m_bInCancelMode = FALSE;
  259. return FALSE;
  260.     }
  261.     // Turn off async Notifications on the socket
  262.     sockObj->HXWSAAsyncSelect(theSocket, m_hWnd, 0, 0);
  263.     // According to the Winsock help, just cause we cancel
  264.     // the notifications, doesn't mean we still won't get notified
  265.     // of something that has already been posted to our window,
  266.     // so... let's flush our message queue...
  267.     //
  268.     // HACK ATTACK: Notice that both of these message pumps
  269.     // are needed. If you run a debug build or a retail build
  270.     // on some machines without the two message pumps, you
  271.     // won't have any trouble. But on some machines having only
  272.     // this last message pump will cause a GPF.
  273.     MSG msg;
  274.     while (m_hWnd && PeekMessage(&msg, m_hWnd,0,0,PM_REMOVE))
  275.     {
  276. // This will remove any messages!
  277. HX_TRACE("There's a message that would've go you!!rn");
  278. if(msg.message == WM_QUIT) 
  279. {   
  280.     // When peeking WM_QUIT message in the main thread of an application 
  281.     // we have to put it back into message queue to allow the application 
  282.     // to exit correctly. SB
  283.     PostQuitMessage(0);
  284.     break;
  285. }
  286. else
  287. {
  288.     // Even though we want them removed, we also want to act on them.
  289.     DispatchMessage(&msg);
  290. }
  291.     }
  292.     if (m_ClientSocketsMap)
  293.     {
  294. // Delete the mapping from socket handle to win_net object pointer
  295. if (m_ClientSocketsMap->RemoveKey((void*)theSocket))
  296. {
  297.     // Decrement our client count and conditionally
  298.     // delete ourselves.
  299.     DecrementSocketsClientCount();
  300. }
  301.     }
  302.     m_bInCancelMode = FALSE;
  303.     // check to see if we are in use
  304.     CheckClients();
  305.     return (TRUE);
  306. }
  307. /*
  308.  * Private Class Methods
  309.  */
  310. // Static method
  311. // Computes a session id that should be thread unique
  312. // In Win32 we have a thread ID
  313. // In Win16 we have the task (single threaded)
  314. ULONG32 CAsyncSockN::GetSession()
  315. {
  316. #if defined( _WIN32 )
  317. return (GetCurrentThreadId());
  318. #else
  319. return ((ULONG32)(LPSTR)GetCurrentTask());
  320. #endif
  321. }
  322. // Hidden Constructor, called by GetAsyncNotifier() if there
  323. // is no Socket Notifier for the current session
  324. CAsyncSockN::CAsyncSockN(HINSTANCE hInst)
  325.     : m_hWnd(NULL)
  326.     , m_bValid(FALSE)
  327.     , m_hInst(hInst)
  328.     , m_cbNumHandlesClients(0)
  329.     , m_cbNumSocketsClients(0)
  330.     , m_bInCancelMode(FALSE)
  331.     , m_pNextNotifier(0)
  332. {
  333.     // Validate input
  334.     HX_ASSERT(this);
  335.     // assert( hInst );
  336.     if (!this)
  337.     {
  338. return;
  339.     }
  340.     m_ClientHandlesMap = new CHXMapPtrToPtr;
  341.     m_ClientSocketsMap = new CHXMapPtrToPtr;
  342.     m_ulSession = CAsyncSockN::GetSession();
  343.     m_bValid = Create();
  344. }
  345. // Workhorse construction method
  346. BOOL CAsyncSockN::Create()
  347. {
  348.     char szClassName[MAX_WND_CLASS_LENGTH]; /* Flawfinder: ignore */
  349.     SafeSprintf(szClassName, MAX_WND_CLASS_LENGTH, "%s%d", WND_CLASS_BASE, &zm_bClassRegistered);
  350.     if (!zm_bClassRegistered)
  351.     {
  352. WNDCLASS internalClass;
  353.     
  354. // First register our window class                                  
  355. internalClass.style  = 0;
  356. internalClass.lpfnWndProc  = CAsyncSockN::AsyncNotifyProc;
  357. internalClass.cbClsExtra = 0;
  358. internalClass.cbWndExtra = sizeof(this);
  359. internalClass.hInstance = m_hInst; // Use app's instance
  360. internalClass.hIcon = 0;
  361. internalClass.hCursor = 0;
  362. internalClass.hbrBackground = 0;
  363. internalClass.lpszMenuName = NULL;
  364. internalClass.lpszClassName = szClassName;
  365. zm_bClassRegistered = RegisterClass(&internalClass);
  366. if(!zm_bClassRegistered)
  367. {
  368.     UnregisterClass(szClassName, m_hInst);
  369.     zm_bClassRegistered = RegisterClass(&internalClass);
  370. }
  371.     }
  372.     // Now create an instance of the window
  373.     m_hWnd = CreateWindow(szClassName, "RealAudio Internal Messages", 
  374. WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL, m_hInst, this);
  375.  
  376.     if (!m_hWnd)
  377.     {
  378. return (FALSE);
  379.     }
  380.     return (TRUE);
  381. }
  382. // Destructor: Destroys the window and unregisters the class if necessary
  383. CAsyncSockN::~CAsyncSockN()
  384. {
  385.     // Validate input
  386.     HX_ASSERT(this);
  387.     if (!this)
  388.     {
  389. return;
  390.     }
  391.     m_bValid = FALSE;
  392.     // UnlinkUs( this );
  393.     m_hWnd = NULL;
  394.     m_hInst = NULL;
  395.     if(m_ClientHandlesMap)
  396.     {
  397. delete m_ClientHandlesMap;
  398. m_ClientHandlesMap = NULL;
  399. m_cbNumHandlesClients = 0;
  400.     }
  401.     if(m_ClientSocketsMap)
  402.     {
  403. delete m_ClientSocketsMap;
  404. m_ClientSocketsMap = NULL;
  405. m_cbNumSocketsClients = 0;
  406.     }
  407. }
  408. // This is the WndProc that handles async notifications on behalf of the client
  409. // win_net objects.
  410. LRESULT HXEXPORT CAsyncSockN::AsyncNotifyProc(HWND hWnd, UINT msg, 
  411.       WPARAM wParam, LPARAM lParam)
  412. {
  413.     CAsyncSockN*    pThis = 0;
  414.     // Make ourselves look like a non-static member function dig the this
  415.     // pointer out of the window.
  416.     if (msg == WM_NCCREATE)
  417.     {
  418. CREATESTRUCT* lpCreate = 0;
  419. // Set our this pointer, so our WndProc can find us again
  420. lpCreate = (CREATESTRUCT FAR*) lParam;
  421. pThis = (CAsyncSockN*) lpCreate->lpCreateParams;
  422. SetWindowLong(hWnd, OFFSET_THIS, (long) pThis);
  423.     }
  424.     else if (msg == WM_NCDESTROY)
  425.     {
  426. // remove our this pointer so if somebody calls this function
  427. // again after the window is gone (and the object is gone
  428. // too) we don't try to call a method from the pointer
  429. SetWindowLong(hWnd, OFFSET_THIS, 0L);
  430.     }
  431.     else
  432.     {
  433. // Note: This MUST be a static function
  434. // However we make it appear to be a member function
  435. // By imbedding a this pointer in the window object
  436. pThis = (CAsyncSockN*) (LPHANDLE)GetWindowLong(hWnd, OFFSET_THIS);
  437.     }
  438.     if (pThis != NULL)
  439.     {
  440. switch (msg)
  441. {
  442.     case PWM_ASYNC_SELECT:
  443. return (pThis->OnAsyncSelect(wParam, lParam));
  444.     case PWM_ASYNC_DNS:
  445. return (pThis->OnAsyncDNS(wParam, lParam));
  446.     default:
  447. break;
  448. }
  449.     }
  450.     return (DefWindowProc(hWnd, msg, wParam, lParam));
  451. }
  452. LRESULT CAsyncSockN::CheckClients()
  453. {
  454.     ProcessDNSQueue();
  455.         
  456.     if (!m_bInCancelMode && !m_cbNumHandlesClients && !m_cbNumSocketsClients)
  457.     {
  458. UnlinkUs(this);
  459. DestroyWindow(m_hWnd);
  460. delete this;
  461.     }
  462.     return(TRUE);
  463. }
  464. // Message handler for PWM_ASYNC_DNS
  465. // Notifies the client win_net object that DNS has completed or
  466. // returned w/ an error.
  467. LRESULT CAsyncSockN::OnAsyncDNS(WPARAM wParam, LPARAM lParam)
  468. {
  469.     void*     handle = (void*) (HANDLE) wParam;
  470.     void*     pVoid = 0;
  471.     win_net*     pClient = 0;
  472.     DNS_REQUEST*    pDNSRequest = NULL;
  473.     // Bail if the client map has been previously deleted, this
  474.     // is a sure sign of us already being cleaned up!
  475.     if(!m_ClientHandlesMap)
  476.     {
  477. return(TRUE);
  478.     }
  479.     DEBUGOUTSTR( "AsyncDNS come backrn" );
  480.     // Based on the handle returned, find our client!
  481.     // Note it might be missing from the map if we canceled
  482.     // the DNS!
  483.     if (m_ClientHandlesMap->Lookup(handle, pVoid))
  484.     {
  485. *((ULONG32 *)&pClient) = (ULONG32)pVoid;
  486. // We should already have an async operation active on this socket!
  487. #ifdef _DEBUG
  488. if ((void *)pClient->m_hAsyncHandle != handle)
  489. {
  490.     char szMessage[256]; /* Flawfinder: ignore */
  491.     sprintf(szMessage,"pClient->m_hAsyncHandle = %#lxnhandle = %#lx", /* Flawfinder: ignore */
  492. pClient->m_hAsyncHandle,
  493. handle
  494.     );
  495.     MessageBox(NULL,szMessage,"Oops!",MB_OK);
  496. }
  497. HX_ASSERT((void *)pClient->m_hAsyncHandle == handle);
  498. #endif
  499. // Tell win_net object to forget the Async handle
  500. pClient->m_hAsyncHandle = NULL;
  501. pClient->CB_DNSComplete(!WSAGETASYNCERROR(lParam));
  502. // If async DNS is done, then we can forget the Async handle
  503. if (m_ClientHandlesMap->RemoveKey(handle))
  504. {
  505.     DecrementHandlesClientCount();
  506. }
  507.     }
  508. #ifdef _DEBUG
  509.     if (m_ClientHandlesMap->GetCount() != m_cbNumHandlesClients)
  510.     {
  511. char szMessage[256]; /* Flawfinder: ignore */
  512. sprintf(szMessage,"m_ClientHandlesMap->GetCount() = %dnm_cbNumHandlesClients = %d", /* Flawfinder: ignore */
  513.     m_ClientHandlesMap->GetCount(),
  514.     m_cbNumHandlesClients
  515. );
  516. MessageBox(NULL,szMessage,"Oops!",MB_OK);
  517.     }
  518.     HX_ASSERT(m_ClientHandlesMap->GetCount() == m_cbNumHandlesClients);
  519. #endif
  520.     if (sockGlobals.m_bWinSock2Suck)
  521.     {
  522. pDNSRequest = (DNS_REQUEST*) sockGlobals.m_DNSQueue.RemoveHead();
  523. HX_DELETE(pDNSRequest);
  524.     }
  525.     // check to see if we are still in use.
  526.     CheckClients();
  527.     return (TRUE);
  528. }
  529. // Message handler for PWM_ASYNC_SELECT
  530. // Notifies the win_net client when the corresponding socket
  531. // is ready to read/write/ or has connected.
  532. LRESULT CAsyncSockN::OnAsyncSelect(WPARAM wParam, LPARAM lParam)
  533. {
  534.     LPVOID pVoid;
  535.     UINT16 theEvent;
  536.     UINT16 theError;
  537.     SOCKET theSocket;
  538.     win_net* pClient = NULL;
  539.     theSocket = (SOCKET) wParam;
  540.     theEvent = WSAGETSELECTEVENT(lParam);
  541.     theError = WSAGETSELECTERROR(lParam);
  542.     // Find out the win_net object we want to talk to
  543.     if(m_ClientSocketsMap->Lookup((void*) theSocket, pVoid))
  544.     {
  545. *((ULONG32 *)&pClient) = (ULONG32) pVoid;
  546.     }
  547.     if (!pClient)
  548.     {
  549. DEBUGOUTSTR( "Error OnAsyncSelect() no win_net object foundrn" );
  550. return(TRUE);
  551.     }
  552.     if (theError)
  553.     {
  554. char acError[100]; /* Flawfinder: ignore */
  555. wsprintf(acError, "Got error %d from Winsockrn", theError);
  556. DEBUGOUTSTR(acError);
  557.     }
  558.     switch (theEvent)
  559.     {
  560.     case FD_WRITE:
  561. DEBUGOUTSTR("Got AsyncWrite notificationrn");
  562. pClient->CB_ReadWriteNotification(theEvent);
  563. break;
  564.     case FD_READ:
  565. #ifndef _DEMPSEY
  566. // Noisy debug output
  567. DEBUGOUTSTR("Got AsyncRead notificationrn");
  568. #endif // _DEMPSEY
  569. pClient->CB_ReadWriteNotification(theEvent);
  570. break;
  571.     case FD_CONNECT:
  572. DEBUGOUTSTR("Got AsyncConnect notificationrn");
  573. pClient->CB_ConnectionComplete(!theError);
  574. break;
  575.     case FD_CLOSE:
  576. DEBUGOUTSTR("Got AsyncClose notificationrn");
  577. pClient->CB_CloseNotification();
  578. break;
  579.     
  580.     case FD_ACCEPT:
  581. DEBUGOUTSTR("Got AsyncAccept notificationrn");
  582. pClient->CB_AcceptNotification();
  583. break;
  584.     }
  585.     return (TRUE);
  586. }
  587. // Static method
  588. // Inserts us at the head of the list
  589. void CAsyncSockN::LinkUs(CAsyncSockN* pUs)
  590. {
  591.     HX_ASSERT(pUs);
  592.     if (!pUs)
  593.     {
  594. return;
  595.     }
  596.     // Tack us on at the head of the list since order doesn't matter
  597.     pUs->m_pNextNotifier = zm_pSockNotifiers;
  598.     zm_pSockNotifiers = pUs;
  599. }
  600. // Static method
  601. // Removes us from the list
  602. void CAsyncSockN::UnlinkUs(CAsyncSockN* pUs)
  603. {
  604.     CAsyncSockN* pWalk = 0;
  605.     HX_ASSERT(pUs);
  606.     // Don't try to remove NULL pointers
  607.     if (!pUs)
  608.     {
  609. return;
  610.     }
  611.     // If the desired node is at the head then it's simple
  612.     if (zm_pSockNotifiers == pUs)
  613.     {
  614. zm_pSockNotifiers = pUs->m_pNextNotifier;
  615. return;
  616.     }
  617.     // Otherwise we have to walk the list till we find our node
  618.     else
  619.     {
  620. // iterate till we find ourselves or reach the end of the list
  621. pWalk = zm_pSockNotifiers;
  622. while (pWalk && (pWalk->m_pNextNotifier != pUs))
  623. {
  624.     pWalk = pWalk->m_pNextNotifier;
  625. }
  626. // Did we find ourselves?
  627. if (pWalk)
  628. {
  629.     // Ok, link to our successor
  630.     pWalk->m_pNextNotifier = pUs->m_pNextNotifier;
  631. }
  632.     }
  633.     return;
  634. }
  635. // Static method
  636. // Returns correct notifier object for our current session (thread/task)
  637. CAsyncSockN *CAsyncSockN::FindSockNotifier()
  638. {
  639.     ULONG32     ulSession;
  640.     CAsyncSockN*    pWalk;
  641.     ulSession = CAsyncSockN::GetSession();
  642.     pWalk = CAsyncSockN::zm_pSockNotifiers;
  643.     while (pWalk && pWalk->m_ulSession != ulSession)
  644.     {
  645. pWalk = pWalk->m_pNextNotifier;
  646.     }
  647.     
  648.     return (pWalk);
  649. }
  650. DNS_REQUEST::DNS_REQUEST()
  651. {
  652.     fpSock = NULL;
  653.     lpHostName = NULL;
  654.     lpBuffer = NULL;
  655.     cbBufferSize = 0;
  656. }
  657. DNS_REQUEST::~DNS_REQUEST()
  658. {
  659.     HX_VECTOR_DELETE(lpHostName);
  660. }
  661. SockGlobals::SockGlobals()
  662. {
  663. }
  664. SockGlobals::~SockGlobals()
  665. {
  666.     while (m_DNSQueue.GetCount())
  667.     {
  668. DNS_REQUEST* pDNSRequest = (DNS_REQUEST*) m_DNSQueue.RemoveHead();
  669. HX_DELETE(pDNSRequest);
  670.     }
  671.     m_DNSQueue.RemoveAll();
  672. }