4d3a7562 |
1 | #pragma once |
2 | /* |
3 | * This file is part of the libCEC(R) library. |
4 | * |
16f47961 |
5 | * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. |
4d3a7562 |
6 | * libCEC(R) is an original work, containing original code. |
7 | * |
8 | * libCEC(R) is a trademark of Pulse-Eight Limited. |
9 | * |
10 | * This program is dual-licensed; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. |
14 | * |
15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
23 | * |
24 | * |
25 | * Alternatively, you can license this library under a commercial license, |
26 | * please contact Pulse-Eight Licensing for more information. |
27 | * |
28 | * For more information contact: |
29 | * Pulse-Eight Licensing <license@pulse-eight.com> |
30 | * http://www.pulse-eight.com/ |
31 | * http://www.pulse-eight.net/ |
32 | */ |
33 | |
34 | #include "lib/platform/threads/mutex.h" |
35 | |
36 | namespace CEC |
37 | { |
38 | using namespace PLATFORM; |
39 | |
40 | class CAdapterMessageQueueEntry |
41 | { |
42 | public: |
43 | CAdapterMessageQueueEntry(const cec_command &command) |
44 | : m_bWaiting(true), m_retval((uint32_t)-1), m_bSucceeded(false) |
45 | { |
46 | m_hash = hashValue( |
51b611bc |
47 | uint32_t(command.opcode_set ? command.opcode : CEC_OPCODE_NONE), |
48 | command.initiator, command.destination); |
4d3a7562 |
49 | } |
50 | |
51 | virtual ~CAdapterMessageQueueEntry(void) {} |
52 | |
53 | /*! |
54 | * @brief Query result from worker thread |
55 | */ |
56 | uint32_t Result() const |
57 | { |
58 | return m_retval; |
59 | } |
60 | |
61 | /*! |
62 | * @brief Signal waiting threads |
63 | */ |
64 | void Broadcast(void) |
65 | { |
66 | CLockObject lock(m_mutex); |
67 | m_condition.Broadcast(); |
68 | } |
69 | |
70 | /*! |
71 | * @brief Signal waiting thread(s) when message matches this entry |
72 | */ |
73 | bool CheckMatch(uint32_t opcode, cec_logical_address initiator, |
51b611bc |
74 | cec_logical_address destination, uint32_t response) |
4d3a7562 |
75 | { |
76 | uint32_t hash = hashValue(opcode, initiator, destination); |
77 | |
78 | if (hash == m_hash) |
79 | { |
80 | CLockObject lock(m_mutex); |
81 | |
51b611bc |
82 | m_retval = response; |
4d3a7562 |
83 | m_bSucceeded = true; |
84 | m_condition.Signal(); |
51b611bc |
85 | return true; |
4d3a7562 |
86 | } |
87 | |
88 | return false; |
89 | } |
90 | |
91 | /*! |
92 | * @brief Wait for a response to this command. |
93 | * @param iTimeout The timeout to use while waiting. |
94 | * @return True when a response was received before the timeout passed, false otherwise. |
95 | */ |
96 | bool Wait(uint32_t iTimeout) |
97 | { |
98 | CLockObject lock(m_mutex); |
51b611bc |
99 | |
4d3a7562 |
100 | bool bReturn = m_bSucceeded ? true : m_condition.Wait(m_mutex, m_bSucceeded, iTimeout); |
4d3a7562 |
101 | m_bWaiting = false; |
102 | return bReturn; |
103 | } |
104 | |
105 | /*! |
106 | * @return True while a thread is waiting for a signal or isn't waiting yet, false otherwise. |
107 | */ |
108 | bool IsWaiting(void) |
109 | { |
110 | CLockObject lock(m_mutex); |
111 | return m_bWaiting; |
112 | } |
113 | |
114 | /*! |
115 | * @return Hash value for given cec_command |
116 | */ |
117 | static uint32_t hashValue(uint32_t opcode, |
51b611bc |
118 | cec_logical_address initiator, |
119 | cec_logical_address destination) |
4d3a7562 |
120 | { |
121 | return 1 | ((uint32_t)initiator << 8) | |
122 | ((uint32_t)destination << 16) | ((uint32_t)opcode << 16); |
123 | } |
124 | |
125 | private: |
126 | bool m_bWaiting; /**< true while a thread is waiting or when it hasn't started waiting yet */ |
127 | PLATFORM::CCondition<bool> m_condition; /**< the condition to wait on */ |
128 | PLATFORM::CMutex m_mutex; /**< mutex for changes to this class */ |
129 | uint32_t m_hash; |
130 | uint32_t m_retval; |
131 | bool m_bSucceeded; |
132 | }; |
133 | |
134 | }; |