TNB Library
TnbCeMsgQueueWatcher.h
[詳解]
1#pragma once
11#ifndef _WIN32_WCE
12 #error TnbCeMsgQueueWatcher.h is only supported on Windows CE platforms.
13#endif // _WIN32_WCE
14
15
16
17#include "TnbThread.h"
18#include <Msgqueue.h>
19
20
21
22//TNB Library
23namespace TNB
24{
25
26
27
41template<typename TYP>
43{
44public:
45
54 struct IListener
55 {
57 virtual ~IListener(void) {}
58
66 virtual void OnMsgQueueWatcherEvent(const TYP& data, size_t length, bool isAlert) = 0;
67 };
68
69
70 //---------------------------
71
72
74 CMsgQueueWatcherT(void) : m_handle(NULL), m_pListener(NULL)
75 {
76 }
77
80 {
81 Stop();
82 }
83
88 HANDLE GetSafeHandle(void) const
89 {
90 return m_handle;
91 }
92
97 operator HANDLE(void) const
98 {
99 return m_handle;
100 }
101
107 {
108 m_pListener = P;
109 }
110
116 bool IsStarted(void) const
117 {
118 return m_handle != NULL;
119 }
120
129 bool Start(size_t maxMessagesCount = 0, bool isRead = true, LPCTSTR lpszThreadName = NULL)
130 {
131 MSGQUEUEOPTIONS opt = { 0 };
132 opt.dwSize = sizeof(MSGQUEUEOPTIONS);
133 opt.dwFlags = 0;
134 opt.dwMaxMessages = maxMessagesCount;
135 if ( maxMessagesCount == 0 )
136 {
137 opt.dwFlags = MSGQUEUE_NOPRECOMMIT;
138 }
139 opt.cbMaxMessage = sizeof(TYP);
140 opt.bReadAccess = isRead;
141 return m_Start(NULL, opt, lpszThreadName);
142 }
143
152 bool Start(LPCTSTR lpszQueueName, const MSGQUEUEOPTIONS& option, LPCTSTR lpszThreadName = NULL)
153 {
154 MSGQUEUEOPTIONS opt = option;
155 return m_Start(lpszQueueName, opt,lpszThreadName);
156 }
157
164 bool Stop(void)
165 {
166 bool r = true;
167 if ( m_handle != NULL )
168 {
169 r = !! ::CloseMsgQueue(m_handle);
170 m_handle = NULL;
171 }
172 m_thread.Stop();
173 return r;
174 }
175
184 bool Send(const TYP& data, DWORD timeout = INFINITE, bool isAlert = false)
185 {
186 DWORD fg = isAlert ? MSGQUEUE_MSGALERT : 0;
187 TYP t = data;
188 return !! ::WriteMsgQueue(m_handle, &t, sizeof(data), timeout, fg);
189 }
190
197 bool GetInfo(MSGQUEUEINFO& _info) const
198 {
199 _info.dwSize = sizeof(MSGQUEUEINFO);
200 return !! ::GetMsgQueueInfo(m_handle, &_info);
201 }
202
208 {
209 return m_thread;
210 }
211
212protected:
213
221 virtual DWORD Run(void)
222 {
223 while ( IsRunnable() && IsStarted() )
224 {
225// DWORD dw = ::MsgWaitForMultipleObjects(1, &m_handle, FALSE, INFINITE, QS_ALLEVENTS);
226 DWORD dw = ::WaitForSingleObject(m_handle, INFINITE);
227 if ( dw == WAIT_OBJECT_0 || dw == WAIT_ABANDONED_0 )
228 {
229 TYP buf;
230 DWORD dwRead = 0;
231 DWORD dwFlags = 0;
232 while ( ::ReadMsgQueue(m_handle, &buf, sizeof(TYP), &dwRead, 0, &dwFlags) )
233 {
234 if ( m_pListener != NULL )
235 {
236 m_pListener->OnMsgQueueWatcherEvent(buf, dwRead, dwFlags == MSGQUEUE_MSGALERT);
237 }
238 }
239 DWORD err = ::GetLastError();
240 if ( err != ERROR_TIMEOUT && err != ERROR_INVALID_HANDLE )
241 {
242 if ( ERROR_INSUFFICIENT_BUFFER == _GetLastError("ReadMsgQueue") )
243 {
244 ASSERT( false );
245 }
246 }
247 }
248 }
249 return 0;
250 }
251
252private:
253 bool m_Start(LPCTSTR lpszQueueName, MSGQUEUEOPTIONS& _opt, LPCTSTR lpszThreadName)
254 {
255 Stop();
256 _opt.dwSize = sizeof(MSGQUEUEOPTIONS);
257 m_handle = ::CreateMsgQueue(lpszQueueName, &_opt);
258 if ( m_handle != NULL )
259 {
260 m_thread.SetRunner(this);
261 if ( lpszThreadName == NULL )
262 {
263 lpszThreadName = _T("CMsgQueueWatcher");
264 }
265 if ( m_thread.Start(lpszThreadName) )
266 {
267 return true;
268 }
269 }
270 Stop();
271 return false;
272 }
273
274 HANDLE m_handle;
275 IListener* m_pListener;
276 CThread m_thread;
277};
278
279
280
281}; // TNB
スレッド管理関係のヘッダ
メッセージキュー監視 (CE専用).
CThreadStatus & ReferThreadStatus(void)
[参照] 監視スレッド状態参照.
void SetListener(IListener *P)
[設定] リスナー設定.
bool GetInfo(MSGQUEUEINFO &_info) const
[取得] キュー情報.
~CMsgQueueWatcherT(void)
デストラクタ
bool Send(const TYP &data, DWORD timeout=INFINITE, bool isAlert=false)
[設定] 送信.
bool IsStarted(void) const
[確認] 監視確認.
HANDLE GetSafeHandle(void) const
[取得] ハンドル取得.
bool Start(LPCTSTR lpszQueueName, const MSGQUEUEOPTIONS &option, LPCTSTR lpszThreadName=NULL)
[設定] 監視開始.
bool Start(size_t maxMessagesCount=0, bool isRead=true, LPCTSTR lpszThreadName=NULL)
[設定] 監視開始.
virtual DWORD Run(void)
[動作] スレッド処理本体
CMsgQueueWatcherT(void)
コンストラクタ
bool Stop(void)
[設定] 監視停止.
スレッド状態管理クラス
Definition: TnbThread.h:128
スレッド管理クラス
Definition: TnbThread.h:316
bool SetRunner(IRunner *pRunner)
[設定] ランナー、設定
Definition: TnbThread.h:420
bool Stop(DWORD dwWait=15000)
[設定] スレッド停止 スレッドに対して停止要求します。
Definition: TnbThread.h:505
bool Start(LPCTSTR lpszName=NULL)
[設定] スレッド開始
Definition: TnbThread.h:618
TNB Library
Definition: TnbDoxyTitle.txt:2
メッセージキュー監視のリスナーインターフェース (CE専用).
virtual void OnMsgQueueWatcherEvent(const TYP &data, size_t length, bool isAlert)=0
[通知] 受信通知.
virtual ~IListener(void)
デストラクタ
スレッド実行管理ランナーインターフェース
Definition: TnbThread.h:341
bool IsRunnable(void) const
[確認] 実行可能か否か
Definition: TnbThread.h:355