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 "SocketThreadManagerImp.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "OSManager.h"
00041 #include "GenericCriticalSection.h"
00042
00043 #include "AsyncSocket.h"
00044
00045 #include <vector>
00046
00047 #ifdef _MEMORY_DEBUG
00048 #define new DEBUG_NEW
00049 #define malloc DEBUG_MALLOC
00050 static char THIS_FILE[] = __FILE__;
00051 #endif
00052
00053 KOMODIA_NAMESPACE_START
00054
00055
00056 BOOL CSocketThreadManagerImp::m_bWindow=FALSE;
00057
00058
00059 CSocketThreadManagerImp CSocketThreadManagerImp::m_sCleanUp;
00060
00061
00062 HINSTANCE CSocketThreadManagerImp::m_hInstance=0;
00063
00064 #define CSocketThreadManagerImp_Class "CSocketThreadManagerImp"
00065
00066 CSocketThreadManagerImp::CSocketThreadManagerImp() : CSocketThreadManager((HINSTANCE)0),
00067 m_bStatic(TRUE),
00068 m_hLocalInstance(0)
00069 {
00070 try
00071 {
00072
00073 SetName(CSocketThreadManagerImp_Class);
00074 }
00075 ERROR_HANDLER("CSocketThreadManagerImp")
00076 }
00077
00078 CSocketThreadManagerImp::CSocketThreadManagerImp(HINSTANCE hInstance) : CSocketThreadManager(hInstance),
00079 m_hLocalInstance(hInstance),
00080 m_bStatic(FALSE)
00081 {
00082 try
00083 {
00084
00085 SetName(CSocketThreadManagerImp_Class);
00086 }
00087 ERROR_HANDLER("CSocketThreadManagerImp")
00088 }
00089
00090 CSocketThreadManagerImp::~CSocketThreadManagerImp()
00091 {
00092 try
00093 {
00094
00095 if (m_bStatic)
00096
00097 if (m_bWindow)
00098 {
00099
00100 ::UnregisterClass(CSocketThreadManagerImp_Class,
00101 m_hInstance);
00102
00103
00104 m_bWindow=FALSE;
00105 }
00106 else
00107 ;
00108 else
00109
00110 Uninitialize();
00111 }
00112 ERROR_HANDLER("~CSocketThreadManagerImp")
00113 }
00114
00115 void CSocketThreadManagerImp::ParseDispatchMessage(const MSG& rMsg,
00116 ThreadData* pData)
00117 {
00118
00119 ExtensionData* pExtension;
00120 pExtension=(ExtensionData*)pData->aExtension.lpData;
00121
00122
00123 MSG aNewMsg(rMsg);
00124
00125
00126 if (rMsg.wParam &&
00127 IsSocketMessage(aNewMsg.message))
00128 {
00129
00130 CCriticalAutoRelease aRelease(pExtension->pCSection);
00131
00132
00133 SocketMap::iterator aIterator;
00134 aIterator=pExtension->aSocketsMap.find((int)rMsg.wParam);
00135
00136
00137 if (aIterator!=pExtension->aSocketsMap.end())
00138
00139 aNewMsg.wParam=(WPARAM)aIterator->second;
00140 else
00141 aNewMsg.wParam=0;
00142 }
00143
00144
00145 CSocketThreadManager::ParseDispatchMessage(aNewMsg,
00146 pData);
00147 }
00148
00149 void CSocketThreadManagerImp::CreateExtendedData(ThreadDataExtend& rData)
00150 {
00151 try
00152 {
00153
00154 ExtensionData* pData;
00155 pData=new ExtensionData;
00156
00157
00158 pData->pCSection=COSManager::CreateCriticalSection();
00159
00160
00161 rData.lpData=(LPVOID)pData;
00162 }
00163 ERROR_HANDLER("CreateExtendedData")
00164 }
00165
00166 void CSocketThreadManagerImp::DeleteExtendedData(ThreadDataExtend& rData)
00167 {
00168 try
00169 {
00170
00171 ExtensionData* pData;
00172 pData=(ExtensionData*)rData.lpData;
00173
00174
00175 if (pData)
00176 {
00177
00178 typedef std::vector<CAsyncSocket*> DeleteVector;
00179
00180
00181 DeleteVector aDeleteVector;
00182
00183 {
00184
00185 CCriticalAutoRelease aRelease(pData->pCSection);
00186
00187
00188 SocketMap::iterator aIterator;
00189 aIterator=pData->aSocketsMap.begin();
00190 while (aIterator!=pData->aSocketsMap.end())
00191 {
00192
00193 aDeleteVector.push_back(aIterator->second);
00194
00195
00196 aIterator=pData->aSocketsMap.erase(aIterator);
00197 }
00198 }
00199
00200
00201 for (int iCount=0;
00202 iCount<aDeleteVector.size();
00203 ++iCount)
00204 try
00205 {
00206
00207 aDeleteVector[iCount]->SetDeleting();
00208
00209
00210 delete aDeleteVector[iCount];
00211 }
00212 ERROR_HANDLER("DeleteExtendedData - Socket delete")
00213
00214
00215 delete pData->pCSection;
00216
00217
00218 delete pData;
00219
00220
00221 rData.lpData=NULL;
00222 }
00223 }
00224 ERROR_HANDLER("DeleteExtendedData")
00225 }
00226
00227 BOOL CSocketThreadManagerImp::Initialize(unsigned long ulThreadCount)
00228 {
00229 try
00230 {
00231
00232 if (!m_bWindow)
00233 {
00234
00235 m_hInstance=m_hLocalInstance;
00236
00237 if (!RegisterWindow(m_hInstance))
00238 {
00239
00240 ReportErrorOS("SetHandlers","Error registering the window, please check API error!");
00241
00242
00243 return FALSE;
00244 }
00245 else
00246
00247 m_bWindow=TRUE;
00248 }
00249
00250
00251 return CSocketThreadManager::Initialize(ulThreadCount,
00252 CSocketThreadManagerImp_Class);
00253 }
00254 ERROR_HANDLER_RETURN("Initialize",FALSE)
00255 }
00256
00257 BOOL CSocketThreadManagerImp::RegisterWindow(HINSTANCE hInstance)
00258 {
00259 try
00260 {
00261
00262 WNDCLASS wc;
00263 wc.style = 0;
00264 wc.lpfnWndProc = (WNDPROC)SocketMessageHandler;
00265 wc.cbClsExtra = 0;
00266 wc.cbWndExtra = 0;
00267 wc.hIcon = NULL;
00268 wc.hInstance = hInstance;
00269 wc.hCursor = NULL;
00270 wc.hbrBackground = NULL;
00271 wc.lpszMenuName = NULL;
00272 wc.lpszClassName = CSocketThreadManagerImp_Class ;
00273
00274
00275 return ::RegisterClass(&wc);
00276 }
00277 ERROR_HANDLER_STATIC_RETURN(CSocketThreadManagerImp_Class,"RegisterWindow",FALSE)
00278 }
00279
00280 HWND CSocketThreadManagerImp::GetWindowHandle(CAsyncSocket* pSocket)
00281 {
00282 try
00283 {
00284
00285 HWND hHandle;
00286 hHandle=CSocketThreadManager::GetWindowHandle();
00287
00288
00289 if (hHandle)
00290
00291 AddSocketToList(pSocket,
00292 hHandle);
00293
00294
00295 return hHandle;
00296 }
00297 ERROR_HANDLER_RETURN("GetWindowHandle",NULL)
00298 }
00299
00300 void CSocketThreadManagerImp::AddSocketToList(CAsyncSocket* pSocket,
00301 HWND hHandle)
00302 {
00303 try
00304 {
00305
00306 ThreadData* pData;
00307 pData=GetDataByHWND(hHandle);
00308
00309
00310 if (!pData)
00311
00312 ReportError("AddSocketToList","Failed to find thread data!");
00313 else
00314 {
00315
00316 ExtensionData* pExtension;
00317 pExtension=(ExtensionData*)pData->aExtension.lpData;
00318
00319
00320 CCriticalAutoRelease aRelease(pExtension->pCSection);
00321
00322
00323 pExtension->aSocketsMap.insert(SocketMap::value_type(pSocket->GetAsyncHandle(),
00324 pSocket));
00325 }
00326 }
00327 ERROR_HANDLER("AddSocketToList")
00328 }
00329
00330 void CSocketThreadManagerImp::RemoveSocket(CAsyncSocket* pSocket)
00331 {
00332 try
00333 {
00334
00335 HWND hHandle;
00336 hHandle=pSocket->GetWindowHandle();
00337
00338
00339 if (!hHandle)
00340 {
00341
00342 ReportError("RemoveSocket","Received socket without a handle!");
00343
00344
00345 return;
00346 }
00347
00348
00349 ThreadData* pData;
00350 pData=GetDataByHWND(hHandle);
00351
00352
00353 if (!pData)
00354
00355 ReportError("RemoveSocket","Failed to find thread data!");
00356 else
00357 {
00358
00359 ExtensionData* pExtension;
00360 pExtension=(ExtensionData*)pData->aExtension.lpData;
00361
00362 {
00363
00364 CCriticalAutoRelease aRelease(pExtension->pCSection);
00365
00366
00367 pExtension->aSocketsMap.erase(pSocket->GetAsyncHandle());
00368 }
00369
00370
00371 DecreaseSocketCount(hHandle,
00372 TRUE);
00373 }
00374 }
00375 ERROR_HANDLER("RemoveSocket")
00376 }
00377
00378 BOOL CSocketThreadManagerImp::IsSocketMessage(unsigned int uiMsg)
00379 {
00380 return uiMsg==WM_SOCKET_DELETE ||
00381 uiMsg==WM_SOCKET_FORCED ||
00382 uiMsg==WM_SOCKET_GENERAL ||
00383 uiMsg==WM_SOCKET_CONNECT ||
00384 uiMsg==WM_SOCKET_ACCEPT ||
00385 uiMsg==WM_TIMER;
00386 }
00387
00388 LRESULT CALLBACK CSocketThreadManagerImp::SocketMessageHandler(HWND hwnd,
00389 UINT uMsg,
00390 WPARAM wParam,
00391 LPARAM lParam)
00392 {
00393 try
00394 {
00395
00396 CAsyncSocket* pSocket;
00397
00398
00399 if (IsSocketMessage(uMsg))
00400 pSocket=(CAsyncSocket*)(wParam);
00401 else
00402 pSocket=NULL;
00403
00404
00405 BOOL bIgnore;
00406 if (pSocket &&
00407 pSocket->IsClosing() &&
00408 uMsg!=WM_SOCKET_DELETE)
00409 bIgnore=TRUE;
00410 else if (pSocket &&
00411 pSocket->m_hLocalWindowHandle!=hwnd)
00412 {
00413
00414 ReportStaticError(CAsyncSocket_Class,"SocketMessageHandler","Received loose message!");
00415
00416
00417 bIgnore=TRUE;
00418 }
00419 else
00420 bIgnore=FALSE;
00421
00422
00423 try
00424 {
00425 if (pSocket &&
00426 !bIgnore)
00427
00428 switch (uMsg)
00429 {
00430 case WM_SOCKET_FORCED:
00431 return pSocket->OnSocketReceive(0);
00432 break;
00433 case WM_SOCKET_GENERAL:
00434 if (WSAGETSELECTEVENT(lParam)==FD_READ)
00435 return pSocket->SocketReceive(WSAGETSELECTERROR(lParam));
00436 else if (WSAGETSELECTEVENT(lParam)==FD_WRITE)
00437 return pSocket->SocketWrite(WSAGETSELECTERROR(lParam));
00438 else if (WSAGETSELECTEVENT(lParam)==FD_OOB)
00439 return pSocket->OnSocketOOB(WSAGETSELECTERROR(lParam));
00440 else if (WSAGETSELECTEVENT(lParam)==FD_CLOSE)
00441 return pSocket->SocketClosed(WSAGETSELECTERROR(lParam));
00442 break;
00443 case WM_SOCKET_CONNECT:
00444 if (WSAGETSELECTEVENT(lParam)==FD_CONNECT)
00445 return pSocket->SocketConnected(WSAGETSELECTERROR(lParam));
00446 break;
00447 case WM_SOCKET_ACCEPT:
00448 if (WSAGETSELECTEVENT(lParam)==FD_ACCEPT)
00449 return pSocket->SocketAccept(WSAGETSELECTERROR(lParam));
00450 break;
00451 case WM_TIMER:
00452
00453 if (pSocket->HasTimeout())
00454
00455 return pSocket->OnSocketTimeout();
00456 else
00457 return FALSE;
00458 case WM_SOCKET_DELETE:
00459
00460 pSocket->OnSocketDelete((CGenericEvent*)lParam);
00461
00462
00463 return TRUE;
00464 default:
00465 return (int)(DefWindowProc(hwnd,
00466 uMsg,
00467 wParam,
00468 lParam));
00469 }
00470 else
00471 return (int)(DefWindowProc(hwnd,
00472 uMsg,
00473 wParam,
00474 lParam));
00475 }
00476 ERROR_HANDLER_STATIC(CSocketThreadManagerImp_Class,"SocketMessageHandler - Proc")
00477
00478
00479 return TRUE;
00480 }
00481 ERROR_HANDLER_STATIC_RETURN(CSocketThreadManagerImp_Class,"SocketMessageHandler",TRUE)
00482 }
00483
00484 KOMODIA_NAMESPACE_END