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 int getDataSize (void) const { return (int)m_data.size(); } 59 void setDataSize (int 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, int numBytes); 76 const deUint8* getDataBlock (int numBytes); //!< \note Valid only during call. 77 78 private: 79 Call* m_call; 80 int m_curPos; 81 }; 82 83 class CallWriter 84 { 85 public: 86 CallWriter (CallQueue* queue, Call::Function function); 87 ~CallWriter (void); 88 89 void write (const deUint8* bytes, int numBytes); 90 void enqueue (void); 91 92 private: 93 CallWriter (const CallWriter& other); 94 CallWriter& operator= (const CallWriter& other); 95 96 CallQueue* m_queue; 97 Call* m_call; 98 bool m_enqueued; 99 }; 100 101 class CallQueue 102 { 103 public: 104 CallQueue (void); 105 ~CallQueue (void); 106 107 void callNext (void); //!< Executes and removes first call in queue. Will block if queue is empty. 108 109 Call* getEmptyCall (void); 110 void enqueue (Call* call); 111 void freeCall (Call* call); 112 113 private: 114 CallQueue (const CallQueue& other); 115 CallQueue& operator= (const CallQueue& other); 116 117 de::Semaphore m_callSem; 118 119 de::Mutex m_lock; 120 std::vector<Call*> m_calls; 121 std::vector<Call*> m_freeCalls; 122 de::RingBuffer<Call*> m_callQueue; 123 }; 124 125 // Stream operators for call reader / writer. 126 127 CallReader& operator>> (CallReader& reader, std::string& value); 128 CallWriter& operator<< (CallWriter& writer, const char* str); 129 130 template <typename T> 131 CallReader& operator>> (CallReader& reader, T& value) 132 { 133 reader.read((deUint8*)&value, sizeof(T)); 134 return reader; 135 } 136 137 template <typename T> 138 CallWriter& operator<< (CallWriter& writer, T& value) 139 { 140 writer.write((const deUint8*)&value, sizeof(T)); 141 return writer; 142 } 143 144 } // xe 145 146 #endif // _XECALLQUEUE_HPP 147