| #ifndef _XECALLQUEUE_HPP |
| #define _XECALLQUEUE_HPP |
| /*------------------------------------------------------------------------- |
| * drawElements Quality Program Test Executor |
| * ------------------------------------------ |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Cross-thread function call dispatcher. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "xeDefs.hpp" |
| #include "deMutex.hpp" |
| #include "deSemaphore.hpp" |
| #include "deRingBuffer.hpp" |
| |
| #include <vector> |
| |
| namespace xe |
| { |
| |
| class Call; |
| class CallReader; |
| class CallWriter; |
| class CallQueue; |
| |
| // \todo [2012-07-10 pyry] Optimize memory management in Call |
| // \todo [2012-07-10 pyry] CallQueue API could be improved to match TestLog API more closely. |
| // In order to do that, reference counting system for call object management is needed. |
| |
| class Call |
| { |
| public: |
| typedef void (*Function) (CallReader& data); |
| |
| Call (void); |
| ~Call (void); |
| |
| void clear (void); |
| |
| Function getFunction (void) const { return m_func; } |
| void setFunction (Function func) { m_func = func; } |
| |
| size_t getDataSize (void) const { return m_data.size(); } |
| void setDataSize (size_t size) { m_data.resize(size); } |
| |
| const deUint8* getData (void) const { return m_data.empty() ? DE_NULL : &m_data[0]; } |
| deUint8* getData (void) { return m_data.empty() ? DE_NULL : &m_data[0]; } |
| |
| private: |
| Function m_func; |
| std::vector<deUint8> m_data; |
| }; |
| |
| class CallReader |
| { |
| public: |
| CallReader (Call* call); |
| CallReader (void) : m_call(DE_NULL), m_curPos(0) {} |
| |
| void read (deUint8* bytes, size_t numBytes); |
| const deUint8* getDataBlock (size_t numBytes); //!< \note Valid only during call. |
| bool isDataConsumed (void) const; //!< all data has been consumed |
| |
| private: |
| CallReader (const CallReader& other); //!< disallowed |
| CallReader& operator= (const CallReader& other); //!< disallowed |
| |
| Call* m_call; |
| size_t m_curPos; |
| }; |
| |
| class CallWriter |
| { |
| public: |
| CallWriter (CallQueue* queue, Call::Function function); |
| ~CallWriter (void); |
| |
| void write (const deUint8* bytes, size_t numBytes); |
| void enqueue (void); |
| |
| private: |
| CallWriter (const CallWriter& other); |
| CallWriter& operator= (const CallWriter& other); |
| |
| CallQueue* m_queue; |
| Call* m_call; |
| bool m_enqueued; |
| }; |
| |
| class CallQueue |
| { |
| public: |
| CallQueue (void); |
| ~CallQueue (void); |
| |
| void callNext (void); //!< Executes and removes first call in queue. Will block if queue is empty. |
| |
| Call* getEmptyCall (void); |
| void enqueue (Call* call); |
| void freeCall (Call* call); |
| void cancel (void); |
| |
| private: |
| CallQueue (const CallQueue& other); |
| CallQueue& operator= (const CallQueue& other); |
| |
| bool m_canceled; |
| de::Semaphore m_callSem; |
| |
| de::Mutex m_lock; |
| std::vector<Call*> m_calls; |
| std::vector<Call*> m_freeCalls; |
| de::RingBuffer<Call*> m_callQueue; |
| }; |
| |
| // Stream operators for call reader / writer. |
| |
| CallReader& operator>> (CallReader& reader, std::string& value); |
| CallWriter& operator<< (CallWriter& writer, const char* str); |
| |
| template <typename T> |
| CallReader& operator>> (CallReader& reader, T& value) |
| { |
| reader.read((deUint8*)&value, sizeof(T)); |
| return reader; |
| } |
| |
| template <typename T> |
| CallWriter& operator<< (CallWriter& writer, T& value) |
| { |
| writer.write((const deUint8*)&value, sizeof(T)); |
| return writer; |
| } |
| |
| } // xe |
| |
| #endif // _XECALLQUEUE_HPP |