xref: /xnu-11417.101.15/libkern/libkern/c++/OSObject.h (revision e3723e1f17661b24996789d8afc084c0c3303b26)
1 /*
2  * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  *  Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
30  *  HISTORY
31  *   1998-10-30  Godfrey van der Linden(gvdl)
32  *   Created
33  */
34 #ifndef _LIBKERN_OSOBJECT_H
35 #define _LIBKERN_OSOBJECT_H
36 
37 #include <libkern/c++/OSMetaClass.h>
38 #include <libkern/c++/OSPtr.h>
39 #include <IOKit/IORPC.h>
40 #include <DriverKit/OSObject.h>
41 
42 #if defined(__clang__)
43 #pragma clang diagnostic ignored "-Woverloaded-virtual"
44 #endif
45 
46 class OSSymbol;
47 class OSString;
48 class OSObject;
49 
50 typedef OSObject* OSObjectPtr;
51 
52 
53 /*!
54  * @header
55  *
56  * @abstract
57  * This header declares the OSObject class,
58  * which is the concrete root of the Libkern C++ class hierarchy.
59  */
60 
61 
62 /*!
63  * @class OSObject
64  *
65  * @abstract
66  * OSObject is the concrete root class
67  * of the Libkern and I/O Kit C++ class hierarchy.
68  *
69  * @discussion
70  * OSObject defines the minimal functionality
71  * required of Libkern and I/O Kit C++ classes:
72  * tie-in to the run-time type information facility,
73  * the dynamic allocation/initialization paradigm,
74  * and reference counting.
75  * While kernel extensions are free to use their own C++ classes internally,
76  * any interaction they have with Libkern or the I/O Kit will require
77  * classes ultimately derived from OSObject.
78  *
79  * <b>Run-Time Type Information</b>
80  *
81  * OSObject is derived from the abstract root class
82  * @link //apple_ref/doc/class/OSMetaClassBase OSMetaClassBase@/link,
83  * which declares (and defines many of) the primitives
84  * on which the run-time type information facility is based.
85  * A parallel inheritance hierarchy of metaclass objects
86  * provides run-time introspection, including access to class names,
87  * inheritance, and safe type-casting.
88  * See @link //apple_ref/doc/class/OSMetaClass OSMetaClass@/link
89  * for more information.
90  *
91  * <b>Dynamic Allocation/Initialization</b>
92  *
93  * The kernel-resident C++ runtime does not support exceptions,
94  * so Libkern classes cannot use standard C++ object
95  * constructors and destructors,
96  * which use exceptions to report errors.
97  * To support error-handling during instance creation, then,
98  * OSObject separates object allocation from initialization.
99  * You can create a new OSObject-derived instance
100  * with the <code>new</code> operator,
101  * but this does nothing more than allocate memory
102  * and initialize the reference count to 1.
103  * Following this, you must call a designated initialization function
104  * and check its <code>bool</code> return value.
105  * If the initialization fails,
106  * you must immediately call
107  * <code>@link
108  * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
109  * release@/link</code>
110  * on the instance and handle the failure in whatever way is appropriate.
111  * Many Libkern and I/O Kit classes define static instance-creation functions
112  * (beginning with the word "with")
113  * to make construction a one-step process for clients.
114  *
115  * <b>Reference Counting</b>
116  *
117  * OSObject provides reference counting services using the
118  * <code>@link
119  * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
120  * retain@/link</code>,
121  * <code>@link
122  * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
123  * release()@/link</code>,
124  * <code>@link
125  * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int)
126  * release(int freeWhen)@/link</code>
127  * and
128  *<code> @link
129  * //apple_ref/cpp/instm/OSObject/free/virtualvoid/()
130  * free@/link</code>
131  * functions.
132  * The public interface to the reference counting is
133  * <code>@link
134  * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
135  * retain@/link</code>,
136  * and
137  * <code>@link
138  * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
139  * release@/link</code>;
140  * <code>@link
141  * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int)
142  * release(int freeWhen)@/link</code>
143  * is provided
144  * for objects that have internal retain cycles.
145  *
146  * In general, a subclass is expected to only override
147  * <code>@link
148  * //apple_ref/cpp/instm/OSObject/free/virtualvoid/()
149  * free@/link</code>.
150  * It may also choose to override
151  * <code>@link
152  * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int)
153  * release(int freeWhen)@/link</code>
154  * if the object has a circular retain count, as noted above.
155  *
156  * <b>Use Restrictions</b>
157  *
158  * With very few exceptions in the I/O Kit, all Libkern-based C++
159  * classes, functions, and macros are <b>unsafe</b>
160  * to use in a primary interrupt context.
161  * Consult the I/O Kit documentation related to primary interrupts
162  * for more information.
163  *
164  * <b>Concurrency Protection</b>
165  *
166  * The basic features of OSObject are thread-safe.
167  * Most Libkern subclasses are not, and require locking or other protection
168  * if instances are shared between threads.
169  * I/O Kit driver objects are either designed for use within thread-safe contexts
170  * or designed to inherently be thread-safe.
171  * Always check the individual class documentation to see what
172  * steps are necessary for concurrent use of instances.
173  */
174 class OSObject : public OSMetaClassBase
175 {
176 	OSDeclareAbstractStructorsWithDispatchAndNoOperators(OSObject);
177 
178 #if IOKITSTATS
179 	friend class IOStatistics;
180 #endif
181 
182 private:
183 /* Not to be included in headerdoc.
184  *
185  * @var retainCount Number of references held on this instance.
186  */
187 	mutable int retainCount;
188 
189 protected:
190 
191 // xx-review: seems not to be used, should we deprecate?
192 
193 /*!
194  * @function release
195  *
196  * @abstract
197  * Releases a reference to an object,
198  * freeing it immediately if the reference count
199  * drops below the specified threshold.
200  *
201  * @param freeWhen If decrementing the reference count makes it
202  *                 < <code>freeWhen</code>, the object is immediately freed.
203  *
204  * @discussion
205  * If the receiver has fewer than <code>freeWhen</code> references
206  * after its reference count is decremented,
207  * it is immediately freed.
208  *
209  * This version of <code>release</code>
210  * can be used to break certain retain cycles in object graphs.
211  * In general, however, it should be avoided.
212  */
213 	virtual void release(int freeWhen) const APPLE_KEXT_OVERRIDE;
214 
215 /*!
216  * @function taggedRelease
217  *
218  * @abstract
219  * Releases a tagged reference to an object,
220  * freeing it immediately if the reference count
221  * drops below the specified threshold.
222  *
223  * @param tag      Used for tracking collection references.
224  * @param freeWhen If decrementing the reference count makes it
225  *                 < <code>freeWhen</code>, the object is immediately freed.
226  *
227  * @discussion
228  * Kernel extensions should not use this function.
229  * It is for use by OSCollection and subclasses to track
230  * inclusion in collections.
231  *
232  * If the receiver has fewer than <code>freeWhen</code> references
233  * after its reference count is decremented,
234  * it is immediately freed.
235  *
236  * This version of <code>release</code>
237  * can be used to break certain retain cycles in object graphs.
238  * In general, however, it should be avoided.
239  */
240 	virtual void taggedRelease(const void * tag, const int freeWhen) const APPLE_KEXT_OVERRIDE;
241 
242 
243 /*!
244  * @function init
245  *
246  * @abstract
247  * Initializes a newly-allocated object.
248  *
249  * @result
250  * <code>true</code> on success, <code>false</code> on failure.
251  *
252  * @discussion
253  * Classes derived from OSObject must override the primary init method
254  * of their parent.
255  * In general most implementations call
256  * <code><i>super</i>::init()</code>
257  * before doing local initialisation.
258  * If the superclass call fails then return <code>false</code> immediately.
259  * If the subclass encounters a failure then it should return <code>false</code>.
260  */
261 	virtual bool init();
262 
263 
264 /*!
265  * @function free
266  *
267  * @abstract
268  * Deallocates/releases resources held by the object.
269  *
270  * @discussion
271  * Classes derived from OSObject should override this function
272  * to deallocate or release all dynamic resources held by the instance,
273  * then call the superclass's implementation.
274  *
275  * <b>Caution:</b>
276  * <ol>
277  * <li>You can not assume that you have completed initialization
278  *     before <code>free</code> is called,
279  *     so be very careful in your implementation.</li>
280  * <li>OSObject's implementation performs the C++ <code>delete</code>
281  *     of the instance, so be sure that you call the superclass
282  *     implementation <i>last</i> in your implementation.</li>
283  * <li><code>free</code> must not fail;
284  *     all resources must be deallocated or released on completion.</li>
285  * </ol>
286  */
287 	virtual void free();
288 
289 
290 /*!
291  * @function operator delete
292  *
293  * @abstract
294  * Frees the memory of the object itself.
295  *
296  * @param mem   A pointer to the object's memory.
297  * @param size  The size of the object's block of memory.
298  *
299  * @discussion
300  * Never use <code>delete</code> on objects derived from OSObject;
301  * use
302  * <code>@link
303  * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
304  * release@/link</code>
305  * instead.
306  */
307 	static void operator delete(void * mem, size_t size);
308 
309 
310 // XXX: eventually we can flip this switch
311 //#ifdef LIBKERN_SMART_POINTERS
312 #if 0
313 private:
314 #else
315 public:
316 #endif
317 
318 /*!
319  * @function operator new
320  *
321  * @abstract
322  * Allocates memory for an instance of the class.
323  *
324  * @param size The number of bytes to allocate
325  *
326  * @result
327  * A pointer to block of memory if available, <code>NULL</code> otherwise.
328  */
329 	static void * operator new(size_t size);
330 
331 public:
332 
333 /*!
334  * @function getRetainCount
335  *
336  * @abstract
337  * Returns the reference count of the object.
338  *
339  * @result
340  * The reference count of the object.
341  */
342 	virtual int getRetainCount() const APPLE_KEXT_OVERRIDE;
343 
344 
345 /*!
346  * @function retain
347  *
348  * @abstract
349  * Retains a reference to the object.
350  *
351  * @discussion
352  * This function increments the reference count of the receiver by 1.
353  * If you need to maintain a reference to an object
354  * outside the context in which you received it,
355  * you should always retain it immediately.
356  */
357 	virtual void retain() const APPLE_KEXT_OVERRIDE;
358 
359 
360 /*!
361  * @function release
362  *
363  * @abstract
364  * Releases a reference to the object,
365  * freeing it immediately if the reference count drops to zero.
366  *
367  * @discussion
368  * This function decrements the reference count of the receiver by 1.
369  * If the reference count drops to zero,
370  * the object is immediately freed using
371  * <code>@link
372  * //apple_ref/cpp/instm/OSObject/free/virtualvoid/()
373  * free@/link</code>.
374  */
375 	virtual void release() const APPLE_KEXT_OVERRIDE;
376 
377 
378 /*!
379  * @function taggedRetain
380  *
381  * @abstract
382  * Retains a reference to the object with an optional
383  * tag used for reference-tracking.
384  *
385  * @param tag      Used for tracking collection references.
386  *
387  * @discussion
388  * Kernel extensions should not use this function.
389  * It is for use by OSCollection and subclasses to track
390  * inclusion in collections.
391  *
392  * If you need to maintain a reference to an object
393  * outside the context in which you received it,
394  * you should always retain it immediately.
395  */
396 	virtual void taggedRetain(const void * tag = NULL) const APPLE_KEXT_OVERRIDE;
397 
398 
399 /*!
400  * @function taggedRelease
401  *
402  * @abstract
403  * Releases a tagged reference to an object,
404  * freeing it immediately if the reference count
405  * drops to zero.
406  *
407  * @param tag      Used for tracking collection references.
408  *
409  * @discussion
410  * Kernel extensions should not use this function.
411  * It is for use by OSCollection and subclasses to track
412  * inclusion in collections.
413  */
414 	virtual void taggedRelease(const void * tag = NULL) const APPLE_KEXT_OVERRIDE;
415 // xx-review: used to say, "Remove a reference on this object with this tag, if an attempt is made to remove a reference that isn't associated with this tag the kernel will panic immediately", but I don't see that in the implementation
416 
417 
418 /*!
419  * @function serialize
420  *
421  * @abstract
422  * Overridden by subclasses to archive the receiver into the provided
423  * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link object.
424  *
425  * @param serializer The OSSerialize object.
426  *
427  * @result
428  * <code>true</code> if serialization succeeds, <code>false</code> if not.
429  *
430  * @discussion
431  * OSObject's implementation writes a string indicating that
432  * the class of the object receiving the function call
433  * is not serializable.
434  * Subclasses that can meaningfully encode themselves
435  * in I/O Kit-style property list XML can override this function to do so.
436  * See
437  * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link
438  * for more information.
439  */
440 	virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE;
441 
442 #ifdef XNU_KERNEL_PRIVATE
443 #if IOTRACKING
444 	void trackingAccumSize(size_t size);
445 #endif
446 
447 	bool taggedTryRetain(const void *tag) const;
448 
449 	bool iterateObjects(void * refcon, bool (*callback)(void * refcon, OSObject * object));
450 #ifdef __BLOCKS__
451 	bool iterateObjects(bool (^block)(OSObject * object));
452 #endif /* __BLOCKS__ */
453 
454 #endif /* XNU_KERNEL_PRIVATE */
455 
456 // Unused Padding
457 	OSMetaClassDeclareReservedUnused(OSObject, 0);
458 	OSMetaClassDeclareReservedUnused(OSObject, 1);
459 	OSMetaClassDeclareReservedUnused(OSObject, 2);
460 	OSMetaClassDeclareReservedUnused(OSObject, 3);
461 	OSMetaClassDeclareReservedUnused(OSObject, 4);
462 	OSMetaClassDeclareReservedUnused(OSObject, 5);
463 	OSMetaClassDeclareReservedUnused(OSObject, 6);
464 	OSMetaClassDeclareReservedUnused(OSObject, 7);
465 	OSMetaClassDeclareReservedUnused(OSObject, 8);
466 	OSMetaClassDeclareReservedUnused(OSObject, 9);
467 	OSMetaClassDeclareReservedUnused(OSObject, 10);
468 	OSMetaClassDeclareReservedUnused(OSObject, 11);
469 	OSMetaClassDeclareReservedUnused(OSObject, 12);
470 	OSMetaClassDeclareReservedUnused(OSObject, 13);
471 	OSMetaClassDeclareReservedUnused(OSObject, 14);
472 	OSMetaClassDeclareReservedUnused(OSObject, 15);
473 };
474 
475 #endif /* !_LIBKERN_OSOBJECT_H */
476