///////////////////////////////////////////////////////////////////////// // MMFmgr.cpp - Provides management of shared memory for IPC // // // // Jim Fawcett, CSE775 - Distributed Objects, MT1-Q4, Spring 2009 // ///////////////////////////////////////////////////////////////////////// #include "MMFmgr.h" RWToggle::RWToggle(std::wstring name) : name_(name) { std::wstring temp = name + L"ReaderEvent"; hRead_ = CreateEvent(0,TRUE,TRUE,temp.c_str()); if(hRead_ == NULL) throw std::exception("\n\ncan't create read event\n\n"); temp = name + L"WriterEvent"; hWrite_ = CreateEvent(0,TRUE,FALSE,temp.c_str()); if(hWrite_ == NULL) throw std::exception("\n\ncan't create write event\n\n"); temp = name + L"WritersLock"; hWritersLock_ = CreateMutex(0,FALSE,name.c_str()); if(hWritersLock_ == NULL) throw std::exception("\n\ncan't create writers lock\n\n"); readReady = false; setWrite(); } RWToggle::~RWToggle() { CloseHandle(hRead_); CloseHandle(hWrite_); CloseHandle(hWritersLock_); } void RWToggle::setRead() { ResetEvent(hWrite_); SetEvent(hRead_); readReady = true; } void RWToggle::setWrite() { ResetEvent(hRead_); SetEvent(hWrite_); readReady = false; } void RWToggle::readWait() { WaitForSingleObject(hRead_,INFINITE); } void RWToggle::writeWait() { WaitForSingleObject(hWrite_,INFINITE); } void RWToggle::writerLock() { WaitForSingleObject(hWritersLock_,INFINITE); } void RWToggle::writerUnlock() { ReleaseMutex(hWritersLock_); } MMFmgr::MMFmgr(const std::wstring& name, size_t size) : size_(size), rwt_(name+L"RWToggle") { hMMF_ = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (int)size, name.c_str() ); if(hMMF_ == NULL) throw std::exception("\n\n can't create MMF\n\n"); pMMF_ = (wchar_t*)MapViewOfFile(hMMF_,FILE_MAP_ALL_ACCESS,0,0,size); rwt_.setWrite(); } MMFmgr::~MMFmgr() { CloseHandle(hMMF_); } void MMFmgr::putString(const std::wstring& str) { rwt_.writeWait(); rwt_.writerLock(); if(str.size() > this->size_) throw std::exception("\n\n string size exceeds MMF size\n\n"); ::wmemcpy(pMMF_,str.c_str(),str.size()); *(pMMF_ + str.size()) = '\0'; rwt_.setRead(); rwt_.writerUnlock(); } std::wstring MMFmgr::getString() { rwt_.readWait(); std::wstring temp(pMMF_); rwt_.setWrite(); return temp; } void MMFmgr::putBlock(Block blk) { throw std::exception("\n\n not implemented yet\n\n"); } Block MMFmgr::getBlock() { throw std::exception("\n\n not implemented yet\n\n"); } void MMFmgr::clear() { rwt_.setWrite(); } #include #include #include "threads.h" template std::wstring ToString(T t) { std::wostringstream out; out << t; return out.str(); } class threadProc : public Thread_Processing { public: threadProc(MMFmgr& mmf) : mmf_(mmf) {} threadProc* clone() const { return new threadProc(*this); } void run() { std::wstring msg; for(int i=0; i<20; ++i) { msg = L"msg#"; msg += ToString(i); msg += L" - through MMF"; mmf_.putString(msg); ::Sleep(10); } msg = L"quit"; mmf_.putString(msg); } private: MMFmgr mmf_; }; void main() { try { RWToggle rwt(L"CSE775_Toggle"); MMFmgr mmf(L"CSE775_Map",1024); mmf.putString(L"CSE775 string for Memory-Mapped File"); std::wcout << L"\n " << mmf.getString().c_str() << L"\n"; mmf.clear(); threadProc tp(mmf); Thread thrd(tp); thrd.start(); std::wstring msg = L""; while(msg != L"quit") { msg = mmf.getString(); std::wcout << L"\n " << msg; } std::wcout << L"\n\n"; thrd.wait(); } catch(std::exception& ex) { std::cout << ex.what(); } }