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
getFunction(void) const55 Function getFunction (void) const { return m_func; }
setFunction(Function func)56 void setFunction (Function func) { m_func = func; }
57
getDataSize(void) const58 size_t getDataSize (void) const { return m_data.size(); }
setDataSize(size_t size)59 void setDataSize (size_t size) { m_data.resize(size); }
60
getData(void) const61 const deUint8* getData (void) const { return m_data.empty() ? DE_NULL : &m_data[0]; }
getData(void)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);
CallReader(void)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>
operator >>(CallReader & reader,T & value)137 CallReader& operator>> (CallReader& reader, T& value)
138 {
139 reader.read((deUint8*)&value, sizeof(T));
140 return reader;
141 }
142
143 template <typename T>
operator <<(CallWriter & writer,T & value)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