1 krisbash 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 krisbash 1.1 **==============================================================================
23 */
24
25 #ifndef _subscription_manager_h
26 #define _subscription_manager_h
27
28 #include "context.h"
29 #include "filter.h"
30 #include "SubscriptionContext.h"
31 #include "AggregationContext.h"
32 #include "LifecycleContext.h"
33 #include <common.h>
34 #include <base/list.h>
35 #include <indication/common/indicommon.h>
36 #include <pal/sem.h>
37
38 BEGIN_EXTERNC
39
40 /*
41 **==============================================================================
42 **
43 krisbash 1.1 ** Describes the various states of a SubscriptionContext
44 **
45 **==============================================================================
46 */
47 typedef enum _SubscriptionState
48 {
49 SubscriptionState_NotInitialized = 0,
50 SubscriptionState_Initialized = 1,
51 SubscriptionState_Subscribed = 2,
52 SubscriptionState_Unsubscribing = 3,
53 SubscriptionState_Unsubscribed = 4
54 } SubscriptionState;
55
56 /*
57 **==============================================================================
58 **
59 ** Define SubMgrSubscription, one object represents one indication subscription
60 **
61 **==============================================================================
62 */
63 typedef struct _SubMgrSubscription
64 krisbash 1.1 {
65 /* This struct holds the same initial members as ListElem, so it conforms
66 * to the ListElem interface (for use of the ListElem API. */
67 struct _SubMgrSubscription* next;
68 struct _SubMgrSubscription* prev;
69
70 /* The original subscription request. */
71 SubscribeReq* msg;// TODO: Needed?
72
73 /* Ptrs to the two possible contexts in use by this subscription.
74 * These are needed for clean up during Post* handling. */
75 SubscriptionContext* subscribeCtx;
76
77 /* Current state of the SubscriptionContext */
78 SubscriptionState state;
79
80 /* Saved from SubscribeReq msg for use during PostIndicationMsg */
81 MI_Uint64 subscriptionID; // TODO: Not needed if keep SubscribeReq ptr here
82
83 /* Keeps filtering function and state for indication evaluation. */
84 InstanceFilter* filter;
85 krisbash 1.1
86 /* Ref count of the object */
87 volatile ptrdiff_t refcount;
88
89 /* final msg sent or not, 0 - not, 1 - sent */
90 volatile ptrdiff_t finalmsgbit;
91
92 /* unsubscribe started or not, 0 - not, 1 - started */
93 volatile ptrdiff_t unsubscribebit;
94
95 /* lock to ensure one message post a time to the subscription context */
96 RecursiveLock postlock;
97
98 }SubMgrSubscription;
99
100 typedef SubMgrSubscription* SubMgrSubscriptionPtr;
101
102
103 /*
104 **==============================================================================
105 **
106 krisbash 1.1 ** Define SubMgrSubscription linked list
107 **
108 **==============================================================================
109 */
110 typedef struct _SubscriptionList
111 {
112 ListElem* head;
113 ListElem* tail;
114 ReadWriteLock lock; /* Readwrite lock to protect subscription list */
115 size_t count; /* total number of subscription(s) */
116 MI_Boolean allcancelled; /* all subscriptions cancelled or not */
117
118 /*
119 * aggregation context or lifecycle context take the snapshot of
120 * subscriptions' list to dispatch indication
121 */
122 _Field_size_(capacity) SubMgrSubscriptionPtr* subarray;
123 /* the capacity of the subarray */
124 size_t capacity;
125
126 } SubscriptionList;
127 krisbash 1.1
128 /*
129 **==============================================================================
130 **
131 ** Master struct for handling subscription state for a class/provider. It
132 ** tracks the subscriptions is must aggregate and determines how to handle
133 ** each AggregationContext and SubscriptionContext as it completes.
134 **
135 **==============================================================================
136 */
137 typedef struct _SubscriptionManager
138 {
139 /* Ptrs to the two possible contexts in use by this subscription manager.
140 * These are needed for clean up during Post* handling. */
141 AggregationContext* aggrCtx;
142
143 /* Context used by providers to Post lifecycle indications.
144 */
145 LifecycleContext* lifecycleCtx;
146
147 /* Prointer to provider
148 krisbash 1.1 */
149 Provider* provider;
150
151 /* Linked list of aggregated subscriptions */
152 SubscriptionList subscrList;
153
154 /*
155 * lock to ensure EnableIndication/Subscribe/DisableIndication
156 * call to provider threadsafe; also in case of termination of
157 * current provider(class), make sure new subscribe request
158 * wait until provider was disabled;
159 */
160 RecursiveLock enablelock;
161
162 /*
163 * 3 code path needs to take enablelock,
164 * #1 - Subscribe request
165 * #2 - post result on aggrCtx or lifecycleCtx
166 * #3 - last subscription was cancelled
167 *
168 * #2 terminates current provider (class), which
169 krisbash 1.1 * set terminating to MI_TRUE, and cancel all active
170 * subscriptions, in the meantime, if any #1 requests
171 * would fail due to the current provider does not
172 * complete the cancellation yet; upon the last
173 * subscription being cancelled and removed, then
174 * terminating flag is set to MI_FALSE
175 *
176 */
177 MI_Boolean terminating;
178
179 /* Indicates current class is enabled or not */
180 MI_Boolean enabled;
181
182 /*
183 * The thread that invoke EnableIndication/Subscribe call to provider,
184 * Post indication on the invoke thread will result in
185 * MI_RESULT_NOT_SUPPORTED error code
186 */
187 ThreadID enableThreadID;
188 }
189 SubscriptionManager;
190 krisbash 1.1
191 /*
192 **==============================================================================
193 **
194 ** SubscriptionList Functions
195 **
196 **==============================================================================
197 */
198 void SubscriptionList_Init(
199 _Out_ SubscriptionList* self);
200
201 void SubscriptionList_Finalize(
202 _In_ _Post_invalid_ SubscriptionList* self);
203
204 void SubscriptionList_AddSubscription(
205 _Inout_ SubscriptionList* self,
206 _In_ SubMgrSubscription* subscription);
207
208 MI_Result SubscriptionList_DeleteSubscription(
209 _Inout_ SubscriptionList* self,
210 _In_ SubMgrSubscription* subscription,
211 krisbash 1.1 _In_ SubscriptionManager* mgr );
212
213 MI_Result SubscriptionList_CancelAllSubscription(
214 _Inout_ SubscriptionList* self );
215
216 MI_Result SubscriptionList_GetList(
217 _In_ const SubscriptionList* self,
218 _In_ MI_Boolean addref,
219 _Outptr_result_buffer_(*count) SubMgrSubscriptionPtr** subs,
220 _Out_ size_t* count);
221
222 void SubscriptionList_SetAllCancelled(
223 _Inout_ SubscriptionList* self,
224 _In_ MI_Boolean allcancelled);
225
226 void SubscriptionList_SetAllCancelledSafe(
227 _Inout_ SubscriptionList* self,
228 _In_ MI_Boolean allcancelled);
229
230 /*
231 **==============================================================================
232 krisbash 1.1 **
233 ** SubscriptionManager Functions
234 **
235 **==============================================================================
236 */
237 SubscriptionManager* SubMgr_New();
238
239 void SubMgr_Delete(
240 _In_ _Post_invalid_ SubscriptionManager* pMgr );
241
242 void SubMgr_Init(
243 _Inout_ SubscriptionManager* mgr,
244 _In_ Provider* provider );
245
246 void SubMgr_Finalize(
247 _In_ _Post_invalid_ SubscriptionManager* mgr);
248
249 MI_Boolean SubMgr_IsEnabled(
250 _In_ const SubscriptionManager* mgr );
251
252 void SubMgr_SetEnabled(
253 krisbash 1.1 _Inout_ SubscriptionManager* mgr,
254 _In_ MI_Boolean enabled);
255
256 MI_Boolean SubMgr_IsTerminating(
257 _In_ const SubscriptionManager* mgr );
258
259 void SubMgr_SetTerminating(
260 _Inout_ SubscriptionManager* mgr,
261 _In_ MI_Boolean terminating);
262
263 void SubMgr_SetAllCancelledSafe(
264 _Inout_ SubscriptionManager* mgr,
265 _In_ MI_Boolean allcancelled);
266
267 MI_Boolean SubMgr_IsSubListEmpty(
268 _Inout_ SubscriptionManager* mgr );
269
270 MI_Result SubMgr_CreateSubscription(
271 _Inout_ SubscriptionManager* mgr,
272 _In_ Provider* provider,
273 _In_ InteractionOpenParams* interactionParams,
274 krisbash 1.1 _Out_ SubscriptionContext** subscrContext );
275
276 MI_Result SubMgr_DeleteSubscription(
277 _Inout_ SubscriptionManager* mgr,
278 _In_ SubMgrSubscription* subscription );
279
280 MI_Result SubMgr_CancelAllSubscriptions(
281 _Inout_ SubscriptionManager* mgr,
282 _In_ MI_Result result,
283 _In_opt_ const ZChar* errorMessage,
284 _In_opt_ const MI_Instance* cimError);
285
286 SubMgrSubscription* SubMgr_GetSubscription(
287 _In_ const SubscriptionManager* mgr,
288 _In_ MI_Uint64 subscriptionID );
289
290 /* search subscription based on subctx, add refcount to subscription if found */
291 SubMgrSubscription* SubMgr_GetSubscriptionByContext(
292 _In_ const SubscriptionManager* mgr,
293 _In_ SubscriptionContext* subCtx);
294
295 krisbash 1.1 /* read subscription context list snapshot into an array */
296 MI_Result SubMgr_GetSubscriptionList(
297 _In_ const SubscriptionManager* mgr,
298 _Outptr_result_buffer_(*count) SubMgrSubscriptionPtr** subs,
299 _Out_ size_t* count);
300
301 void SubMgr_SetEnableThread(
302 _Inout_ SubscriptionManager* mgr);
303
304 MI_Boolean SubMgr_IsEnableThread(
305 _In_ const SubscriptionManager* mgr);
306
307 MI_Boolean SubMgr_CanPostIndication(
308 _In_ const SubscriptionManager* mgr);
309
310 /*
311 * Three scenarios require the enablelock,
312 * #1 - Subscribe request
313 * #2 - post result on aggrCtx or lifecycleCtx
314 * #3 - last subscription was cancelled
315 *
316 krisbash 1.1 */
317 typedef enum AcquireEnableLockOperationType
318 {
319 AcquireFromSubscribe = 0,
320 AcquireFromDisable = 1,
321 AcquireFromTerminate = 2
322 }
323 AcquireEnableLockOperationType;
324
325 MI_Boolean SubMgr_AcquireEnableLock(
326 _In_ SubscriptionManager* self,
327 _In_ AcquireEnableLockOperationType optype);
328
329 void SubMgr_ReleaseEnableLock(
330 _In_ SubscriptionManager* self);
331
332 AggregationContext* SubMgr_CreateAggrContext(
333 _In_ SubscriptionManager* self);
334
335 AggregationContext* SubMgr_RemoveAggrContext(
336 _In_ SubscriptionManager* self);
337 krisbash 1.1
338
339
340 /*
341 **==============================================================================
342 **
343 ** SubMgrSubscription Functions
344 **
345 **==============================================================================
346 */
347 SubMgrSubscription* _SubMgrSubscription_New(
348 _In_ SubscribeReq* msg,
349 CallSite cs);
350 #define SubMgrSubscription_New(msg) \
351 _SubMgrSubscription_New((msg), CALLSITE)
352
353 void _SubMgrSubscription_Addref(
354 _Inout_ SubMgrSubscription* subscription,
355 CallSite cs);
356 #define SubMgrSubscription_Addref(subscription) \
357 _SubMgrSubscription_Addref((subscription), CALLSITE)
358 krisbash 1.1
359 void _SubMgrSubscription_Release(
360 _Inout_ SubMgrSubscription* subscription,
361 CallSite cs);
362 #define SubMgrSubscription_Release(subscription) \
363 _SubMgrSubscription_Release((subscription), CALLSITE)
364
365 MI_Result SubMgrSubscription_SetState(
366 _Inout_ SubMgrSubscription* subscription,
367 _In_ SubscriptionState state );
368
369 SubscriptionTargetType SubMgrSubscription_GetSupportedTypes(
370 _In_ SubMgrSubscription* subscription );
371
372 void SubMgrSubscription_AcuquirePostLock(
373 _In_ SubMgrSubscription* self);
374
375 void SubMgrSubscription_ReleasePostLock(
376 _In_ SubMgrSubscription* self);
377
378 MI_Boolean SubMgrSubscription_ShouldCallUnsubscribe(
379 krisbash 1.1 _In_ SubMgrSubscription* self);
380
381 MI_Boolean SubMgrSubscription_ShouldSendFinalMsg(
382 _In_ SubMgrSubscription* self);
383
384 MI_Boolean SubMgrSubscription_CancelStarted(
385 _In_ SubMgrSubscription* self);
386
387 MI_Boolean SubMgrSubscription_IsQueryValid(
388 _In_ SubMgrSubscription* self,
389 _In_ const MI_ClassDecl* cd );
390
391 /*
392 **==============================================================================
393 **
394 ** MISC. Functions
395 **
396 **==============================================================================
397 */
398 /* Get unsigned int represent of current thread ID */
399 unsigned int UintThreadID();
400 krisbash 1.1
401 END_EXTERNC
402
403 #endif /* _subscription_manager_h */
404
|