1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_Event.h
4
5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 29304 $
14 *---------------------------------------------------------------------------*/
15
16 /*! @file
17 @brief Event に関するAPI の宣言
18
19 :include nn/os.h
20 */
21
22 #ifndef NN_OS_OS_EVENT_H_
23 #define NN_OS_OS_EVENT_H_
24
25 #include <nn/types.h>
26 #include <nn/Handle.h>
27 #include <nn/Result.h>
28 #include <nn/os/os_Synchronization.h>
29
30 #include <nn/util/util_Result.h>
31 #include <nn/err.h>
32
33 #ifdef __cplusplus
34
35 namespace nn{ namespace os {
36
37 /*!
38 @brief ライブラリが内部的に使うクラスです。このクラスを直接使わないでください。
39 */
40 class EventBase : public InterruptEvent
41 {
42 protected:
43 explicit EventBase(ResetType resetType);
EventBase()44 EventBase() {}
~EventBase()45 ~EventBase() {}
46
47 void Initialize(ResetType resetType);
48 nn::Result TryInitialize(ResetType resetType);
49 void Finalize();
50 void Signal();
51 void ClearSignal();
52
53 private:
54 Result TryInitializeImpl(ResetType resetType);
55 };
56
57 // インライン実装
58
TryInitializeImpl(ResetType resetType)59 inline Result EventBase::TryInitializeImpl(ResetType resetType)
60 {
61 Handle handle;
62 NN_UTIL_RETURN_IF_FAILED(nn::svc::CreateEvent(&handle, resetType));
63 this->SetHandle(handle);
64 return ResultSuccess();
65 }
66
Initialize(ResetType resetType)67 inline void EventBase::Initialize(ResetType resetType)
68 {
69 NN_ERR_THROW_FATAL(TryInitializeImpl(resetType));
70 }
71
TryInitialize(ResetType resetType)72 inline nn::Result EventBase::TryInitialize(ResetType resetType)
73 {
74 Result result = TryInitializeImpl(resetType);
75 if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE)
76 {
77 return result;
78 }
79 NN_ERR_THROW_FATAL(result);
80 return result;
81 }
82
Finalize()83 inline void EventBase::Finalize()
84 {
85 InterruptEvent::Finalize();
86 }
87
EventBase(ResetType resetType)88 inline EventBase::EventBase(ResetType resetType)
89 {
90 Initialize(resetType);
91 }
92
Signal()93 inline void EventBase::Signal()
94 {
95 NN_ERR_THROW_FATAL(nn::svc::SignalEvent(GetHandle()));
96 }
97
ClearSignal()98 inline void EventBase::ClearSignal()
99 {
100 NN_ERR_THROW_FATAL(nn::svc::ClearEvent(GetHandle()));
101 }
102
103
104 /*!
105 @brief イベントを扱う為のクラスです。イベントはイベントの発生を通知する同期オブジェクトです。
106
107 通常は @ref nn::os::Event ではなく、@ref nn::os::LightEvent を使用すべきです。
108 複数の同期オブジェクトを同時に待つことができないという点を除いて
109 @ref nn::os::Event より @ref nn::os::LightEvent の方が優れています。
110
111 イベントは、シグナル状態と非シグナル状態の二つの状態持ちます。
112 Event の Wait 動作では、イベントがシグナル状態になるのを待ちます。
113
114 イベントには、「手動リセットイベント」と「自動リセットイベント」の二つがあり、
115 初期化時のパラメータによって設定することができます。
116
117 手動リセットイベントでは、@ref Signal によってシグナル状態になると、
118 @ref ClearSignal が呼び出されるまで、常にシグナル状態が維持されます。
119 シグナル状態の間、このイベントに対する全ての Wait 動作は解放されます。
120
121 自動リセットイベントでは、@ref Signal によってシグナル状態になると、
122 Wait 動作の解放されうるスレッドの中で最も優先度の高いもののうち唯一つだけがが解放されます。
123 そのほかのスレッドは解放されません。
124
125 @see nn::os::Semaphore
126 */
127 class Event : public EventBase
128 {
129 public:
130
131 /*!
132 @brief イベントを構築し、初期化します。
133
134 @param[in] manualReset 手動リセットイベントか否かを指定します。
135 */
Event(bool manualReset)136 explicit Event(bool manualReset) : EventBase(manualReset ? RESET_TYPE_STICKY: RESET_TYPE_ONESHOT) {}
137
138 /*!
139 @brief イベントオブジェクトを構築します。初期化はしません。
140 イベントを使用する場合は、明示的に @ref Initialize を呼ぶ必要があります。
141 */
Event()142 Event() {}
143
144 /*!
145 @brief イベントを初期化します。
146
147 @param[in] manualReset 手動リセットイベントか否かを指定します。
148 */
Initialize(bool manualReset)149 void Initialize(bool manualReset) { EventBase::Initialize(manualReset ? RESET_TYPE_STICKY: RESET_TYPE_ONESHOT); }
Initialize(ResetType resetType)150 void Initialize(ResetType resetType) { EventBase::Initialize(resetType); }
151
TryInitialize(bool manualReset)152 nn::Result TryInitialize(bool manualReset) { return EventBase::TryInitialize(manualReset ? RESET_TYPE_STICKY: RESET_TYPE_ONESHOT); }
153
154 /*!
155 @brief イベントを破棄します。
156
157 デストラクタからも自動で呼ばれます。
158 @return 無し。
159 */
Finalize()160 void Finalize() { EventBase::Finalize(); }
161
162 /*!
163 @brief デストラクタです。
164 */
~Event()165 ~Event() {}
166
167 /*!
168 @brief イベントをシグナル状態にします。
169
170 @return 無し。
171 */
Signal()172 void Signal() { EventBase::Signal(); }
173
174 /*!
175 @brief イベントがシグナル状態になるのを待ちます。
176
177 @return 無し。
178 */
Wait()179 void Wait() { EventBase::WaitOne(); }
180
181 /*!
182 @brief イベントが発生するまでブロックします。
183
184 イベントがシグナル状態であれば、即座に true が返ります。
185 シグナル状態でなかった場合、最大で timeout で指定した時間だけ待ち、
186 その間にシグナルを受け取ることができれば true を返します。
187 timeout で指定した時間だけ待ってもシグナルを受け取れなかった場合は、false を返します。
188
189 @param[in] timeout タイムアウト時間を指定します。0 を指定すると即座に処理を返します。
190
191 @return タイムアウト時間までにイベントが発生したかを返します。
192 */
Wait(nn::fnd::TimeSpan timeout)193 bool Wait(nn::fnd::TimeSpan timeout) { return EventBase::WaitOne(timeout); }
194
195 /*!
196 @brief イベントを手動でクリアします。
197
198 @return 無し。
199 */
ClearSignal()200 void ClearSignal() { EventBase::ClearSignal(); }
201
202 };
203
204 }} // namesapce nn::os
205
206 #endif // __cplusplus
207
208 // 以下、C 用宣言
209
210 #include <nn/util/detail/util_CLibImpl.h>
211
212 /*!
213 @addtogroup nn_os
214 @{
215
216 @defgroup nn_os_Event_c Event (C)
217
218 @brief @ref nn::os::Event の C インタフェースモジュールです。
219
220 @{
221 */
222
223 /*!
224 @struct nnosEvent
225 @brief イベントを表す C の構造体です。
226 @brief 対応するクラス @ref nn::os::Event を参照してください。
227 */
228 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosEvent, nn::os::Event, 4, u32);
229 NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosEventToWaitObject, nnosEvent, nnosWaitObject);
230 NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosWaitObjectToEvent, nnosWaitObject, nnosEvent);
231
232 /*!
233 @brief 対応する C++ 関数 @ref nn::os::Event::Initialize を参照してください。
234 */
235 NN_EXTERN_C void nnosEventInitialize(nnosEvent* this_, bool manualReset);
236
237 /*!
238 @brief 対応する C++ 関数 @ref nn::os::Event::TryInitialize を参照してください。
239 */
240 NN_EXTERN_C bool nnosEventTryInitialize(nnosEvent* this_, bool manualReset);
241
242 /*!
243 @brief 対応する C++ 関数 @ref nn::os::Event::Signal を参照してください。
244 */
245 NN_EXTERN_C void nnosEventSignal(nnosEvent* this_);
246
247 /*!
248 @brief 対応する C++ 関数 @ref nn::os::Event::Wait を参照してください。
249 */
250 NN_EXTERN_C void nnosEventWaitSignal(nnosEvent* this_);
251
252 /*!
253 @brief 対応する C++ 関数 @ref nn::os::Event::Wait を参照してください。
254 */
255 NN_EXTERN_C bool nnosEventTryWaitSignal(nnosEvent* this_, s64 nanoSecondsTimeout);
256
257 /*!
258 @brief 対応する C++ 関数 @ref nn::os::Event::ClearSignal を参照してください。
259 */
260 NN_EXTERN_C void nnosEventClearSignal(nnosEvent* this_);
261
262 /*!
263 @brief 対応する C++ 関数 @ref nn::os::Event::Finalize を参照してください。
264 */
265 NN_EXTERN_C void nnosEventFinalize(nnosEvent* this_);
266
267 /*!
268 @}
269
270 @}
271 */
272
273 #endif
274
275