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
00037
00038
00039
00040
00041 #include "jaus/core/transport/transportmanager.h"
00042 #include "jaus/core/transport/judp.h"
00043 #include <iomanip>
00044 #include <iostream>
00045 #include <tinyxml/tinyxml.h>
00046
00047 using namespace JAUS;
00048
00049
00055 TransportManager::TransportManager()
00056 {
00057 mDebugMessagesFlag = false;
00058 mUseTcpFlag = true;
00059 mDisconnectTimeMs = 3600000;
00060 mDelayTimeMs = 0;
00061 mMulticastIP.SetAddress("239.255.0.1");
00062 mTimeToLive = 16;
00063 mUseBroadcastingFlag = false;
00064 mDebugMessagesMutex.Create("JAUS");
00065 }
00066
00067
00073 TransportManager::~TransportManager()
00074 {
00075 Shutdown();
00076 }
00077
00078
00089 bool TransportManager::LoadSettings(const std::string& filename)
00090 {
00091 TiXmlDocument xml;
00092
00093 if(xml.LoadFile(filename.c_str()) == false)
00094 {
00095 return false;
00096 }
00097 TiXmlHandle doc(&xml);
00098
00099 TiXmlElement* element = doc.FirstChild("JAUS").FirstChild("Transport").ToElement();
00100 if(element && element->Attribute("type"))
00101 {
00102 if(std::string(element->Attribute("type")) == "JUDP")
00103 {
00104 mUseTcpFlag = false;
00105 }
00106 else
00107 {
00108 mUseTcpFlag = true;
00109 }
00110 }
00111 TiXmlNode* node;
00112
00113 node = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("BroadcastIP").FirstChild().ToNode();
00114 if(node && node->Value())
00115 {
00116 mUseBroadcastingFlag = true;
00117 }
00118 node = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("UseBroadcasting").FirstChild().ToNode();
00119 if(node && node->Value())
00120 {
00121 mUseBroadcastingFlag = atoi(node->Value()) > 0 ? true : false;
00122 }
00123 node = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("MulticastIP").FirstChild().ToNode();
00124 if(node && node->Value())
00125 {
00126 mMulticastIP.SetAddress(node->Value());
00127 }
00128 node = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("TTL").FirstChild().ToNode();
00129 if(node && node->Value())
00130 {
00131 mTimeToLive = (unsigned char )atoi(node->Value());
00132 }
00133 node = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("NetAddress").FirstChild().ToNode();
00134 if(node && node->Value())
00135 {
00136 mHostIP.SetAddress(node->Value());
00137 }
00138 node = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("MaxPacketSizeBytes").FirstChild().ToNode();
00139 if(node && node->Value())
00140 {
00141 mMaxPayloadSize = (unsigned int)atoi(node->Value());
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 node = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("DisconnectTimeMs").FirstChild().ToNode();
00153 if(node && node->Value() && atoi(node->Value()) >= 0)
00154 {
00155 mDisconnectTimeMs = (unsigned int)(atoi(node->Value()));
00156 }
00157 element = doc.FirstChild("JAUS").FirstChild("Transport").FirstChild("Connection").ToElement();
00158 while(element)
00159 {
00160 if(element->Attribute("ip") && element->Attribute("id"))
00161 {
00162 IP4Address ip = element->Attribute("ip");
00163 Address id = Address::FromString(element->Attribute("id"));
00164 mPermanentConnections[id] = ip;
00165 }
00166 element = element->NextSiblingElement("Connection");
00167 }
00168 return true;
00169 }
00170
00171
00179 bool TransportManager::Initialize()
00180 {
00181 bool result = false;
00182
00183 Shutdown();
00184
00185 IP4Address::List hostnames;
00186 IP4Address::List::iterator eth0;
00187 CxUtils::Socket::GetHostAddresses(hostnames);
00188 if(hostnames.size() == 0)
00189 {
00190 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00191 std::cout << "\nTransportManager: No Network Interface Found.\n";
00192 }
00193
00194
00195 for(eth0 = hostnames.begin();
00196 eth0 != hostnames.end();
00197 eth0++)
00198 {
00199
00200 if(mHostIP.mString == "0.0.0.0" ||
00201 mHostIP.mString == "127.0.0.1" ||
00202 mHostIP.mString.empty() ||
00203 mHostIP == *eth0)
00204 {
00205 mListenSocket.SetNetworkInterface(mHostIP);
00206 mUdpSocket.SetNetworkInterface(mHostIP);
00207 if(mListenSocket.InitializeSocket(JTCP::Port,
00208 255,
00209 0,
00210 500,
00211 1)
00212 &&
00213 mUdpSocket.InitializeMulticastSocket(mMulticastIP,
00214 JTCP::Port,
00215 mTimeToLive,
00216 mUseBroadcastingFlag,
00217 JTCP::Port,
00218 false))
00219 {
00220
00221
00222 mTcpListenThread.CreateThread(TransportManager::TcpListenThread, this);
00223 mTcpListenThread.SetThreadName("JTCP-Listen");
00224 mUdpReceiveThread.CreateThread(TransportManager::UdpReceiveThread, this);
00225 mUdpReceiveThread.SetThreadName("JUDP-RCV");
00226 mUdpReceiveThread.SetThreadPriority(25);
00227 result = true;
00228
00229 CxUtils::SleepMs(100);
00230 }
00231
00232 break;
00233 }
00234 }
00235
00236 if(result == false)
00237 {
00238 Shutdown();
00239 }
00240
00241 return result;
00242 }
00243
00244
00250 void TransportManager::Shutdown()
00251 {
00252 mListenSocket.Shutdown();
00253 mUdpSocket.Shutdown();
00254 mTcpListenThread.StopThread();
00255 mUdpReceiveThread.StopThread();
00256
00257 {
00258 Mutex::ScopedLock lock(&mUdpMutex);
00259
00260 std::map<Address, CxUtils::UdpClient*>::iterator udp;
00261 for(udp = mUdpConnections.begin();
00262 udp != mUdpConnections.end();
00263 udp++)
00264 {
00265 udp->second->Shutdown();
00266 }
00267
00268 for(udp = mUdpConnections.begin();
00269 udp != mUdpConnections.end();
00270 udp++)
00271 {
00272 delete udp->second;
00273 }
00274 }
00275 {
00276 Mutex::ScopedLock lock(&mTcpMutex);
00277 std::map<Address, JTCP*>::iterator tcp;
00278 for(tcp = mTcpConnections.begin();
00279 tcp != mTcpConnections.end();
00280 tcp++)
00281 {
00282 delete tcp->second;
00283 }
00284 std::vector<JTCP*>::iterator unknown;
00285 for(unknown = mUnknownConnections.begin();
00286 unknown != mUnknownConnections.end();
00287 unknown++)
00288 {
00289 delete *unknown;
00290 }
00291 }
00292
00293 mTcpConnections.clear();
00294 mUnknownConnections.clear();
00295 mUdpConnections.clear();
00296 }
00297
00298
00307 void TransportManager::CheckServiceStatus(const unsigned int timeSinceLastCheckMs)
00308 {
00309 if(mTcpListenThread.IsThreadActive() == false ||
00310 mUdpReceiveThread.IsThreadActive() == false)
00311 {
00312 return;
00313 }
00314
00315 {
00316 Mutex::ScopedLock connectionsLock(&mTcpMutex);
00317
00318 std::vector<JTCP*>::iterator u = mUnknownConnections.begin();
00319 while(u != mUnknownConnections.end())
00320 {
00321 if((*u)->GetLastSourceID().IsValid())
00322 {
00323
00324 std::map<Address, JTCP*>::iterator i;
00325 i = mTcpConnections.find((*u)->GetLastSourceID());
00326 if(i == mTcpConnections.end())
00327 {
00328 mTcpConnections[(*u)->GetLastSourceID()] = (*u);
00329 }
00330 else
00331 {
00332
00333 Time::Stamp updateTimeMs = (*u)->GetUpdateTime().ToMs();
00334 if(Time::GetUtcTimeMs() - updateTimeMs > mDelayTimeMs)
00335 {
00336
00337 if(mDebugMessagesFlag)
00338 {
00339 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00340 std::cout << "\nTransportManager: Dropping conflicting connection [" << i->first.ToString() << "]\n";
00341 }
00342 delete i->second;
00343 i->second = (*u);
00344 }
00345 }
00346 if(mDebugMessagesFlag)
00347 {
00348 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00349 std::cout << "\nTransportManager: Identified connection [" << (*u)->GetLastSourceID().ToString() << "]\n";
00350 }
00351
00352 u = mUnknownConnections.erase(u);
00353 }
00354 else
00355 {
00356 u++;
00357 }
00358 }
00359
00360
00361 std::map<Address, JTCP*>::iterator tcp = mTcpConnections.begin();
00362 while(tcp != mTcpConnections.end())
00363 {
00364 if(tcp->second->GetSocket()->IsValid() == false)
00365 {
00366 if(mDebugMessagesFlag)
00367 {
00368 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00369 std::cout << "\nTransportManager: Dropping JTCP Connection [" << tcp->first.ToString() << "]\n";
00370 }
00371 delete tcp->second;
00372 mTcpConnections.erase(tcp);
00373 tcp = mTcpConnections.begin();
00374 }
00375 else
00376 {
00377 tcp++;
00378 }
00379 }
00380 }
00381
00382 static Time::Stamp prevCheckTime = 0;
00383 if(Time::GetUtcTimeMs() - prevCheckTime <= 1000)
00384 {
00385 return;
00386 }
00387
00388 {
00389 Mutex::ScopedLock updLock(&mUdpMutex);
00390 std::map<Address, bool>::iterator perm;
00391 std::map<Address, Time::Stamp>::iterator utime;
00392
00393 utime = mUpdateTimes.begin();
00394 while(utime != mUpdateTimes.end() && mDisconnectTimeMs > 0)
00395 {
00396 if(mPermanentConnections.find(utime->first) != mPermanentConnections.end())
00397 {
00398 utime++;
00399 continue;
00400 }
00401 Time::Stamp diff = Time::GetUtcTimeMs() - utime->second;
00402 if(diff >= mDisconnectTimeMs)
00403 {
00404 if(mDebugMessagesFlag)
00405 {
00406 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00407 std::cout << "\nTransportManager: Connection Timeout to " << utime->first.ToString() << "\n";
00408 }
00409 std::map<Address, CxUtils::UdpClient*>::iterator judp;
00410 judp = mUdpConnections.find(utime->first);
00411 if(judp != mUdpConnections.end())
00412 {
00413 delete judp->second;
00414 mUdpConnections.erase(judp);
00415 }
00416 mUpdateTimes.erase(utime);
00417 utime = mUpdateTimes.begin();
00418 }
00419 else
00420 {
00421 utime++;
00422 }
00423 }
00424 }
00425
00426
00427 std::map<Address, IP4Address>::iterator p;
00428 for(p = mPermanentConnections.begin();
00429 p != mPermanentConnections.end();
00430 p++)
00431 {
00432 std::map<Address, JTCP*>::iterator tcp;
00433 std::map<Address, CxUtils::UdpClient*>::iterator udp;
00434
00435 {
00436 Mutex::ScopedLock tcpLock(&mTcpMutex);
00437
00438 tcp = mTcpConnections.find(p->first);
00439 if(tcp != mTcpConnections.end())
00440 {
00441 continue;
00442 }
00443 }
00444 {
00445 Mutex::ScopedLock udpLock(&mUdpMutex);
00446
00447 udp = mUdpConnections.find(p->first);
00448 if(udp != mUdpConnections.end())
00449 {
00450 continue;
00451 }
00452 }
00453
00454 if(mUseTcpFlag)
00455 {
00456 CxUtils::TcpClient* sock = new CxUtils::TcpClient();
00457 if(sock->InitializeSocket(p->second, JTCP::Port))
00458 {
00459 JTCP* jtcp = new JTCP();
00460 jtcp->Initialize(this, sock);
00461 Mutex::ScopedLock tcpLock(&mTcpMutex);
00462 mTcpConnections[p->first] = jtcp;
00463 continue;
00464 }
00465 delete sock;
00466 }
00467
00468 {
00469 Mutex::ScopedLock udpLock(&mUdpMutex);
00470 CxUtils::UdpClient* sock = mUdpSocket.CreateNewDestination(p->second, JUDP::Port);
00471 if(sock)
00472 {
00473 mUdpConnections[p->first] = sock;
00474 mUpdateTimes[p->first] = Time::GetUtcTimeMs();
00475 }
00476 }
00477 }
00478
00479
00480 prevCheckTime = Time::GetUtcTimeMs();
00481 }
00482
00483
00497 void TransportManager::ProcessPacket(Packet& packet,
00498 Header& header,
00499 const IP4Address& ipAddress,
00500 const unsigned short sourcePort,
00501 const int transport)
00502 {
00503
00504 if(header.mDestinationID.IsBroadcast())
00505 {
00506 bool fromLocalHost = false;
00507 if(CxUtils::Socket::IsHostAddress(ipAddress))
00508 {
00509 fromLocalHost = true;
00510 }
00511
00512 if(transport != TransportManager::UDP &&
00513 header.mBroadcastFlag != Header::Broadcast::None &&
00514 fromLocalHost)
00515 {
00516 mUdpSocket.Send(packet);
00517 }
00518
00519 {
00520 Mutex::ScopedLock lock(&mTcpMutex);
00521 std::map<Address, JTCP*>::iterator tcp;
00522 for(tcp = mTcpConnections.begin();
00523 tcp != mTcpConnections.end();
00524 tcp++)
00525 {
00526 if(Address::DestinationMatch(header.mDestinationID, tcp->first) &&
00527 tcp->first != header.mSourceID)
00528 {
00529 if(header.mBroadcastFlag != Header::Broadcast::None)
00530 {
00531
00532
00533 if(tcp->second->IsLocalConnection())
00534 {
00535 tcp->second->GetSocket()->Send(packet);
00536 }
00537 }
00538
00539
00540 else if( (tcp->second->IsLocalConnection() == false && fromLocalHost) ||
00541 (tcp->second->IsLocalConnection() ) )
00542 {
00543 tcp->second->GetSocket()->Send(packet);
00544 }
00545 }
00546 }
00547 }
00548
00549 {
00550 Mutex::ScopedLock lock(&mUdpMutex);
00551 std::map<Address, CxUtils::UdpClient*>::iterator udp;
00552 for(udp = mUdpConnections.begin();
00553 udp != mUdpConnections.end() && header.mBroadcastFlag == Header::Broadcast::None;
00554 udp++)
00555 {
00556 if(Address::DestinationMatch(header.mDestinationID, udp->first) &&
00557 udp->first != header.mSourceID)
00558 {
00559 udp->second->Send(packet);
00560 }
00561 }
00562 }
00563 }
00564 else
00565 {
00566 {
00567 Mutex::ScopedLock lock(&mTcpMutex);
00568 std::map<Address, JTCP*>::iterator tcp = mTcpConnections.find(header.mDestinationID);
00569 if(tcp != mTcpConnections.end())
00570 {
00571 if(tcp->second->GetSocket()->Send(packet) == 0)
00572 {
00573 if(mDebugMessagesFlag)
00574 {
00575 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00576 std::cout << "\nTransportManager: ERROR Sending Over TCP - [SRC:" << header.mSourceID.ToString() << ", DST:" << header.mDestinationID.ToString() << "] Size: " << header.mSize << "\n";
00577 std::cout << "\nTransportManager: Dropping JTCP Connection [" << tcp->first.ToString() << "]\n";
00578 }
00579 delete tcp->second;
00580 mTcpConnections.erase(tcp);
00581 }
00582 return;
00583 }
00584 }
00585 {
00586 Mutex::ScopedLock lock(&mUdpMutex);
00587 std::map<Address, CxUtils::UdpClient*>::iterator udp = mUdpConnections.find(header.mDestinationID);
00588 if(udp != mUdpConnections.end())
00589 {
00590 if(udp->second->Send(packet) == 0)
00591 {
00592 if(mDebugMessagesFlag)
00593 {
00594 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00595 std::cout << "\nTransportManager: ERROR Sending Over JUDP - [SRC:" << header.mSourceID.ToString() << ", DST:" << header.mDestinationID.ToString() << "] Size: " << header.mSize << "\n";
00596 }
00597 }
00598 return;
00599 }
00600 }
00601 if(mDebugMessagesFlag)
00602 {
00603 Mutex::ScopedLock lock(&mDebugMessagesMutex);
00604 std::cout << "\nTransportManager: Unknown Destination - [SRC:" << header.mSourceID.ToString() << ", DST:" << header.mDestinationID.ToString() << "] Size: " << header.mSize << "\n";
00605 }
00606 }
00607 }
00608
00609
00624 bool TransportManager::AddConnection(const IP4Address& networkIP,
00625 const Address& jausID)
00626 {
00627 if(IsInitialized() == false && jausID.IsValid())
00628 {
00629 mPermanentConnections[jausID] = networkIP;
00630 return true;
00631 }
00632 return false;
00633 }
00634
00635
00641 unsigned int TransportManager::GetNumLocalClients() const
00642 {
00643 std::map<Address, JTCP*>::const_iterator c;
00644 Mutex::ScopedLock tcpLock(&mTcpMutex);
00645 unsigned int count = 0;
00646 for(c = mTcpConnections.begin();
00647 c != mTcpConnections.end();
00648 c++)
00649 {
00650 CxUtils::TcpServer* server = dynamic_cast<CxUtils::TcpServer*>(c->second->GetSocket());
00651 if(server)
00652 {
00653 if(CxUtils::Socket::IsHostAddress(server->GetClientAddress()))
00654 {
00655 count++;
00656 }
00657 }
00658 }
00659 return count;
00660 }
00661
00667 void TransportManager::TcpListenThread(void* args)
00668 {
00669 TransportManager* manager = (TransportManager*)args;
00670 CxUtils::TcpServer* sock = NULL;
00671 while(manager && manager->mTcpListenThread.QuitThreadFlag() == false)
00672 {
00673 sock = NULL;
00674
00675
00676 sock = manager->mListenSocket.AwaitConnection();
00677
00678 if(sock)
00679 {
00680
00681 JTCP* tcp = new JTCP();
00682 tcp->SetPacketPollingDelayMs(manager->mDelayTimeMs);
00683 if(tcp->Initialize(manager, sock))
00684 {
00685 if(manager->mDebugMessagesFlag)
00686 {
00687 Mutex::ScopedLock lock(&manager->mDebugMessagesMutex);
00688 std::cout << "\nTransportManager: New incomming JTCP connection made.\n";
00689 }
00690 {
00691 Mutex::ScopedLock lock(&manager->mTcpMutex);
00692
00693
00694
00695 manager->mUnknownConnections.push_back(tcp);
00696 }
00697
00698 manager->CheckServiceStatus(0);
00699 }
00700 else
00701 {
00702 delete tcp;
00703 tcp = NULL;
00704 }
00705 }
00706 CxUtils::SleepMs(1);
00707 }
00708
00709 if(sock)
00710 {
00711 delete sock;
00712 }
00713 }
00714
00715
00721 void TransportManager::UdpReceiveThread(void* args)
00722 {
00723 TransportManager* manager = (TransportManager*)args;
00724 Packet udpMessage;
00725 CxUtils::IP4Address sourceAddress;
00726 unsigned short sourcePort = 0;
00727 long int timeoutMs = 100;
00728
00729 #ifdef WIN32
00730 int loopCounter = 0;
00731 #endif
00732
00733 udpMessage.Reserve(5000);
00734
00735 while(manager && manager->mUdpReceiveThread.QuitThreadFlag() == false)
00736 {
00737 udpMessage.Clear(false);
00738 sourcePort = 0;
00739
00740 if(manager->mUdpSocket.Recv(udpMessage,
00741 5000,
00742 timeoutMs,
00743 &sourceAddress,
00744 &sourcePort) > 0)
00745 {
00746
00747
00748 if(CxUtils::Socket::IsHostAddress(sourceAddress) == false &&
00749 udpMessage.Length() > Header::MinSize + BYTE_SIZE && *udpMessage.Ptr() == JUDP::Version)
00750 {
00751
00752 Packet::Wrapper stripped((unsigned char *)(udpMessage.Ptr() + 1), udpMessage.Length() - 1);
00753 Header header;
00754 stripped->SetReadPos(0);
00755 std::string errorMessage;
00756 if(header.Read(*stripped.GetData()) && header.IsValid(&errorMessage))
00757 {
00758
00759 {
00760 bool createConnection = false;
00761 {
00762 {
00763 Mutex::ScopedLock udpLock(&manager->mUdpMutex);
00764 manager->mUpdateTimes[header.mSourceID] = Time::GetUtcTimeMs();
00765 std::map<Address, CxUtils::UdpClient*>::iterator udp;
00766 udp = manager->mUdpConnections.find(header.mSourceID);
00767 if(udp == manager->mUdpConnections.end())
00768 {
00769 createConnection = true;
00770 }
00771 else if(udp->second->GetDestinationPort() != sourcePort ||
00772 udp->second->GetConnectionAddress() != sourceAddress)
00773 {
00774
00775 Mutex::ScopedLock lock(&manager->mDebugMessagesMutex);
00776 std::cout << "=============================================================\n";
00777 std::cout << "=============================================================\n";
00778 std::cout << "=============================================================\n";
00779 std::cout << "=============================================================\n";
00780 std::cout << "JAUS ID DUPLICATED BY " << sourceAddress.mString << std::endl;
00781 std::cout << "=============================================================\n";
00782 std::cout << "=============================================================\n";
00783 std::cout << "=============================================================\n";
00784 std::cout << "=============================================================\n";
00785
00786
00787 createConnection = true;
00788 delete udp->second;
00789 manager->mUdpConnections.erase(udp);
00790 }
00791 }
00792 if(createConnection)
00793 {
00794 Mutex::ScopedLock tcpLock(&manager->mTcpMutex);
00795 std::map<Address, JTCP*>::iterator tcp;
00796 tcp = manager->mTcpConnections.find(header.mSourceID);
00797 if(tcp != manager->mTcpConnections.end())
00798 {
00799 createConnection = false;
00800 }
00801 if(manager->mUnknownConnections.size() > 0)
00802 {
00803 createConnection = false;
00804 }
00805 }
00806 }
00807 if(createConnection)
00808 {
00809
00810
00811 if(manager->mUseTcpFlag)
00812 {
00813 Mutex::ScopedLock tcpLock(&manager->mTcpMutex);
00814 std::map<Address, JTCP*>::iterator tcp;
00815 tcp = manager->mTcpConnections.find(header.mSourceID);
00816 if(tcp == manager->mTcpConnections.end())
00817 {
00818 CxUtils::TcpClient* sock = new CxUtils::TcpClient();
00819 if(sock->InitializeSocket(sourceAddress, sourcePort))
00820 {
00821 JTCP* jtcp = new JTCP();
00822 jtcp->Initialize(manager, sock);
00823 manager->mTcpConnections[header.mSourceID] = jtcp;
00824 createConnection = false;
00825 }
00826 else
00827 {
00828 delete sock;
00829 sock = NULL;
00830 }
00831 }
00832 else
00833 {
00834
00835 createConnection = false;
00836 }
00837 }
00838 if(createConnection == true)
00839 {
00840
00841 Mutex::ScopedLock udpLock(&manager->mUdpMutex);
00842 CxUtils::UdpClient* sock = manager->mUdpSocket.CreateNewDestination(sourceAddress, sourcePort);
00843 if(sock)
00844 {
00845 manager->mUdpConnections[header.mSourceID] = sock;
00846 }
00847 }
00848 }
00849 }
00850 manager->ProcessPacket(udpMessage, header, sourceAddress, sourcePort, TransportManager::UDP);
00851 }
00852 }
00853 }
00854
00855 if(manager->mDelayTimeMs == 0)
00856 {
00857 #ifdef WIN32
00858
00859 if( loopCounter++ == 250)
00860 {
00861 loopCounter = 0;
00862 CxUtils::SleepMs(1);
00863 }
00864 #else
00865 usleep(500);
00866 #endif
00867 }
00868 else
00869 {
00870 CxUtils::SleepMs(manager->mDelayTimeMs);
00871 }
00872 }
00873 }
00874
00875