1 #ifndef _XECALLQUEUE_HPP 2 #define _XECALLQUEUE_HPP 3 /*------------------------------------------------------------------------- 4 * drawElements Quality Program Test Executor 5 * ------------------------------------------ 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Cross-thread function call dispatcher. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "xeDefs.hpp" 27 #include "deMutex.hpp" 28 #include "deSemaphore.hpp" 29 #include "deRingBuffer.hpp" 30 31 #include <vector> 32 33 namespace xe 34 { 35 36 class Call; 37 class CallReader; 38 class CallWriter; 39 class CallQueue; 40 41 // \todo [2012-07-10 pyry] Optimize memory management in Call 42 // \todo [2012-07-10 pyry] CallQueue API could be improved to match TestLog API more closely. 43 // In order to do that, reference counting system for call object management is needed. 44 45 class Call 46 { 47 public: 48 typedef void (*Function) (CallReader& data); 49 50 Call (void); 51 ~Call (void); 52 53 void clear (void); 54 55 Function getFunction (void) const { return m_func; } 56 void setFunction (Function func) { m_func = func; } 57 58 size_t getDataSize (void) const { return m_data.size(); } 59 void setDataSize (size_t size) { m_data.resize(size); } 60 61 const deUint8* getData (void) const { return m_data.empty() ? DE_NULL : &m_data[0]; } 62 deUint8* getData (void) { return m_data.empty() ? DE_NULL : &m_data[0]; } 63 64 private: 65 Function m_func; 66 std::vector<deUint8> m_data; 67 }; 68 69 class CallReader 70 { 71 public: 72 CallReader (Call* call); 73 CallReader (void) : m_call(DE_NULL), m_curPos(0) {} 74 75 void read (deUint8* bytes, size_t numBytes); 76 const deUint8* getDataBlock (size_t numBytes); //!< \note Valid only during call. 77 bool isDataConsumed (void) const; //!< all data has been consumed 78 79 private: 80 CallReader (const CallReader& other); //!< disallowed 81 CallReader& operator= (const CallReader& other); //!< disallowed 82 83 Call* m_call; 84 size_t m_curPos; 85 }; 86 87 class CallWriter 88 { 89 public: 90 CallWriter (CallQueue* queue, Call::Function function); 91 ~CallWriter (void); 92 93 void write (const deUint8* bytes, size_t numBytes); 94 void enqueue (void); 95 96 private: 97 CallWriter (const CallWriter& other); 98 CallWriter& operator= (const CallWriter& other); 99 100 CallQueue* m_queue; 101 Call* m_call; 102 bool m_enqueued; 103 }; 104 105 class CallQueue 106 { 107 public: 108 CallQueue (void); 109 ~CallQueue (void); 110 111 void callNext (void); //!< Executes and removes first call in queue. Will block if queue is empty. 112 113 Call* getEmptyCall (void); 114 void enqueue (Call* call); 115 void freeCall (Call* call); 116 void cancel (void); 117 118 private: 119 CallQueue (const CallQueue& other); 120 CallQueue& operator= (const CallQueue& other); 121 122 bool m_canceled; 123 de::Semaphore m_callSem; 124 125 de::Mutex m_lock; 126 std::vector<Call*> m_calls; 127 std::vector<Call*> m_freeCalls; 128 de::RingBuffer<Call*> m_callQueue; 129 }; 130 131 // Stream operators for call reader / writer. 132 133 CallReader& operator>> (CallReader& reader, std::string& value); 134 CallWriter& operator<< (CallWriter& writer, const char* str); 135 136 template <typename T> 137 CallReader& operator>> (CallReader& reader, T& value) 138 { 139 reader.read((deUint8*)&value, sizeof(T)); 140 return reader; 141 } 142 143 template <typename T> 144 CallWriter& operator<< (CallWriter& writer, T& value) 145 { 146 writer.write((const deUint8*)&value, sizeof(T)); 147 return writer; 148 } 149 150 } // xe 151 152 #endif // _XECALLQUEUE_HPP 153