34ba3dd78329a77bc03144d7344cc1e6d3549337
[mirror/winof/.git] / inc / complib / cl_obj.h
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 \r
34 /*\r
35  * Abstract:\r
36  *      Declaration of basic objects and relationships.\r
37  *\r
38  * Environment:\r
39  *      All\r
40  */\r
41 \r
42 \r
43 #if !defined(__CL_OBJ_H__)\r
44 #define __CL_OBJ_H__\r
45 \r
46 #include <complib/cl_async_proc.h>\r
47 #include <complib/cl_atomic.h>\r
48 #include <complib/cl_event.h>\r
49 #include <complib/cl_qlist.h>\r
50 #include <complib/cl_qpool.h>\r
51 #include <complib/cl_spinlock.h>\r
52 \r
53 \r
54 /****h* Component Library/Object\r
55 * NAME\r
56 *       Object\r
57 *\r
58 * DESCRIPTION\r
59 *       Object describes a basic class that can be used to track accesses to an\r
60 *       object and provides automatic cleanup of an object that is dependent\r
61 *       on another object.\r
62 *\r
63 *       Dependencies between objects are described using a relationship.  A\r
64 *       child object is considered dependent on a parent object.  Destruction of\r
65 *       a parent object automatically results in the destruction of any child\r
66 *       objects associated with the parent.\r
67 *\r
68 *       The relationship between parent and child objects is many to many.\r
69 *       Parents can have multiple child objects, and a child can be dependent on\r
70 *       multiple parent objects.  In the latter case, destruction of any parent\r
71 *       object results in the destruction of the child object.\r
72 *\r
73 *       Other relationships between objects are described using references.  An\r
74 *       object that takes a reference on a second object prevents the second object\r
75 *       from being deallocated as long as the reference is held.\r
76 *\r
77 * SEE ALSO\r
78 *       Types\r
79 *               cl_destroy_type_t\r
80 *\r
81 *       Structures:\r
82 *               cl_obj_t, cl_obj_rel_t\r
83 *\r
84 *       Callbacks:\r
85 *               cl_pfn_obj_call_t\r
86 *\r
87 *       Initialization/Destruction:\r
88 *               cl_obj_mgr_create, cl_obj_mgr_destroy,\r
89 *               cl_obj_construct, cl_obj_init, cl_obj_destroy, cl_obj_deinit\r
90 *\r
91 *       Object Relationships:\r
92 *               cl_obj_ref, cl_obj_deref,\r
93 *               cl_rel_alloc, cl_rel_free, cl_obj_insert_rel, cl_obj_remove_rel\r
94 *\r
95 *       Object Manipulation:\r
96 *               cl_obj_reset\r
97 *********/\r
98 \r
99 \r
100 \r
101 /* Forward declaration. */\r
102 typedef struct _cl_obj *__p_cl_obj_t;\r
103 \r
104 \r
105 \r
106 /****s* Component Library: Object/cl_obj_mgr_t\r
107 * NAME\r
108 *       cl_obj_mgr_t\r
109 *\r
110 * DESCRIPTION\r
111 *       The global object manager.\r
112 *\r
113 *       The manager must be created before constructing any other objects, and all\r
114 *       objects must be destroyed before the object manager is destroyed.\r
115 *\r
116 *       The manager is used to maintain the list of all objects currently active\r
117 *       in the system.  It provides a pool of relationship items used to\r
118 *       describe parent-child, or dependent, relationships between two objects.\r
119 *       The manager contains an asynchronous processing thread that is used to\r
120 *       support asynchronous object destruction.\r
121 *\r
122 * SYNOPSIS\r
123 */\r
124 typedef struct _cl_obj_mgr\r
125 {\r
126         cl_qlist_t                                      obj_list;\r
127         cl_spinlock_t                           lock;\r
128 \r
129         cl_async_proc_t                         async_proc_mgr;\r
130 \r
131         cl_qpool_t                                      rel_pool;\r
132 \r
133 }       cl_obj_mgr_t;\r
134 /*\r
135 * FIELDS\r
136 *       obj_list\r
137 *               List of all object's in the system.  Object's are inserted into this\r
138 *               list when constructed and removed when freed.\r
139 *\r
140 *       lock\r
141 *               A lock used by the object manager for synchronization to the obj_list.\r
142 *\r
143 *       async_proc_mgr\r
144 *               An asynchronous processing manager used to process asynchronous\r
145 *               destruction requests.  Users wishing to synchronize the execution of\r
146 *               specific routines with object destruction may queue work requests to\r
147 *               this processing manager.\r
148 *\r
149 *       rel_pool\r
150 *               Pool of items used to describe dependent relationships.  Users may\r
151 *               obtain relationship objects from this pool when forming relationships,\r
152 *               but are not required to do so.\r
153 *\r
154 * SEE ALSO\r
155 *       Object, cl_obj_mgr_create, cl_obj_mgr_destroy,\r
156 *       cl_obj_construct, cl_obj_deinit,\r
157 *       cl_qlist_t, cl_spinlock_t, cl_async_proc_t, cl_qpool_t\r
158 *********/\r
159 \r
160 \r
161 \r
162 #ifdef __cplusplus\r
163 extern "C" {\r
164 #endif\r
165 \r
166 \r
167 \r
168 /****f* Component Library: Object/cl_obj_mgr_create\r
169 * NAME\r
170 *       cl_obj_mgr_create\r
171 *\r
172 * DESCRIPTION\r
173 *       This routine creates an object manager used to track all objects by\r
174 *       the user.  The object manager assists with debugging efforts by identifying\r
175 *       objects that are not destroyed properly.\r
176 *\r
177 * SYNOPSIS\r
178 */\r
179 CL_EXPORT cl_status_t CL_API\r
180 cl_obj_mgr_create(void);\r
181 /*\r
182 * PARAMETERS\r
183 *       None.\r
184 *\r
185 * RETURN VALUE\r
186 *       CL_SUCCESS\r
187 *               The object manager was succesfully created.\r
188 *\r
189 *       CL_INSUFFICIENT_MEMORY\r
190 *               The object manager could not be allocated.\r
191 *\r
192 * NOTES\r
193 *       This call must succeed before invoking any other object-related function.\r
194 *\r
195 * SEE ALSO\r
196 *       Object, cl_obj_mgr_destroy\r
197 *********/\r
198 \r
199 \r
200 \r
201 /****f* Component Library: Object/cl_obj_mgr_destroy\r
202 * NAME\r
203 *       cl_obj_mgr_destroy\r
204 *\r
205 * DESCRIPTION\r
206 *       This routine destroys the object manager created through cl_obj_mgr_create.\r
207 *\r
208 * SYNOPSIS\r
209 */\r
210 CL_EXPORT void CL_API\r
211 cl_obj_mgr_destroy(void);\r
212 /*\r
213 * PARAMETERS\r
214 *       None.\r
215 *\r
216 * RETURN VALUE\r
217 *       None.\r
218 *\r
219 * NOTES\r
220 *       When the object manager is destroyed, it will display information about all\r
221 *       objects that have not yet been destroyed.\r
222 *\r
223 * SEE ALSO\r
224 *       Object, cl_obj_mgr_create\r
225 *********/\r
226 \r
227 \r
228 /****d* Component Library: Object/cl_pfn_obj_call_t\r
229 * NAME\r
230 *       cl_pfn_obj_call_t\r
231 *\r
232 * DESCRIPTION\r
233 *       The cl_pfn_obj_call_t function type defines the prototype for functions\r
234 *       used to return objects to the user.\r
235 *\r
236 * SYNOPSIS\r
237 */\r
238 typedef void\r
239 (CL_API *cl_pfn_obj_call_t)(\r
240         IN                              struct _cl_obj                          *p_obj );\r
241 /*\r
242 * PARAMETERS\r
243 *       p_obj\r
244 *               [in] Pointer to a cl_obj_t.  This is the object being returned to\r
245 *               the user.\r
246 *\r
247 * RETURN VALUES\r
248 *       None.\r
249 *\r
250 * NOTES\r
251 *       This function type is provided as a prototype for functions provided\r
252 *       by users as parameters to the cl_obj_init function.\r
253 *\r
254 * SEE ALSO\r
255 *       Object, cl_obj_init, cl_obj_t\r
256 *********/\r
257 \r
258 \r
259 /****d* Component Library: Object/cl_destroy_type_t\r
260 * NAME\r
261 *       cl_destroy_type_t\r
262 *\r
263 * DESCRIPTION\r
264 *       Indicates the type of destruction to perform on an object.\r
265 *\r
266 * SYNOPSIS\r
267 */\r
268 typedef enum _cl_destroy_type\r
269 {\r
270         CL_DESTROY_ASYNC,\r
271         CL_DESTROY_SYNC\r
272 \r
273 }       cl_destroy_type_t;\r
274 /*\r
275 * VALUES\r
276 *       CL_DESTROY_ASYNC\r
277 *               Indicates that the object should be destroyed asynchronously.  Objects\r
278 *               destroyed asynchronously complete initial destruction processing, then\r
279 *               return the calling thread.  Once their reference count goes to zero,\r
280 *               they are queue onto an asynchronous thread to complete destruction\r
281 *               processing.\r
282 *\r
283 *       CL_DESTROY_SYNC\r
284 *               Indicates that the object should be destroyed synchronously.  Objects\r
285 *               destroyed synchronously wait (block) until their reference count goes\r
286 *               to zero.  Once their reference count goes to zero, destruction\r
287 *               processing is completed by the calling thread.\r
288 *\r
289 * SEE ALSO\r
290 *       Object, cl_obj_init, cl_obj_destroy, cl_obj_deinit, cl_obj_t\r
291 *********/\r
292 \r
293 \r
294 \r
295 /****s* Component Library: Object/cl_obj_t\r
296 * NAME\r
297 *       cl_obj_t\r
298 *\r
299 * DESCRIPTION\r
300 *       Object structure.\r
301 *\r
302 * SYNOPSIS\r
303 */\r
304 typedef struct _cl_obj\r
305 {\r
306         cl_pool_item_t                          pool_item;      /* Must be first. */\r
307         uint32_t                                        type;\r
308         cl_state_t                                      state;\r
309         cl_destroy_type_t                       destroy_type;\r
310 \r
311         cl_async_proc_item_t            async_item;\r
312         cl_event_t                                      event;\r
313 \r
314         cl_pfn_obj_call_t                       pfn_destroying;\r
315         cl_pfn_obj_call_t                       pfn_cleanup;\r
316         cl_pfn_obj_call_t                       pfn_free;\r
317 \r
318         cl_spinlock_t                           lock;\r
319 \r
320         cl_qlist_t                                      parent_list;\r
321         cl_qlist_t                                      child_list;\r
322 \r
323         atomic32_t                                      ref_cnt;\r
324 \r
325 }       cl_obj_t;\r
326 /*\r
327 * FIELDS\r
328 *       pool_item\r
329 *               Used to track the object with the global object manager.  We use\r
330 *               a pool item, rather than a list item, to let users store the object\r
331 *               in a pool.\r
332 *\r
333 *       type\r
334 *               Stores a user-specified object type.\r
335 *\r
336 *       state\r
337 *               Records the current state of the object, such as initialized,\r
338 *               destroying, etc.\r
339 *\r
340 *       destroy_type\r
341 *               Specifies the type of destruction, synchronous or asynchronous, to\r
342 *               perform on this object.\r
343 *\r
344 *       async_item\r
345 *               Asynchronous item used when destroying the object asynchronously.\r
346 *               This item is queued to an asynchronous thread to complete destruction\r
347 *               processing.\r
348 *\r
349 *       event\r
350 *               Event used when destroying the object synchronously.  A call to destroy\r
351 *               the object will wait on this event until the destruction has completed.\r
352 *\r
353 *       pfn_destroying\r
354 *               User-specified callback invoked to notify a user that an object has\r
355 *               been marked for destruction.  This callback is invoked directly from\r
356 *               the thread destroying the object and is used to notify a user that\r
357 *               a parent object has invoked a child object's destructor.\r
358 *\r
359 *       pfn_cleanup\r
360 *               User-specified callback invoked as an object is undergoing destruction.\r
361 *               For object's destroyed asynchronously, this callback is invoked from\r
362 *               the context of the asynchronous destruction thread.  Users may block\r
363 *               in the context of this thread; however, further destruction processing\r
364 *               will not continue until this callback returns.\r
365 *\r
366 *       pfn_free\r
367 *               User-specified callback invoked to notify a user that an object has\r
368 *               been destroyed and is ready for deallocation.  Users should either\r
369 *               call cl_obj_deinit or cl_obj_reset from within this callback.\r
370 *\r
371 *       lock\r
372 *               A lock provided by the object.\r
373 *\r
374 *       parent_list\r
375 *               A list of relationships to parent objects that an object is dependent\r
376 *               on.\r
377 *\r
378 *       child_list\r
379 *               A list of all child objects that are dependent on this object.\r
380 *               Destroying this object will result in all related objects maintained\r
381 *               in the child list also being destroyed.\r
382 *\r
383 *       ref_cnt\r
384 *               A count of the number of objects still referencing this object.\r
385 *\r
386 * SEE ALSO\r
387 *       Object, cl_obj_construct, cl_obj_init, cl_obj_destroy,\r
388 *       cl_obj_deinit, cl_pfn_obj_call_t, cl_destroy_type_t,\r
389 *       cl_pool_item_t, cl_state_t, cl_async_proc_item_t,\r
390 *       cl_event_t, cl_spinlock_t, cl_qlist_t, atomic32_t\r
391 *********/\r
392 \r
393 \r
394 \r
395 /****f* Component Library: Object/cl_obj_construct\r
396 * NAME\r
397 *       cl_obj_construct\r
398 *\r
399 * DESCRIPTION\r
400 *       This routine prepares an object for use.  The object must be successfully\r
401 *       initialized before being used.\r
402 *\r
403 * SYNOPSIS\r
404 */\r
405 CL_EXPORT void CL_API\r
406 cl_obj_construct(\r
407         IN                              cl_obj_t * const                        p_obj,\r
408         IN              const   uint32_t                                        obj_type );\r
409 /*\r
410 * PARAMETERS\r
411 *       p_obj\r
412 *               [in] A pointer to the object to construct.\r
413 *\r
414 *       obj_type\r
415 *               [in] A user-specified type associated with the object.  This type\r
416 *               is recorded by the object for debugging purposes and may be accessed\r
417 *               by the user.\r
418 *\r
419 * RETURN VALUE\r
420 *       None.\r
421 *\r
422 * NOTES\r
423 *       This call must succeed before invoking any other function on an object.\r
424 *\r
425 * SEE ALSO\r
426 *       Object, cl_obj_init, cl_obj_destroy, cl_obj_deinit.\r
427 *********/\r
428 \r
429 \r
430 /****f* Component Library: Object/cl_obj_init\r
431 * NAME\r
432 *       cl_obj_init\r
433 *\r
434 * DESCRIPTION\r
435 *       This routine initializes an object for use.  Upon the successful completion\r
436 *       of this call, the object is ready for use.\r
437 *\r
438 * SYNOPSIS\r
439 */\r
440 CL_EXPORT cl_status_t CL_API\r
441 cl_obj_init(\r
442         IN                              cl_obj_t * const                        p_obj,\r
443         IN                              cl_destroy_type_t                       destroy_type,\r
444         IN              const   cl_pfn_obj_call_t                       pfn_destroying OPTIONAL,\r
445         IN              const   cl_pfn_obj_call_t                       pfn_cleanup OPTIONAL,\r
446         IN              const   cl_pfn_obj_call_t                       pfn_free );\r
447 /*\r
448 * PARAMETERS\r
449 *       p_obj\r
450 *               [in] A pointer to the object to initialize.\r
451 *\r
452 *       destroy_type\r
453 *               [in] Specifies the destruction model used by this object.\r
454 *\r
455 *       pfn_destroying\r
456 *               [in] User-specified callback invoked to notify a user that an object has\r
457 *               been marked for destruction.  This callback is invoked directly from\r
458 *               the thread destroying the object and is used to notify a user that\r
459 *               a parent object has invoked a child object's destructor.\r
460 *\r
461 *       pfn_cleanup\r
462 *               [in] User-specified callback invoked to an object is undergoing\r
463 *               destruction.  For object's destroyed asynchronously, this callback\r
464 *               is invoked from the context of the asynchronous destruction thread.\r
465 *               Users may block in the context of this thread; however, further\r
466 *               destruction processing will not continue until this callback returns.\r
467 *\r
468 *       pfn_free\r
469 *               [in] User-specified callback invoked to notify a user that an object has\r
470 *               been destroyed and is ready for deallocation.  Users should either\r
471 *               call cl_obj_deinit or cl_obj_reset from within this callback.\r
472 *\r
473 * RETURN VALUE\r
474 *       CL_SUCCESS\r
475 *               The object was successfully initialized.\r
476 *\r
477 *       CL_INSUFFICIENT_MEMORY\r
478 *               The object could not allocate the necessary memory resources to\r
479 *               complete initialization.\r
480 *\r
481 * NOTES\r
482 *       The three destruction callbacks are used to notify the user of the progress\r
483 *       of the destruction, permitting the user to perform an additional processing.\r
484 *       Pfn_destroying is used to notify the user that the object is being\r
485 *       destroyed.  It is called after an object has removed itself from\r
486 *       relationships with its parents, but before it destroys any child objects\r
487 *       that it might have.\r
488 *\r
489 *       Pfn_cleanup is invoked after all child objects have been destroyed, and\r
490 *       there are no more references on the object itself.  For objects destroyed\r
491 *       asynchronously, pfn_cleanup is invoked from an asynchronous destruction\r
492 *       thread.\r
493 *\r
494 *       Pfn_free is called to notify the user that the destruction of the object has\r
495 *       completed.  All relationships have been removed, and all child objects have\r
496 *       been destroyed.  Relationship items (cl_obj_rel_t) that were used to\r
497 *       identify parent objects are returned to the user through the p_parent_list\r
498 *       field of the cl_obj_t structure.\r
499 *\r
500 * SEE ALSO\r
501 *       Object, cl_obj_construct, cl_obj_destroy, cl_obj_deinit,\r
502 *       cl_obj_t, cl_destroy_type_t, cl_pfn_obj_call_t,\r
503 *********/\r
504 \r
505 \r
506 /****f* Component Library: Object/cl_obj_destroy\r
507 * NAME\r
508 *       cl_obj_destroy\r
509 *\r
510 * DESCRIPTION\r
511 *       This routine destroys the specified object.\r
512 *\r
513 * SYNOPSIS\r
514 */\r
515 CL_EXPORT void CL_API\r
516 cl_obj_destroy(\r
517         IN                              cl_obj_t *                                      p_obj );\r
518 /*\r
519 * PARAMETERS\r
520 *       p_obj\r
521 *               [in] A pointer to the object to destroy.\r
522 *\r
523 * RETURN VALUE\r
524 *       None.\r
525 *\r
526 * NOTES\r
527 *       This routine starts the destruction process for the specified object.  For\r
528 *       additional information regarding destruction callbacks, see the following\r
529 *       fields in cl_obj_t and parameters in cl_obj_init: pfn_destroying,\r
530 *       pfn_cleanup, and pfn_free.\r
531 *\r
532 *       In most cases, after calling this routine, users should call cl_obj_deinit\r
533 *       from within their pfn_free callback routine.\r
534 *\r
535 * SEE ALSO\r
536 *       Object, cl_obj_construct, cl_obj_init, cl_obj_deinit,\r
537 *       cl_obj_t, cl_destroy_type_t, cl_pfn_obj_call_t\r
538 *********/\r
539 \r
540 \r
541 \r
542 /****f* Component Library: Object/cl_obj_deinit\r
543 * NAME\r
544 *       cl_obj_deinit\r
545 *\r
546 * DESCRIPTION\r
547 *       Release all resources allocated by an object.  This routine should\r
548 *       typically be called from a user's pfn_free routine.\r
549 *\r
550 * SYNOPSIS\r
551 */\r
552 CL_EXPORT void CL_API\r
553 cl_obj_deinit(\r
554         IN                              cl_obj_t * const                        p_obj );\r
555 /*\r
556 * PARAMETERS\r
557 *       p_obj\r
558 *               [in] A pointer to the object to free.\r
559 *\r
560 * RETURN VALUE\r
561 *       None.\r
562 *\r
563 * NOTES\r
564 *       This call must be invoked to release the object from the global object\r
565 *       manager.\r
566 *\r
567 * SEE ALSO\r
568 *       Object, cl_obj_construct, cl_obj_init, cl_obj_destroy, cl_obj_t\r
569 *********/\r
570 \r
571 \r
572 \r
573 /****f* Component Library: Object/cl_obj_reset\r
574 * NAME\r
575 *       cl_obj_reset\r
576 *\r
577 * DESCRIPTION\r
578 *       Reset an object's state.  This is called after cl_obj_destroy has\r
579 *       been called on a object, but before cl_obj_deinit has been invoked.\r
580 *       After an object has been reset, it is ready for re-use.\r
581 *\r
582 * SYNOPSIS\r
583 */\r
584 CL_EXPORT void CL_API\r
585 cl_obj_reset(\r
586         IN                              cl_obj_t * const                        p_obj );\r
587 /*\r
588 * PARAMETERS\r
589 *       p_obj\r
590 *               [in] A pointer to the object to reset.\r
591 *\r
592 * RETURN VALUE\r
593 *       None.\r
594 *\r
595 * NOTES\r
596 *       This routine allows an object to be initialized once, then destroyed\r
597 *       and re-used multiple times.  This permits the user to allocate and\r
598 *       maintain a pool of objects.  The objects may be reset and returned to\r
599 *       the pool, rather than freed, after being destroyed.  The objects would\r
600 *       not be freed until the pool itself was destroyed.\r
601 *\r
602 * SEE ALSO\r
603 *       Object, cl_obj_destroy, cl_obj_free, cl_obj_t\r
604 *********/\r
605 \r
606 \r
607 \r
608 /****f* Component Library: Object/cl_obj_ref\r
609 * NAME\r
610 *       cl_obj_ref\r
611 *\r
612 * DESCRIPTION\r
613 *       Increments the reference count on an object and returns the updated count.\r
614 *       This routine is thread safe, but does not result in locking the object.\r
615 *\r
616 * SYNOPSIS\r
617 */\r
618 CL_EXPORT int32_t CL_API\r
619 cl_obj_ref(\r
620         IN                              cl_obj_t * const                        p_obj );\r
621 /*\r
622 * PARAMETERS\r
623 *       p_obj\r
624 *               [in] A pointer to the object to reference.\r
625 *\r
626 * RETURN VALUE\r
627 *       The updated reference count.\r
628 *\r
629 * SEE ALSO\r
630 *       Object, cl_obj_t, cl_obj_deref\r
631 *********/\r
632 \r
633 \r
634 \r
635 /****f* Component Library: Object/cl_obj_deref\r
636 * NAME\r
637 *       cl_obj_deref\r
638 *\r
639 * DESCRIPTION\r
640 *       Decrements the reference count on an object and returns the updated count.\r
641 *       This routine is thread safe, but results in locking the object.\r
642 *\r
643 * SYNOPSIS\r
644 */\r
645 CL_EXPORT int32_t CL_API\r
646 cl_obj_deref(\r
647         IN                              cl_obj_t * const                        p_obj );\r
648 /*\r
649 * PARAMETERS\r
650 *       p_obj\r
651 *               [in] A pointer to the object to dereference.\r
652 *\r
653 * RETURN VALUE\r
654 *       The updated reference count.\r
655 *\r
656 * SEE ALSO\r
657 *       Object, cl_obj_t, cl_obj_ref\r
658 *********/\r
659 \r
660 \r
661 /****f* Component Library: Object/cl_obj_type\r
662 * NAME\r
663 *       cl_obj_type\r
664 *\r
665 * DESCRIPTION\r
666 *       Returns the type of an object.\r
667 *\r
668 * SYNOPSIS\r
669 */\r
670 CL_INLINE uint32_t CL_API\r
671 cl_obj_type(\r
672         IN                              cl_obj_t * const                        p_obj )\r
673 {\r
674         return p_obj->type;\r
675 }\r
676 /*\r
677 * PARAMETERS\r
678 *       p_obj\r
679 *               [in] A pointer to the object whose type to return.\r
680 *\r
681 * RETURN VALUE\r
682 *       The type of the object, as specified in the call to cl_obj_init.\r
683 *\r
684 * SEE ALSO\r
685 *       Object, cl_obj_t, cl_obj_init\r
686 *********/\r
687 \r
688 \r
689 /****f* Component Library: Object/cl_obj_lock\r
690 * NAME\r
691 *       cl_obj_lock\r
692 *\r
693 * DESCRIPTION\r
694 *       Acquires an object's lock.\r
695 *\r
696 * SYNOPSIS\r
697 */\r
698 CL_INLINE void CL_API\r
699 cl_obj_lock(\r
700         IN                              cl_obj_t * const                        p_obj )\r
701 {\r
702         CL_ASSERT( p_obj->state == CL_INITIALIZED ||\r
703                 p_obj->state == CL_DESTROYING );\r
704         cl_spinlock_acquire( &p_obj->lock );\r
705 }\r
706 /*\r
707 * PARAMETERS\r
708 *       p_obj\r
709 *               [in] A pointer to the object whose lock to acquire.\r
710 *\r
711 * RETURN VALUE\r
712 *       This function does not return a value.\r
713 *\r
714 * SEE ALSO\r
715 *       Object, cl_obj_t, cl_obj_unlock\r
716 *********/\r
717 \r
718 \r
719 /****f* Component Library: Object/cl_obj_unlock\r
720 * NAME\r
721 *       cl_obj_unlock\r
722 *\r
723 * DESCRIPTION\r
724 *       Releases an object's lock previously acquired by a call to cl_obj_lock.\r
725 *\r
726 * SYNOPSIS\r
727 */\r
728 CL_INLINE void CL_API\r
729 cl_obj_unlock(\r
730         IN                              cl_obj_t * const                        p_obj )\r
731 {\r
732         CL_ASSERT( p_obj->state == CL_INITIALIZED ||\r
733                 p_obj->state == CL_DESTROYING );\r
734         cl_spinlock_release( &p_obj->lock );\r
735 }\r
736 /*\r
737 * PARAMETERS\r
738 *       p_obj\r
739 *               [in] A pointer to the object whose lock to release.\r
740 *\r
741 * RETURN VALUE\r
742 *       This function does not return a value.\r
743 *\r
744 * SEE ALSO\r
745 *       Object, cl_obj_t, cl_obj_lock\r
746 *********/\r
747 \r
748 \r
749 /****s* Component Library: Object/cl_obj_rel_t\r
750 * NAME\r
751 *       cl_obj_rel_t\r
752 *\r
753 * DESCRIPTION\r
754 *       Identifies a dependent relationship between two objects.\r
755 *\r
756 * SYNOPSIS\r
757 */\r
758 typedef struct _cl_obj_rel\r
759 {\r
760         cl_pool_item_t                          pool_item;              /* Must be first. */\r
761         struct _cl_obj                          *p_parent_obj;\r
762 \r
763         cl_list_item_t                          list_item;\r
764         struct _cl_obj                          *p_child_obj;\r
765 \r
766 }       cl_obj_rel_t;\r
767 /*\r
768 * FIELDS\r
769 *       pool_item\r
770 *               An item used to store the relationship in a free pool maintained\r
771 *               by the object manager.  This field is also used by the parent object\r
772 *               to store the relationship in its child_list.\r
773 *\r
774 *       p_parent_obj\r
775 *               A reference to the parent object for the relationship.\r
776 *\r
777 *       list_item\r
778 *               This field is used by the child object to store the relationship in\r
779 *               its parent_list.\r
780 *\r
781 *       p_child_obj\r
782 *               A reference to the child object for the relationship.\r
783 *\r
784 * NOTES\r
785 *       This structure is used to define all dependent relationships.  Dependent\r
786 *       relationships are those where the destruction of a parent object result in\r
787 *       the destruction of child objects.  For other types of relationships, simple\r
788 *       references between objects may be used.\r
789 *\r
790 *       Relationship items are stored in lists maintained by both the parent\r
791 *       and child objects.  References to both objects exist while the\r
792 *       relationship is maintained.  Typically, relationships are defined by\r
793 *       the user by calling cl_obj_insert_rel, but are destroyed automatically\r
794 *       via an object's destruction process.\r
795 *\r
796 * SEE ALSO\r
797 *       Object, cl_rel_alloc, cl_rel_free, cl_obj_insert_rel, cl_obj_remove_rel,\r
798 *       cl_obj_destroy\r
799 *********/\r
800 \r
801 \r
802 \r
803 /****f* Component Library: Object/cl_rel_alloc\r
804 * NAME\r
805 *       cl_rel_alloc\r
806 *\r
807 * DESCRIPTION\r
808 *       Retrieves an object relationship item from the object manager.\r
809 *\r
810 * SYNOPSIS\r
811 */\r
812 CL_EXPORT cl_obj_rel_t* CL_API\r
813 cl_rel_alloc(void);\r
814 /*\r
815 * PARAMETERS\r
816 *       None.\r
817 *\r
818 * RETURN VALUE\r
819 *       A reference to an allocated relationship object, or NULL if no relationship\r
820 *       object could be allocated.\r
821 *\r
822 * NOTES\r
823 *       This routine retrieves a cl_obj_rel_t structure from a pool maintained\r
824 *       by the object manager.  The pool automatically grows as needed.\r
825 *\r
826 *       Relationship items are used to describe a dependent relationship between\r
827 *       a parent and child object.  In cases where a child has a fixed number of\r
828 *       relationships, the user may be able to allocate and manage the cl_obj_rel_t\r
829 *       structures more efficiently than obtaining the structures through this call.\r
830 *\r
831 * SEE ALSO\r
832 *       Object, cl_rel_free, cl_obj_insert_rel, cl_obj_remove_rel, cl_obj_destroy\r
833 *********/\r
834 \r
835 \r
836 \r
837 /****f* Component Library: Object/cl_rel_free\r
838 * NAME\r
839 *       cl_rel_free\r
840 *\r
841 * DESCRIPTION\r
842 *       Return a relationship object to the global object manager.\r
843 *\r
844 * SYNOPSIS\r
845 */\r
846 CL_EXPORT void CL_API\r
847 cl_rel_free(\r
848         IN                              cl_obj_rel_t * const            p_rel );\r
849 /*\r
850 * PARAMETERS\r
851 *       p_rel\r
852 *               [in] A reference to the relationship item to free.\r
853 *\r
854 * RETURN VALUE\r
855 *       None.\r
856 *\r
857 * NOTES\r
858 *       Relationship items must not be freed until both the parent and child\r
859 *       object have removed their references to one another.  Relationship items\r
860 *       may be freed after calling cl_obj_remove_rel or after the associated\r
861 *       child object's free callback has been invoked.  In the latter case, the\r
862 *       invalid relationship items are referenced by the child object's parent_list.\r
863 *\r
864 * SEE ALSO\r
865 *       Object, cl_rel_alloc, cl_obj_insert_rel, cl_obj_remove_rel, cl_obj_destroy\r
866 *********/\r
867 \r
868 \r
869 \r
870 /****f* Component Library: Object/cl_obj_insert_rel\r
871 * NAME\r
872 *       cl_obj_insert_rel\r
873 *\r
874 * DESCRIPTION\r
875 *       Forms a relationship between two objects, with the existence of the child\r
876 *       object dependent on the parent.\r
877 *\r
878 * SYNOPSIS\r
879 */\r
880 CL_EXPORT void CL_API\r
881 cl_obj_insert_rel(\r
882         IN                              cl_obj_rel_t * const            p_rel,\r
883         IN                              cl_obj_t * const                        p_parent_obj,\r
884         IN                              cl_obj_t * const                        p_child_obj );\r
885 /*\r
886 * PARAMETERS\r
887 *       p_rel\r
888 *               [in] A reference to an unused relationship item.\r
889 *\r
890 *       p_parent_obj\r
891 *               [in] A reference to the parent object.\r
892 *\r
893 *       p_child_obj\r
894 *               [in] A reference to the child object.\r
895 *\r
896 * RETURN VALUE\r
897 *       None.\r
898 *\r
899 * NOTES\r
900 *       This call inserts a relationship between the parent and child object.\r
901 *       The relationship allows for the automatic destruction of the child object\r
902 *       if the parent is destroyed.\r
903 *\r
904 *       A given object can have multiple parent and child objects, but the\r
905 *       relationships must form into an object tree.  That is, there cannot be any\r
906 *       cycles formed through the parent-child relationships.  (For example, an\r
907 *       object cannot be both the parent and a child of a second object.)\r
908 *\r
909 * SEE ALSO\r
910 *       Object, cl_rel_alloc, cl_rel_free, cl_obj_remove_rel, cl_obj_destroy\r
911 *********/\r
912 \r
913 \r
914 \r
915 /****f* Component Library: Object/cl_obj_insert_rel_parent_locked\r
916 * NAME\r
917 *       cl_obj_insert_rel_parent_locked\r
918 *\r
919 * DESCRIPTION\r
920 *       Forms a relationship between two objects, with the existence of the child\r
921 *       object dependent on the parent.  The parent's object lock is held.\r
922 *\r
923 * SYNOPSIS\r
924 */\r
925 CL_EXPORT void CL_API\r
926 cl_obj_insert_rel_parent_locked(\r
927         IN                              cl_obj_rel_t * const            p_rel,\r
928         IN                              cl_obj_t * const                        p_parent_obj,\r
929         IN                              cl_obj_t * const                        p_child_obj );\r
930 /*\r
931 * PARAMETERS\r
932 *       p_rel\r
933 *               [in] A reference to an unused relationship item.\r
934 *\r
935 *       p_parent_obj\r
936 *               [in] A reference to the parent object.\r
937 *\r
938 *       p_child_obj\r
939 *               [in] A reference to the child object.\r
940 *\r
941 * RETURN VALUE\r
942 *       None.\r
943 *\r
944 * NOTES\r
945 *       This call inserts a relationship between the parent and child object.\r
946 *       The relationship allows for the automatic destruction of the child object\r
947 *       if the parent is destroyed.\r
948 *\r
949 *       A given object can have multiple parent and child objects, but the\r
950 *       relationships must form into an object tree.  That is, there cannot be any\r
951 *       cycles formed through the parent-child relationships.  (For example, an\r
952 *       object cannot be both the parent and a child of a second object.)\r
953 *\r
954 *       This call requires the caller to already hold the parent object's lock.\r
955 *\r
956 * SEE ALSO\r
957 *       Object, cl_rel_alloc, cl_rel_free, cl_obj_remove_rel, cl_obj_destroy\r
958 *********/\r
959 \r
960 \r
961 \r
962 /****f* Component Library: Object/cl_obj_remove_rel\r
963 * NAME\r
964 *       cl_obj_remove_rel\r
965 *\r
966 * DESCRIPTION\r
967 *       Manually removes a relationship between two objects.\r
968 *\r
969 * SYNOPSIS\r
970 */\r
971 CL_EXPORT void CL_API\r
972 cl_obj_remove_rel(\r
973         IN                              cl_obj_rel_t * const            p_rel );\r
974 /*\r
975 * PARAMETERS\r
976 *       p_rel\r
977 *               [in] A reference to the relationship to remove.\r
978 *\r
979 * RETURN VALUE\r
980 *       None.\r
981 *\r
982 * NOTES\r
983 *       This routine permits a user to manually remove a dependent relationship\r
984 *       between two objects.  When removing a relationship using this call, the\r
985 *       user must ensure that objects referenced by the relationship are not\r
986 *       destroyed, either directly or indirectly via a parent.\r
987 *\r
988 * SEE ALSO\r
989 *       Object, cl_rel_alloc, cl_rel_free, cl_obj_insert_rel, cl_obj_destroy\r
990 *********/\r
991 \r
992 \r
993 #ifdef __cplusplus\r
994 }\r
995 #endif\r
996 \r
997 \r
998 #endif /* __CL_OBJ_H__ */\r