00001 /* 00002 Copyright 2007 Erez Bibi (erezbibi@users.sourceforge.net) 00003 This file is part of Beesnest. 00004 00005 Beesnest is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 Beesnest is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Beesnest; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00020 #include "DcLoadController.h" 00021 00022 #include "DcBuffer.h" 00023 00024 int CdcLoadController::nThreadsLimit = 10; 00025 int CdcLoadController::nClientThreadLimit = 5; 00026 int CdcLoadController::nOverloadSleep = 0; 00027 int CdcLoadController::nNoOfThreads = 0; 00028 CdcLoadController::t_clients_map CdcLoadController::mClients; 00029 CdcMutex CdcLoadController::oMutex; 00030 00031 00032 void CdcLoadController::Init () 00033 { 00034 CdcString temp = CdcParameters::GetParam ("Server->Total-Threads-Limit"); 00035 if (temp.IsEmpty () == false) 00036 nThreadsLimit = CdcParameters::ToInt (temp); 00037 00038 temp = CdcParameters::GetParam ("Server->Client-Threads-Limit"); 00039 if (temp.IsEmpty () == false) 00040 nClientThreadLimit = CdcParameters::ToInt (temp); 00041 00042 temp = CdcParameters::GetParam ("Server->Overload-Sleep"); 00043 if (temp.IsEmpty () == false) 00044 nOverloadSleep = CdcParameters::ToInt (temp); 00045 } 00046 00047 00048 bool CdcLoadController::AddThread (CdcSocket* psock) 00049 { 00050 oMutex.Lock (); 00051 00052 if (nNoOfThreads == nThreadsLimit) 00053 { 00054 try { psock->Write (OVRLOAD_MSG, OVRLOAD_MSG_LEN); } 00055 catch (CdcException& e) {} 00056 PrintString ("Total Thread Limit", PS_SEC); 00057 delete psock; 00058 oMutex.Unlock (); 00059 Sleep (nOverloadSleep); /* Give the server a chance to get stuff done. */ 00060 return false; 00061 } 00062 00063 CdcString& ip = psock->GetClientAddress (); 00064 CdcLoadController::t_clients_map::iterator itr = mClients.find (ip); 00065 if (itr == mClients.end ()) 00066 mClients [ip] = 1; 00067 else 00068 { 00069 if ((*itr).second == nClientThreadLimit) 00070 { 00071 try { psock->Write (OVRLOAD_MSG, OVRLOAD_MSG_LEN); } 00072 catch (CdcException& e) {} 00073 PrintString (ip + " - Thread Limit", PS_SEC); 00074 delete psock; 00075 oMutex.Unlock (); 00076 return false; 00077 } 00078 ++((*itr).second); 00079 } 00080 ++(nNoOfThreads); 00081 00082 oMutex.Unlock (); 00083 return true; 00084 } 00085 00086 00087 void CdcLoadController::ThreadDone (CdcSocket* psock) 00088 { 00089 oMutex.Lock (); 00090 CdcLoadController::t_clients_map::iterator itr = mClients.find 00091 (psock->GetClientAddress ()); 00092 if (itr != mClients.end ()) --((*itr).second); 00093 --nNoOfThreads; 00094 00095 if (nNoOfThreads == 0) 00096 mClients.clear (); 00097 00098 oMutex.Unlock (); 00099 }