Go to the documentation of this file.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
00042 #include "cxutils/ipc/mappedmessagebox.h"
00043 #include "cxutils/time.h"
00044 #include <stdio.h>
00045 #include <string.h>
00046 #include <assert.h>
00047 #include <limits.h>
00048 #include <iostream>
00049 #include <sstream>
00050
00051 using namespace std;
00052 using namespace CxUtils;
00053
00059 MappedMessageBox::Header::Header() : mWriteTimeMs(0),
00060 mReadTimeMs(0),
00061 mCount(0),
00062 mStartBytePos(Header::Size),
00063 mEndBytePos(Header::Size)
00064 {
00065
00066 }
00067
00068
00074 MappedMessageBox::Header::Header(const MappedMessageBox::Header& header) : mWriteTimeMs(0),
00075 mReadTimeMs(0),
00076 mCount(0),
00077 mStartBytePos(Header::Size),
00078 mEndBytePos(Header::Size)
00079 {
00080 *this = header;
00081 }
00082
00083
00089 MappedMessageBox::Header::~Header()
00090 {
00091 }
00092
00093
00099 MappedMessageBox::Header& MappedMessageBox::Header::operator =(const MappedMessageBox::Header& header)
00100 {
00101 if(this != &header)
00102 {
00103 mWriteTimeMs = header.mWriteTimeMs;
00104 mReadTimeMs = header.mReadTimeMs;
00105 mCount = header.mCount;
00106 mStartBytePos = header.mStartBytePos;
00107 mEndBytePos = header.mEndBytePos;
00108 }
00109 return *this;
00110 }
00111
00112
00118 MappedMessageBox::MappedMessageBox() : mMessagesRead(0)
00119 {
00120 }
00121
00122
00128 MappedMessageBox::~MappedMessageBox()
00129 {
00130 CloseMessageBox();
00131 }
00132
00133
00144 bool MappedMessageBox::OpenMessageBox(const ID id)
00145 {
00146 bool result = false;
00147
00148 CloseMessageBox();
00149
00150 if(mMessageBox.OpenMappedMemory(id) && mMessageBox.Length() > Header::Size)
00151 {
00152 result = true;
00153 }
00154
00155 if(result == false)
00156 {
00157 CloseMessageBox();
00158 }
00159
00160 return result;
00161 }
00162
00176 bool MappedMessageBox::OpenMessageBox(const std::string& name)
00177 {
00178 bool result = false;
00179
00180 CloseMessageBox();
00181
00182 if(mMessageBox.OpenMappedMemory(name) && mMessageBox.Length() > Header::Size)
00183 {
00184 result = true;
00185 }
00186
00187 if(result == false)
00188 {
00189 CloseMessageBox();
00190 }
00191
00192 return result;
00193 }
00194
00195
00209 bool MappedMessageBox::CreateMessageBox(const ID id,
00210 const unsigned int size)
00211 {
00212 std::ostringstream input;
00213 input << id;
00214 return CreateMessageBox(input.str(), size);
00215 }
00216
00217
00234 bool MappedMessageBox::CreateMessageBox(const std::string& name,
00235 const unsigned int size)
00236 {
00237 bool result = false;
00238 Header header;
00239
00240 CloseMessageBox();
00241
00242 if(mMessageBox.CreateMappedMemory(name, size + Header::Size))
00243 {
00244 result = true;
00245 mMessageBox.Lock();
00246 header.mStartBytePos = Header::Size;
00247 header.mEndBytePos = Header::Size;
00248 header.mWriteTimeMs = GetTimeMs();
00249 header.mReadTimeMs = GetTimeMs();
00250 WriteHeader(header);
00251 mMessageBox.Unlock();
00252 }
00253 else if(mMessageBox.OpenMappedMemory(name))
00254 {
00255
00256
00257
00258 mMessageBox.Lock();
00259 header = ReadHeader();
00260 if(mMessageBox.Length() < size + Header::Size)
00261 {
00262 if(GetTimeMs() - header.mWriteTimeMs > DefaultTimeOut &&
00263 GetTimeMs() - header.mReadTimeMs > DefaultTimeOut)
00264 {
00265 mMessageBox.Unlock();
00266 mMessageBox.CloseMappedMemory();
00267 MappedMemory::DeleteMappedMemory(name);
00268 CxUtils::SleepMs(DefaultTimeOut);
00269
00270 if(mMessageBox.CreateMappedMemory(name, size + Header::Size))
00271 {
00272 result = true;
00273 mMessageBox.Lock();
00274 header.mStartBytePos = Header::Size;
00275 header.mEndBytePos = Header::Size;
00276 header.mWriteTimeMs = GetTimeMs();
00277 header.mReadTimeMs = GetTimeMs();
00278 WriteHeader(header);
00279 mMessageBox.Unlock();
00280 }
00281 }
00282 }
00283 else
00284 {
00285 Time::Stamp currentTimeMs = GetTimeMs();
00286 #ifndef WIN32 // LINUX
00287
00288
00289 if(header.mWriteTimeMs > currentTimeMs && header.mWriteTimeMs - currentTimeMs >= DefaultTimeOut)
00290 {
00291 result = false;
00292 }
00293 #endif
00294 if(currentTimeMs > header.mWriteTimeMs && currentTimeMs - header.mWriteTimeMs >= DefaultTimeOut)
00295 {
00296 result = true;
00297 }
00298 }
00299 if(result)
00300 {
00301 header.mWriteTimeMs = GetTimeMs();
00302 WriteHeader(header);
00303 }
00304 mMessageBox.Unlock();
00305 }
00306
00307
00308 if(result == false)
00309 {
00310 CloseMessageBox();
00311 }
00312
00313 return result;
00314 }
00315
00316
00323 void MappedMessageBox::CloseMessageBox()
00324 {
00325 mMessageBox.CloseMappedMemory();
00326 mMessagesRead = 0;
00327 }
00328
00329
00335 bool MappedMessageBox::IsOpen() const
00336 {
00337 if(mMessageBox.IsOpen())
00338 {
00339 return true;
00340 }
00341 return false;
00342 }
00343
00344
00353 bool MappedMessageBox::IsEmpty() const
00354 {
00355 if(mMessageBox.IsOpen())
00356 {
00357 Header header;
00358 mMessageBox.Lock();
00359 header = ReadHeader();
00360 mMessageBox.Unlock();
00361
00362 if(header.mCount == 0)
00363 {
00364 return true;
00365 }
00366 }
00367
00368 return false;
00369 }
00370
00371
00387 bool MappedMessageBox::IsActive(const bool readTimeFlag, const unsigned int thresholdMilliseconds) const
00388 {
00389 if(mMessageBox.IsOpen())
00390 {
00391 Header header;
00392 Time::Stamp timeMs = 0;
00393 mMessageBox.Lock();
00394 header = ReadHeader();
00395 mMessageBox.Unlock();
00396 Time::Stamp currentTimeMs = GetTimeMs();
00397 timeMs = readTimeFlag ? header.mReadTimeMs : header.mWriteTimeMs;
00398 #ifndef WIN32 // LINUX
00399
00400
00401 if(timeMs >= currentTimeMs && timeMs - currentTimeMs >= thresholdMilliseconds)
00402 {
00403 return false;
00404 }
00405 #endif
00406 if(currentTimeMs >= timeMs && currentTimeMs - timeMs <= thresholdMilliseconds)
00407 {
00408 return true;
00409 }
00410 }
00411
00412 return false;
00413 }
00414
00415
00426 bool MappedMessageBox::Touch()
00427 {
00428 if(mMessageBox.IsOpen())
00429 {
00430 Header header;
00431 mMessageBox.Lock();
00432 header = ReadHeader();
00433 header.mWriteTimeMs = GetTimeMs();
00434 WriteHeader(header);
00435 mMessageBox.Unlock();
00436
00437 return true;
00438 }
00439
00440 return false;
00441 }
00442
00443
00456 bool MappedMessageBox::WriteMessage(const Packet& message)
00457 {
00458 bool result = false;
00459 if(mMessageBox.IsOpen())
00460 {
00461 Header header;
00462 mMessageBox.Lock();
00463 header = ReadHeader();
00464
00465 unsigned int availableBytes = mMessageBox.Length() - Header::Size;
00466 unsigned int messageSize = message.Length() + MessageHeaderSize;
00467 if(messageSize < availableBytes)
00468 {
00469
00470
00471 if(messageSize + header.mEndBytePos >= mMessageBox.Length() && header.mStartBytePos > Header::Size)
00472 {
00473 unsigned int dataSize = header.mEndBytePos - header.mStartBytePos;
00474 memmove(mMessageBox->Ptr() + Header::Size,
00475 mMessageBox->Ptr() + header.mStartBytePos,
00476 dataSize);
00477 header.mEndBytePos = dataSize + Header::Size;
00478 header.mStartBytePos = Header::Size;
00479 }
00480
00481 if(messageSize + header.mEndBytePos < mMessageBox.Length() - 1)
00482 {
00483 mMessageBox->SetWritePos(header.mEndBytePos);
00484 if(mMessageBox->Write(((unsigned int)(message.Length()))) &&
00485 mMessageBox->Write(message))
00486 {
00487 result = true;
00488 header.mEndBytePos += message.Length() + MessageHeaderSize;
00489 header.mCount++;
00490 }
00491 }
00492 }
00493 header.mWriteTimeMs = GetTimeMs();
00494 WriteHeader(header);
00495 mMessageBox.Unlock();
00496 }
00497
00498 return result;
00499 }
00500
00501
00514 bool MappedMessageBox::WriteMessage(const std::string& message)
00515 {
00516 Packet::Wrapper wrapper((unsigned char *)message.c_str(), (unsigned int)message.size());
00517 return WriteMessage( *wrapper.GetData() );
00518 }
00519
00520
00521
00534 bool MappedMessageBox::ReadMessage(Packet& message) const
00535 {
00536 bool result = false;
00537 message.Clear();
00538 if(mMessageBox.IsOpen())
00539 {
00540 Header header;
00541 if(mMessageBox.Lock() == 0)
00542 {
00543 return result;
00544 }
00545 header = ReadHeader();
00546
00547 if(header.mCount > 0 && header.mStartBytePos < header.mEndBytePos)
00548 {
00549
00550 unsigned int messageSize = 0;
00551 unsigned int messagePosition = header.mStartBytePos;
00552
00553
00554 mMessageBox->Read(messageSize, messagePosition);
00555
00556 if(messageSize + MessageHeaderSize + messagePosition <= header.mEndBytePos)
00557 {
00558 if(mMessageBox->Read(message, messageSize, messagePosition + MessageHeaderSize) == (int)messageSize)
00559 {
00560 (*( (unsigned *)(&mMessagesRead) ))++;
00561
00562 header.mStartBytePos = messagePosition + MessageHeaderSize + messageSize;
00563
00564 header.mCount--;
00565 result = true;
00566 }
00567 }
00568 if(messageSize + MessageHeaderSize > mMessageBox->Length())
00569 {
00570 assert("Corrupted Shared Memory Message Box" && 0);
00571 }
00572 }
00573
00574 if(header.mCount == 0)
00575 {
00576 header.mStartBytePos = header.mEndBytePos = Header::Size;
00577 }
00578
00579 header.mReadTimeMs = GetTimeMs();
00580
00581 WriteHeader(header);
00582
00583 mMessageBox.Unlock();
00584 }
00585
00586 return result;
00587 }
00588
00589
00602 bool MappedMessageBox::ReadMessage(std::string& message) const
00603 {
00604 Packet pmessage;
00605 message.clear();
00606 if(ReadMessage(pmessage))
00607 {
00608 for(unsigned int i = 0; i < pmessage.Length(); i++)
00609 {
00610 message.push_back(pmessage.Ptr()[i]);
00611 }
00612 return true;
00613 }
00614 return false;
00615 }
00616
00617
00623 unsigned int MappedMessageBox::GetBufferSize() const
00624 {
00625 if(mMessageBox.IsOpen())
00626 {
00627 return mMessageBox.Length() - Header::Size;
00628 }
00629 return 0;
00630 }
00631
00632
00638 unsigned int MappedMessageBox::GetNumMessages() const
00639 {
00640 if(mMessageBox.IsOpen())
00641 {
00642 Header header;
00643 mMessageBox.Lock();
00644 header = ReadHeader();
00645 mMessageBox.Unlock();
00646 return header.mCount;
00647 }
00648 return 0;
00649 }
00650
00651
00659 MappedMessageBox::Header MappedMessageBox::ReadHeader() const
00660 {
00661 Header header;
00662 if(mMessageBox.GetData() == NULL)
00663 {
00664 return header;
00665 }
00666 mMessageBox->SetReadPos(0);
00667 if(mMessageBox->Length() < Header::Size)
00668 {
00669 return header;
00670 }
00671 mMessageBox->Read(header.mWriteTimeMs);
00672 mMessageBox->Read(header.mReadTimeMs);
00673 mMessageBox->Read(header.mCount);
00674 mMessageBox->Read(header.mStartBytePos);
00675 mMessageBox->Read(header.mEndBytePos);
00676 return header;
00677 }
00678
00679
00687 void MappedMessageBox::WriteHeader(const MappedMessageBox::Header& header) const
00688 {
00689 MappedMemory* memory = ((MappedMemory*)(&mMessageBox));
00690 if(memory->IsOpen() == false)
00691 {
00692 return;
00693 }
00694 (*memory)->SetWritePos(0);
00695 unsigned int totalWritten = 0;
00696 totalWritten += (*memory)->Write(header.mWriteTimeMs);
00697 totalWritten += (*memory)->Write(header.mReadTimeMs);
00698 totalWritten += (*memory)->Write(header.mCount);
00699 totalWritten += (*memory)->Write(header.mStartBytePos);
00700 totalWritten += (*memory)->Write(header.mEndBytePos);
00701 }
00702
00703
00704