00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "stdafx.h"
00037 #include "AsyncSocket.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040
00041 #include "OSManager.h"
00042 #include "GenericCriticalSection.h"
00043 #include "GenericEvent.h"
00044
00045 #include <conio.h>
00046
00047 #include <vector>
00048
00049 #ifdef _MEMORY_DEBUG
00050 #define new DEBUG_NEW
00051 #define malloc DEBUG_MALLOC
00052 static char THIS_FILE[] = __FILE__;
00053 #endif
00054
00055 KOMODIA_NAMESPACE_START
00056
00057
00058
00059 CAsyncSocket::CAsyncShutdown::CAsyncShutdown() : CSocketBase()
00060 {
00061 try
00062 {
00063
00064 SetName(CAsyncShutdown_Class);
00065
00066
00067 RegisterShutdown(this);
00068 }
00069 ERROR_HANDLER("CAsyncShutdown")
00070 }
00071
00072 CAsyncSocket::CAsyncShutdown::~CAsyncShutdown()
00073 {
00074 }
00075
00076 void CAsyncSocket::CAsyncShutdown::NotifyShutdown()
00077 {
00078 try
00079 {
00080
00081 CAsyncSocket::Shutdown();
00082 }
00083 ERROR_HANDLER("NotifyShutdown")
00084 }
00085
00086
00087
00088
00089
00090 HINSTANCE CAsyncSocket::m_hInstance=0;
00091
00092
00093 BOOL CAsyncSocket::m_bInitialized=0;
00094
00095
00096 CSocketThreadManagerImp* CAsyncSocket::m_pThreadManager=NULL;
00097
00098
00099 BOOL CAsyncSocket::m_bShuttingDown=FALSE;
00100
00101 CAsyncSocket::CAsyncSocket() : CSocketBase(),
00102 m_bList(FALSE),
00103 m_bTimeout(FALSE),
00104 m_pLocalThreadManager(NULL),
00105 m_hLocalWindowHandle(0),
00106 m_bFreeze(FALSE),
00107 m_bBlocking(FALSE),
00108 m_iMsg(0),
00109 m_lEvent(0),
00110 m_iSocketID(0),
00111 m_pBlockedBuffer(NULL),
00112 m_bClosing(FALSE),
00113 m_ucEvents(0),
00114 m_pSendEvent(NULL),
00115 m_bBlockSend(TRUE),
00116 m_pThread(NULL),
00117 m_bDeleting(FALSE),
00118 m_bDetached(FALSE)
00119 {
00120 try
00121 {
00122
00123 m_pSendEvent=COSManager::CreateEvent();
00124
00125
00126 Initialize();
00127
00128
00129 SocketCreated();
00130 }
00131 ERROR_HANDLER("CAsyncSocket")
00132 }
00133
00134 CAsyncSocket::~CAsyncSocket()
00135 {
00136 try
00137 {
00138
00139
00140 if (m_aTimerID.iTimerID)
00141 GetThreadManager()->RemoveTimeout(m_aTimerID);
00142
00143 if (m_aDeleteTimerID.iTimerID)
00144 GetThreadManager()->RemoveTimeout(m_aDeleteTimerID);
00145
00146
00147 if (GetThreadManager())
00148
00149 GetThreadManager()->DecreaseSocketCount(GetWindowHandle(),
00150 m_bFreeze);
00151
00152
00153 if (m_bDetached)
00154 delete GetThreadManager();
00155
00156
00157 delete m_pBlockedBuffer;
00158
00159
00160 delete m_pSendEvent;
00161 }
00162 ERROR_HANDLER("~CAsyncSocket")
00163 }
00164
00165 void CAsyncSocket::DetachedSocketThread()
00166 {
00167 try
00168 {
00169
00170 CSocketThreadManagerImp* pClone;
00171 pClone=CloneThreadManager(1);
00172
00173
00174 if (!pClone)
00175
00176 ReportError("DetachedSocketThread","Failed to create detach manager, will resume as normal!");
00177 else
00178 {
00179
00180 if (!SetLocalThreadManager(pClone))
00181 ReportError("DetachedSocketThread","Failed to set manager!");
00182 else
00183
00184 m_bDetached=TRUE;
00185 }
00186 }
00187 ERROR_HANDLER("DetachedSocketThread")
00188 }
00189
00190 BOOL CAsyncSocket::SetHandlers()
00191 {
00192 try
00193 {
00194
00195 if (!m_pThreadManager)
00196 {
00197
00198 int iThreads;
00199 if (CSocketBase::IsMultiThreaded())
00200 iThreads=CSocketBase::GetNumberOfThreads();
00201 else
00202 iThreads=1;
00203
00204
00205 m_pThreadManager=new CSocketThreadManagerImp(m_hInstance);
00206 if (!m_pThreadManager->Initialize(iThreads))
00207 {
00208
00209 ReportStaticError(CAsyncSocket_Class,"SetHandlers","Failed to initialize the thread manager!");
00210
00211
00212 delete m_pThreadManager;
00213 m_pThreadManager=NULL;
00214
00215
00216 return FALSE;
00217 }
00218 }
00219
00220
00221
00222 return TRUE;
00223 }
00224 ERROR_HANDLER_STATIC_RETURN(CAsyncSocket_Class,"CAsyncSocket",FALSE)
00225 }
00226
00227 HINSTANCE CAsyncSocket::GetInstance()
00228 {
00229
00230 return m_hInstance;
00231 }
00232
00233 void CAsyncSocket::AddSocketToList()
00234 {
00235 try
00236 {
00237
00238 AllocateHandle();
00239
00240
00241 m_bList=TRUE;
00242 }
00243 ERROR_HANDLER("AddSocketToList")
00244 }
00245
00246 int CAsyncSocket::GetSocketID()const
00247 {
00248 return m_iSocketID;
00249 }
00250
00251 void CAsyncSocket::SetInstance(HINSTANCE hInst)
00252 {
00253 m_hInstance=hInst;
00254 }
00255
00256 HWND CAsyncSocket::GetWindowHandle()const
00257 {
00258
00259 return m_hLocalWindowHandle;
00260 }
00261
00262 void CAsyncSocket::RemoveSocketFromList()
00263 {
00264 try
00265 {
00266 if (m_bList)
00267 {
00268
00269 GetThreadManager()->RemoveSocket(this);
00270
00271
00272 m_bList=FALSE;
00273
00274
00275 DeAllocateHandle();
00276 }
00277 }
00278 ERROR_HANDLER("RemoveSocketFromList")
00279 }
00280
00281 BOOL CAsyncSocket::SetTimeout(int iMs)
00282 {
00283 try
00284 {
00285
00286 HWND hWindowHandle;
00287 hWindowHandle=GetWindowHandle();
00288
00289 if (!hWindowHandle)
00290 return FALSE;
00291
00292
00293 m_bTimeout=SetTimer(hWindowHandle,
00294 GetAsyncHandle(),
00295 iMs,
00296 NULL);
00297
00298 return m_bTimeout;
00299 }
00300 ERROR_HANDLER_RETURN("SetTimeout",FALSE)
00301 }
00302
00303 BOOL CAsyncSocket::KillTimer()
00304 {
00305 try
00306 {
00307
00308 HWND hWindowHandle;
00309 hWindowHandle=GetWindowHandle();
00310
00311 if (!hWindowHandle ||
00312 !m_bTimeout)
00313 return FALSE;
00314
00315
00316 m_bTimeout=FALSE;
00317
00318
00319 BOOL bResult;
00320 bResult=::KillTimer(hWindowHandle,
00321 GetAsyncHandle());
00322
00323 if (!bResult)
00324
00325 ReportError("KillTimer");
00326
00327 return bResult;
00328 }
00329 ERROR_HANDLER_RETURN("KillTimer",FALSE)
00330 }
00331
00332 void CAsyncSocket::Shutdown()
00333 {
00334 try
00335 {
00336
00337 if (!m_bInitialized)
00338 return;
00339
00340
00341 m_bShuttingDown=TRUE;
00342
00343
00344 if (m_pThreadManager)
00345 {
00346 delete m_pThreadManager;
00347 m_pThreadManager=NULL;
00348 }
00349
00350
00351 m_bInitialized=FALSE;
00352 }
00353 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"Shutdown")
00354 }
00355
00356 BOOL CAsyncSocket::IsTimeout() const
00357 {
00358 return m_bTimeout;
00359 }
00360
00361 void CAsyncSocket::Initialize()
00362 {
00363 try
00364 {
00365
00366 if (!m_bInitialized &&
00367 CSocketBase::IsInitialized())
00368 {
00369
00370 m_pCSection=COSManager::CreateCriticalSection();
00371
00372
00373 if (!SetHandlers())
00374 {
00375
00376 ReportStaticError(CAsyncSocket_Class,"CAsyncSocket","Failed to init handlers!");
00377
00378
00379 return;
00380 }
00381
00382
00383 CAsyncShutdown* pShutdown;
00384 pShutdown=new CAsyncShutdown;
00385
00386
00387 m_bInitialized=TRUE;
00388 }
00389 }
00390 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"Initialize")
00391 }
00392
00393 CSocketThreadManagerImp* CAsyncSocket::GetThreadManager()const
00394 {
00395 if (!m_pLocalThreadManager)
00396 return m_pThreadManager;
00397 else
00398 return m_pLocalThreadManager;
00399 }
00400
00401 void CAsyncSocket::AllocateHandle()
00402 {
00403 try
00404 {
00405
00406 m_pThread=NULL;
00407
00408
00409 m_hLocalWindowHandle=GetThreadManager()->GetWindowHandle(this);
00410
00411
00412 m_pThread=GetThreadManager()->GetThreadByHWND(m_hLocalWindowHandle);
00413 }
00414 ERROR_HANDLER_RETHROW("AllocateHandle")
00415 }
00416
00417 void CAsyncSocket::DeAllocateHandle()
00418 {
00419
00420 m_hLocalWindowHandle=0;
00421
00422
00423 m_pThread=NULL;
00424 }
00425
00426 BOOL CAsyncSocket::DisableAsync()
00427 {
00428 try
00429 {
00430
00431 if (!CheckAsyncSocketValid())
00432 return FALSE;
00433
00434
00435 int iResult;
00436
00437 iResult=WSAAsyncSelect(GetAsyncHandle(),
00438 GetWindowHandle(),
00439 0,
00440 0);
00441 if (iResult)
00442 {
00443
00444 SetLastError("DisableAsync");
00445
00446
00447 return FALSE;
00448 }
00449
00450 return TRUE;
00451 }
00452 ERROR_HANDLER_RETURN("DisableAsync",FALSE)
00453 }
00454
00455 BOOL CAsyncSocket::CheckAsyncSocketValid() const
00456 {
00457 try
00458 {
00459
00460 if (GetAsyncHandle()==INVALID_SOCKET)
00461 {
00462
00463 ReportError("CheckAsyncSocketValid","Operation made on non existant socket!");
00464
00465
00466 return FALSE;
00467 }
00468
00469
00470 return TRUE;
00471 }
00472 ERROR_HANDLER_RETURN("CheckAsyncSocketValid",FALSE)
00473 }
00474
00475 void CAsyncSocket::SocketClosing()
00476 {
00477 try
00478 {
00479
00480 if (m_bClosing ||
00481 GetAsyncHandle()==INVALID_SOCKET)
00482 return;
00483
00484
00485 m_bClosing=TRUE;
00486
00487
00488 m_pSendEvent->Set();
00489
00490
00491 if (m_bTimeout)
00492 KillTimer();
00493
00494
00495 if (m_aTimerID.iTimerID)
00496 KillSystemTimer();
00497
00498
00499 m_iMsg=0;
00500 m_lEvent=0;
00501
00502
00503 if (WSAAsyncSelect(GetAsyncHandle(),
00504 GetWindowHandle(),
00505 0,
00506 0))
00507 SetLastError("SocketClosing");
00508 }
00509 ERROR_HANDLER("SocketClosing")
00510 }
00511
00512 void CAsyncSocket::FreezeThread()
00513 {
00514 m_bFreeze=TRUE;
00515 }
00516
00517 BOOL CAsyncSocket::ReBlock()
00518 {
00519 if (m_bBlocking)
00520 return TRUE;
00521
00522 try
00523 {
00524
00525 if (!CheckAsyncSocketValid())
00526 return FALSE;
00527
00528 if (Block())
00529
00530 m_bBlocking=TRUE;
00531
00532
00533 return TRUE;
00534 }
00535 ERROR_HANDLER_RETURN("ReBlock",FALSE)
00536 }
00537
00538 int CAsyncSocket::InternalWSAAsyncSelect(unsigned int wMsg,
00539 long lEvent)
00540 {
00541 try
00542 {
00543
00544 m_iMsg=wMsg;
00545 m_lEvent=lEvent;
00546
00547
00548 typedef struct _MsgPair
00549 {
00550 unsigned int uiMsg;
00551 AsyncEvents aEvents;
00552 } MsgPair;
00553
00554
00555 static const int iMaxEvents=4;
00556
00557
00558 static const MsgPair aMsgPair[iMaxEvents]={{FD_READ,aeReceive},
00559 {FD_WRITE,aeSend},
00560 {FD_OOB,aeOOB},
00561 {FD_CLOSE,aeClose}};
00562
00563
00564 for (int iCounter=0;
00565 iCounter<iMaxEvents;
00566 ++iCounter)
00567 if ((m_lEvent & aMsgPair[iCounter].uiMsg) &&
00568 (m_ucEvents & ((unsigned char)aMsgPair[iCounter].aEvents)))
00569
00570 m_lEvent^=aMsgPair[iCounter].uiMsg;
00571
00572 if (m_bBlocking)
00573 return 0;
00574 else
00575
00576 return WSAAsyncSelect(GetAsyncHandle(),
00577 GetWindowHandle(),
00578 wMsg,
00579 lEvent);
00580 }
00581 ERROR_HANDLER_RETURN("InternalWSAAsyncSelect",GetErrorCode())
00582 }
00583
00584 BOOL CAsyncSocket::ClearEvents()
00585 {
00586 try
00587 {
00588
00589 if (!CheckAsyncSocketValid())
00590 return FALSE;
00591
00592
00593 return !InternalWSAAsyncSelect(0,0);
00594 }
00595 ERROR_HANDLER_RETURN("ClearEvents",FALSE)
00596 }
00597
00598 BOOL CAsyncSocket::ReAsync()
00599 {
00600 if (!m_bBlocking)
00601 return TRUE;
00602
00603 try
00604 {
00605
00606 if (!CheckAsyncSocketValid())
00607 return FALSE;
00608
00609
00610 int iResult;
00611 iResult=WSAAsyncSelect(GetAsyncHandle(),
00612 GetWindowHandle(),
00613 m_iMsg,
00614 m_lEvent);
00615
00616 if (iResult)
00617 {
00618
00619 SetLastError("ReAsync");
00620
00621
00622 return FALSE;
00623 }
00624
00625
00626 m_bBlocking=FALSE;
00627
00628
00629 return TRUE;
00630 }
00631 ERROR_HANDLER_RETURN("ReAsync",FALSE)
00632 }
00633
00634 BOOL CAsyncSocket::Block()
00635 {
00636 try
00637 {
00638
00639 int iResult;
00640 iResult=WSAAsyncSelect(GetAsyncHandle(),
00641 GetWindowHandle(),
00642 0,
00643 0);
00644
00645 if (iResult)
00646 {
00647
00648 SetLastError("Block");
00649
00650
00651 return FALSE;
00652 }
00653
00654 unsigned long ulBlocking;
00655 ulBlocking=0;
00656
00657
00658 iResult=ioctlsocket(GetAsyncHandle(),
00659 FIONBIO,
00660 &ulBlocking);
00661
00662 if (iResult)
00663 {
00664
00665 SetLastError("Block");
00666
00667
00668 return FALSE;
00669 }
00670
00671 return TRUE;
00672 }
00673 ERROR_HANDLER_RETURN("Block",FALSE)
00674 }
00675
00676 BOOL CAsyncSocket::IsBlocking() const
00677 {
00678 return m_bBlocking;
00679 }
00680
00681 void CAsyncSocket::AllowBlockedBuffer(BOOL bAllow)
00682 {
00683 try
00684 {
00685
00686 if (bAllow &&
00687 !m_pBlockedBuffer)
00688 m_pBlockedBuffer=new CBlockedBuffer(this);
00689 else if (!bAllow &&
00690 m_pBlockedBuffer)
00691 {
00692
00693 delete m_pBlockedBuffer;
00694 m_pBlockedBuffer=NULL;
00695 }
00696 }
00697 ERROR_HANDLER("AllowBlockedBuffer")
00698 }
00699
00700 CBlockedBuffer* CAsyncSocket::GetBlockedBuffer()const
00701 {
00702 return m_pBlockedBuffer;
00703 }
00704
00705 BOOL CAsyncSocket::SendBlockedBuffer(const CBlockedBuffer::CBlockedData& rData)
00706 {
00707
00708 return FALSE;
00709 }
00710
00711 CSocketThreadManagerImp* CAsyncSocket::GetSocketThreadManager()
00712 {
00713 return m_pThreadManager;
00714 }
00715
00716 BOOL CAsyncSocket::SocketConnected(int iErrorCode,
00717 BOOL bNoEvent)
00718 {
00719 try
00720 {
00721
00722 if (iErrorCode)
00723 if (!bNoEvent)
00724 return OnSocketConnect(iErrorCode);
00725 else
00726 return FALSE;
00727
00728
00729 BOOL bConnectValue;
00730 if (!bNoEvent)
00731 bConnectValue=OnSocketConnect(0);
00732 else
00733 bConnectValue=TRUE;
00734
00735
00736 if (!SetAsync())
00737 return FALSE;
00738 else
00739 return bConnectValue;
00740 }
00741 ERROR_HANDLER_RETURN("SocketConnected",FALSE)
00742 }
00743
00744 BOOL CAsyncSocket::SocketReceive(int iErrorCode,
00745 BOOL bNoEvent)
00746 {
00747 try
00748 {
00749
00750 if (!bNoEvent)
00751 return OnSocketReceive(iErrorCode);
00752 else
00753 return FALSE;
00754 }
00755 ERROR_HANDLER_RETURN("SocketConnected",FALSE)
00756 }
00757
00758 BOOL CAsyncSocket::SocketAccept(int iErrorCode,
00759 BOOL bNoEvent)
00760 {
00761 try
00762 {
00763
00764 if (!bNoEvent)
00765 return OnSocketAccept(iErrorCode);
00766 else
00767 return FALSE;
00768 }
00769 ERROR_HANDLER_RETURN("SocketConnected",FALSE)
00770 }
00771
00772 BOOL CAsyncSocket::SocketClosed(int iErrorCode,
00773 BOOL bNoEvent)
00774 {
00775 try
00776 {
00777
00778 CAsyncSocket::SocketClosing();
00779
00780
00781 RemoveSocketFromList();
00782
00783
00784 if (!bNoEvent)
00785 return OnSocketClose(iErrorCode);
00786 else
00787 return TRUE;
00788 }
00789 ERROR_HANDLER_RETURN("SocketClosed",FALSE)
00790 }
00791
00792 BOOL CAsyncSocket::SocketWrite(int iErrorCode)
00793 {
00794 try
00795 {
00796
00797 m_pSendEvent->Set();
00798
00799
00800 return OnSocketWrite(iErrorCode);
00801 }
00802 ERROR_HANDLER_RETURN("SocketWrite",FALSE)
00803 }
00804
00805 void CAsyncSocket::SimpleMessageMap()
00806 {
00807 try
00808 {
00809
00810 MSG msg;
00811
00812
00813 memset(&msg,
00814 0,
00815 sizeof(msg));
00816
00817 while (GetMessage(&msg,
00818 NULL,
00819 0,
00820 0))
00821 {
00822
00823 TranslateMessage(&msg);
00824 DispatchMessage(&msg);
00825 }
00826 }
00827 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"SimpleMessageMap")
00828 }
00829
00830 void CAsyncSocket::SimpleMessageMap(DWORD dwRunTimeMS)
00831 {
00832 try
00833 {
00834
00835 MSG msg;
00836
00837
00838 memset(&msg,
00839 0,
00840 sizeof(msg));
00841
00842
00843 DWORD dwLoopStart;
00844 dwLoopStart=GetTickCount();
00845
00846
00847 while (GetTickCount()-dwLoopStart<dwRunTimeMS)
00848 {
00849 while (PeekMessage(&msg,
00850 NULL,
00851 0,
00852 0,
00853 PM_REMOVE))
00854 {
00855 TranslateMessage(&msg);
00856 DispatchMessage(&msg);
00857 }
00858
00859
00860 Sleep(1);
00861 }
00862 }
00863 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"SimpleMessageMap")
00864 }
00865
00866 void CAsyncSocket::SimpleMessageMap(LPMapProc pProc,
00867 BOOL bStopWhenTRUE,
00868 DWORD dwSleep)
00869 {
00870 try
00871 {
00872
00873 if (!pProc)
00874 {
00875
00876 ReportStaticError(CAsyncSocket_Class,"SimpleMessageMap","Recieved null proc!");
00877
00878
00879 return;
00880 }
00881
00882
00883 MSG msg;
00884
00885
00886 memset(&msg,
00887 0,
00888 sizeof(msg));
00889
00890
00891 BOOL bStop;
00892 bStop=FALSE;
00893
00894
00895 while (!bStop &&
00896 (*pProc)()!=bStopWhenTRUE)
00897 {
00898 while (!(bStop=(*pProc)()==bStopWhenTRUE) &&
00899 PeekMessage(&msg,
00900 NULL,
00901 0,
00902 0,
00903 PM_REMOVE))
00904 {
00905 TranslateMessage(&msg);
00906 DispatchMessage(&msg);
00907 }
00908
00909
00910 if (!bStop)
00911
00912 Sleep(dwSleep);
00913 }
00914 }
00915 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"SimpleMessageMap")
00916 }
00917
00918 char CAsyncSocket::SimpleMessageMapKey(DWORD dwSleep)
00919 {
00920 try
00921 {
00922
00923 MSG msg;
00924
00925
00926 memset(&msg,
00927 0,
00928 sizeof(msg));
00929
00930
00931 while (!kbhit())
00932 {
00933 while (!kbhit() &&
00934 PeekMessage(&msg,
00935 NULL,
00936 0,
00937 0,
00938 PM_REMOVE))
00939 {
00940 TranslateMessage(&msg);
00941 DispatchMessage(&msg);
00942 }
00943
00944
00945 if (!kbhit())
00946
00947 Sleep(dwSleep);
00948 }
00949
00950
00951 return getch();
00952 }
00953 ERROR_HANDLER_STATIC_RETURN(CAsyncSocket_Class,"SimpleMessageMapKey",0)
00954 }
00955
00956 BOOL CAsyncSocket::SetSystemTimeout(int iMS)
00957 {
00958 try
00959 {
00960
00961 if (m_aTimerID.iTimerID)
00962 {
00963
00964 ReportError("SetSystemTimeout","Please kill previous timer!");
00965
00966
00967 return FALSE;
00968 }
00969
00970
00971 m_aTimerID=GetThreadManager()->RegisterTimeout(iMS,
00972 SystemTimerProc,
00973 this,
00974 TRUE,
00975 GetWindowHandle(),
00976 &m_aTimerID);
00977
00978
00979 if (!m_aTimerID.iTimerID)
00980 {
00981
00982 ReportError("SetSystemTimeout","Failed creating the timer!");
00983
00984
00985 return FALSE;
00986 }
00987 else
00988 return TRUE;
00989 }
00990 ERROR_HANDLER_RETURN("SetSystemTimeout",FALSE)
00991 }
00992
00993 BOOL CAsyncSocket::KillSystemTimer()
00994 {
00995 try
00996 {
00997
00998 if (!m_aTimerID.iTimerID)
00999 return TRUE;
01000
01001 return GetThreadManager()->RemoveTimeout(m_aTimerID);
01002 }
01003 ERROR_HANDLER_RETURN("KillSystemTimer",FALSE)
01004 }
01005
01006 void CAsyncSocket::SystemTimeout()
01007 {
01008
01009 }
01010
01011 void CAsyncSocket::SystemTimerProc(LPVOID lpData)
01012 {
01013 try
01014 {
01015
01016 CAsyncSocket* pClass;
01017 pClass=(CAsyncSocket*)lpData;
01018
01019
01020 memset(&pClass->m_aTimerID,
01021 0,
01022 sizeof(pClass->m_aTimerID));
01023
01024
01025 pClass->SystemTimeout();
01026 }
01027 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"SystemTimerProc")
01028 }
01029
01030 void CAsyncSocket::DeleteTimerProc(LPVOID lpData)
01031 {
01032 try
01033 {
01034
01035 CAsyncSocket* pClass;
01036 pClass=(CAsyncSocket*)lpData;
01037
01038
01039 pClass->DeleteSocketFromThread();
01040 }
01041 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"SystemTimerProc")
01042 }
01043
01044 BOOL CAsyncSocket::HasSystemTimer()const
01045 {
01046 return m_aTimerID.iTimerID!=0;
01047 }
01048
01049 void CAsyncSocket::OnSocketDelete(CGenericEvent* pEvent)
01050 {
01051 try
01052 {
01053
01054 delete this;
01055
01056
01057 if (pEvent)
01058 pEvent->Set();
01059 }
01060 ERROR_HANDLER_STATIC(CAsyncSocket_Class,"OnSocketDelete")
01061 }
01062
01063 void CAsyncSocket::ForceReceiveEvent()
01064 {
01065 try
01066 {
01067
01068
01069 if (!m_bList)
01070 OnSocketDelete();
01071 else
01072 PostMessage(GetWindowHandle(),
01073 WM_SOCKET_FORCED,
01074 (WPARAM)GetAsyncHandle(),
01075 0);
01076 }
01077 ERROR_HANDLER("ForceReceiveEvent")
01078 }
01079
01080 void CAsyncSocket::DeleteSocketFromThread()
01081 {
01082 try
01083 {
01084
01085 SocketClosing();
01086
01087
01088
01089 if (!m_bList)
01090 OnSocketDelete();
01091 else
01092 PostMessage(GetWindowHandle(),
01093 WM_SOCKET_DELETE,
01094 (WPARAM)GetAsyncHandle(),
01095 0);
01096 }
01097 ERROR_HANDLER("OnSocketDelete")
01098 }
01099
01100 void CAsyncSocket::DeleteSocketFromThread(DWORD dwTimeToWait)
01101 {
01102 try
01103 {
01104 if (!dwTimeToWait)
01105 DeleteSocketFromThread();
01106 else
01107 {
01108
01109 SocketClosing();
01110
01111
01112
01113 if (!m_bList)
01114 OnSocketDelete();
01115 else
01116 {
01117
01118 m_aDeleteTimerID=GetThreadManager()->RegisterTimeout(dwTimeToWait,
01119 DeleteTimerProc,
01120 (LPVOID)this,
01121 TRUE,
01122 GetWindowHandle(),
01123 &m_aDeleteTimerID);
01124
01125
01126 if (!m_aDeleteTimerID.iTimerID)
01127 {
01128
01129 ReportError("DeleteSocketFromThread","Failed to create timeout!");
01130
01131
01132 DeleteSocketFromThread();
01133 }
01134 }
01135 }
01136 }
01137 ERROR_HANDLER("OnSocketDelete")
01138 }
01139
01140 void CAsyncSocket::DeleteSocketFromThreadWait()
01141 {
01142 try
01143 {
01144
01145 SocketClosing();
01146
01147
01148
01149 if (!m_bList)
01150 OnSocketDelete();
01151 else
01152 {
01153
01154 CGenericEvent* pEvent;
01155 pEvent=COSManager::CreateEvent();
01156
01157
01158 PostMessage(GetWindowHandle(),
01159 WM_SOCKET_DELETE,
01160 (WPARAM)GetAsyncHandle(),
01161 (LPARAM)pEvent);
01162
01163
01164 if (pEvent->Wait(15000))
01165
01166 ReportStaticError(CAsyncSocket_Class,"DeleteSocketFromThreadWait","Timeout waiting for event!");
01167 else
01168 delete pEvent;
01169 }
01170 }
01171 ERROR_HANDLER("OnSocketDelete")
01172 }
01173
01174 void CAsyncSocket::SocketCreated()
01175 {
01176 try
01177 {
01178
01179 memset(&m_aTimerID,
01180 0,
01181 sizeof(m_aTimerID));
01182
01183
01184 memset(&m_aDeleteTimerID,
01185 0,
01186 sizeof(m_aDeleteTimerID));
01187
01188
01189 m_iSocketID=0;
01190 m_bBlocking=FALSE;
01191 m_bFreeze=FALSE;
01192 m_lEvent=0;
01193 m_hLocalWindowHandle=0;
01194 m_bList=FALSE;
01195 m_bClosing=FALSE;
01196 }
01197 ERROR_HANDLER("SocketCreated")
01198 }
01199
01200 BOOL CAsyncSocket::IsClosing()const
01201 {
01202 return m_bClosing;
01203 }
01204
01205 void CAsyncSocket::DisableEvents(unsigned char ucEvents)
01206 {
01207 try
01208 {
01209
01210 m_ucEvents=ucEvents;
01211 }
01212 ERROR_HANDLER("DisableEvents")
01213 }
01214
01215 BOOL CAsyncSocket::HasTimeout()const
01216 {
01217 return m_bTimeout;
01218 }
01219
01220 CSocketThreadManagerImp::TimerID CAsyncSocket::RegisterTimeout(int iMS,
01221 CSocketThreadManagerImp::LPTimeoutProc pProc,
01222 LPVOID pData,
01223 BOOL bClearTimeout,
01224 CSocketThreadManagerImp::TimerID* pTimer)
01225 {
01226
01227 return GetThreadManager()->RegisterTimeout(iMS,
01228 pProc,
01229 pData,
01230 bClearTimeout,
01231 GetWindowHandle(),
01232 pTimer);
01233 }
01234
01235 BOOL CAsyncSocket::SetLocalThreadManager(CSocketThreadManagerImp* pManager)
01236 {
01237 try
01238 {
01239
01240 if (GetAsyncHandle()!=INVALID_SOCKET)
01241 {
01242
01243 ReportError("SetLocalThreadManager","Can't switch after socket is created!");
01244
01245
01246 return FALSE;
01247 }
01248
01249
01250 if (!pManager ||
01251 !pManager->IsInitialized())
01252 {
01253
01254 ReportError("SetLocalThreadManager","Manager is either null or not initialized!");
01255
01256
01257 return FALSE;
01258 }
01259
01260
01261 m_pLocalThreadManager=pManager;
01262
01263
01264 return TRUE;
01265 }
01266 ERROR_HANDLER_RETURN("SetLocalThreadManager",FALSE)
01267 }
01268
01269 CSocketThreadManagerImp* CAsyncSocket::CloneThreadManager(unsigned long ulThreads)
01270 {
01271 try
01272 {
01273
01274 if (!m_pThreadManager ||
01275 !m_pThreadManager->IsInitialized())
01276 {
01277
01278 ReportStaticError(CAsyncSocket_Class,"SetLocalThreadManager","Manager is either null or not initialized!");
01279
01280
01281 return NULL;
01282 }
01283
01284
01285 unsigned long ulThreadCount;
01286 if (!ulThreads)
01287 ulThreadCount=m_pThreadManager->GetNumberOfThreads();
01288 else
01289 ulThreadCount=ulThreads;
01290
01291
01292 CSocketThreadManagerImp* pManager;
01293 pManager=new CSocketThreadManagerImp(m_hInstance);
01294 if (!pManager->Initialize(ulThreads))
01295 {
01296
01297 ReportStaticError(CAsyncSocket_Class,"CloneThreadManager","Failed to initialize the thread manager!");
01298
01299
01300 delete pManager;
01301
01302
01303 return NULL;
01304 }
01305 else
01306 return pManager;
01307 }
01308 ERROR_HANDLER_STATIC_RETURN(CAsyncSocket_Class,"CloneThreadManager",NULL)
01309 }
01310
01311 BOOL CAsyncSocket::IsBlockSend()const
01312 {
01313 return m_bBlockSend;
01314 }
01315
01316 BOOL CAsyncSocket::IsInThread()const
01317 {
01318 try
01319 {
01320
01321 if (m_pThread)
01322 return m_pThread->IsInThread();
01323 else
01324 return FALSE;
01325 }
01326 ERROR_HANDLER_RETURN("IsInThread",FALSE)
01327 }
01328
01329 BOOL CAsyncSocket::WaitForBlockEvent()const
01330 {
01331
01332 if (m_pSendEvent->Wait(5000))
01333 return TRUE;
01334 else
01335 return IsClosing();
01336 }
01337
01338 void CAsyncSocket::ResetEvent()
01339 {
01340 m_pSendEvent->Reset();
01341 }
01342
01343 void CAsyncSocket::DisableBlockingSend()
01344 {
01345 m_bBlockSend=FALSE;
01346 }
01347
01348 BOOL CAsyncSocket::IsDeleting()const
01349 {
01350 return m_bDeleting;
01351 }
01352
01353 void CAsyncSocket::SetDeleting()
01354 {
01355 m_bDeleting=TRUE;
01356 }
01357
01358 void CAsyncSocket::SetCleanTimeout(DWORD dwTimeout)
01359 {
01360
01361 if (m_pThreadManager)
01362 m_pThreadManager->SetCleanTimeout(dwTimeout);
01363 }
01364
01365 KOMODIA_NAMESPACE_END