// // The MIT License // // Copyright (c) 2010 James E Beveridge // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW" // http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html // See ReadMe.txt for overview information. #include template class CThreadSafeQueue : protected std::list { public: CThreadSafeQueue(int nMaxCount) { m_bOverflow = false; m_hSemaphore = ::CreateSemaphore( NULL, // no security attributes 0, // initial count nMaxCount, // max count NULL); // anonymous } ~CThreadSafeQueue() { ::CloseHandle(m_hSemaphore); m_hSemaphore = NULL; } void push(C& c) { CComCritSecLock lock( m_Crit, true ); push_back( c ); lock.Unlock(); if (!::ReleaseSemaphore(m_hSemaphore, 1, NULL)) { // If the semaphore is full, then take back the entry. lock.Lock(); pop_back(); if (GetLastError() == ERROR_TOO_MANY_POSTS) { m_bOverflow = true; } } } bool pop(C& c) { CComCritSecLock lock( m_Crit, true ); // If the user calls pop() more than once after the // semaphore is signaled, then the semaphore count will // get out of sync. We fix that when the queue empties. if (empty()) { while (::WaitForSingleObject(m_hSemaphore, 0) != WAIT_TIMEOUT) 1; return false; } c = front(); pop_front(); return true; } // If overflow, use this to clear the queue. void clear() { CComCritSecLock lock( m_Crit, true ); for (DWORD i=0; i