leonid@255: /* leonid@255: This file is part of CanFestival, a library implementing CanOpen Stack. leonid@255: leonid@255: CanFestival Copyright (C): Edouard TISSERANT and Francis DUPIN leonid@255: CanFestival Win32 port Copyright (C) 2007 Leonid Tochinski, ChattenAssociates, Inc. leonid@255: leonid@255: See COPYING file for copyrights details. leonid@255: leonid@255: This library is free software; you can redistribute it and/or leonid@255: modify it under the terms of the GNU Lesser General Public leonid@255: License as published by the Free Software Foundation; either leonid@255: version 2.1 of the License, or (at your option) any later version. leonid@255: leonid@255: This library is distributed in the hope that it will be useful, leonid@255: but WITHOUT ANY WARRANTY; without even the implied warranty of leonid@255: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU leonid@255: Lesser General Public License for more details. leonid@255: leonid@255: You should have received a copy of the GNU Lesser General Public leonid@255: License along with this library; if not, write to the Free Software leonid@255: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA leonid@255: */ leonid@255: leonid@252: // thread safe que leonid@255: #ifndef __async_access_que_h__ leonid@255: #define __async_access_que_h__ leonid@255: leonid@252: #include leonid@252: #include "AutoReleaseCS.h" leonid@252: leonid@252: template leonid@252: class async_access_que leonid@252: { leonid@252: public: leonid@252: async_access_que() leonid@252: { leonid@252: ::InitializeCriticalSection(&m_cs); Christian@643: Christian@643: m_newObject = CreateEvent(NULL, FALSE, FALSE, NULL); Christian@643: m_stop = CreateEvent(NULL, FALSE, FALSE, NULL); Christian@643: m_stopped = CreateEvent(NULL, FALSE, FALSE, NULL); Christian@643: m_commands[0] = m_newObject; Christian@643: m_commands[1] = m_stop; Christian@643: leonid@252: } leonid@252: ~async_access_que() leonid@252: { Christian@643: SignalObjectAndWait(m_stop, m_stopped, 500, FALSE); leonid@252: ::DeleteCriticalSection(&m_cs); Christian@643: CloseHandle(m_stop); Christian@643: CloseHandle(m_stopped); Christian@643: CloseHandle(m_newObject); leonid@252: } leonid@252: leonid@252: void append(const type& data) leonid@252: { leonid@252: AutoReleaseCS acs(m_cs); leonid@252: m_data.push_back(data); Christian@643: SetEvent(m_newObject); leonid@252: } leonid@252: leonid@252: bool extract_top(type& data) leonid@252: { Christian@643: bool empty = true; Christian@643: { Christian@643: AutoReleaseCS acs(m_cs); Christian@643: empty = m_data.empty(); Christian@643: } Christian@643: Christian@643: if (empty) Christian@643: { Christian@643: DWORD objectIndex; Christian@643: do Christian@643: { Christian@643: objectIndex = WaitForMultipleObjects(sizeof(m_commands) / sizeof(&(m_commands[0])), m_commands, FALSE, INFINITE); Christian@643: if (objectIndex - WAIT_OBJECT_0 == 1) //m_stop Christian@643: { Christian@643: SetEvent(m_stopped); Christian@643: return false; //This will exit the canReceive-loop Christian@643: } Christian@643: } while (objectIndex - WAIT_OBJECT_0 != 0); Christian@643: } Christian@643: Christian@643: { Christian@643: AutoReleaseCS acs(m_cs); Christian@643: if (m_data.empty()) Christian@643: { Christian@643: return false; //This will exit the canReceive-loop Christian@643: } Christian@643: data = m_data.front(); Christian@643: m_data.pop_front(); Christian@643: ResetEvent(m_newObject); Christian@643: return true; Christian@643: } leonid@252: } leonid@252: leonid@252: void clear() leonid@252: { leonid@252: AutoReleaseCS acs(m_cs); leonid@252: m_data.clear(); leonid@252: } leonid@252: leonid@252: protected: leonid@252: std::deque m_data; leonid@252: CRITICAL_SECTION m_cs; Christian@643: Christian@643: HANDLE m_newObject; Christian@643: HANDLE m_stop; Christian@643: HANDLE m_stopped; Christian@643: HANDLE m_commands[2]; leonid@252: }; leonid@255: #endif //__async_access_que_h__