xref: /xnu-8020.101.4/libkern/libkern/c++/OSObject.h (revision e7776783b89a353188416a9a346c6cdb4928faad)
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 #ifdef XNU_KERNEL_PRIVATE
308 	static void operator delete(void * mem, size_t size)
309 	__XNU_INTERNAL(OSObject_operator_delete);
310 #else
311 	static void operator delete(void * mem, size_t size);
312 #endif
313 
314 
315 // XXX: eventually we can flip this switch
316 //#ifdef LIBKERN_SMART_POINTERS
317 #if 0
318 private:
319 #else
320 public:
321 #endif
322 
323 /*!
324  * @function operator new
325  *
326  * @abstract
327  * Allocates memory for an instance of the class.
328  *
329  * @param size The number of bytes to allocate
330  *
331  * @result
332  * A pointer to block of memory if available, <code>NULL</code> otherwise.
333  */
334 #ifdef XNU_KERNEL_PRIVATE
335 	static void * operator new(size_t size)
336 	__XNU_INTERNAL(OSObject_operator_new);
337 #else
338 	static void * operator new(size_t size);
339 #endif
340 
341 public:
342 
343 /*!
344  * @function getRetainCount
345  *
346  * @abstract
347  * Returns the reference count of the object.
348  *
349  * @result
350  * The reference count of the object.
351  */
352 	virtual int getRetainCount() const APPLE_KEXT_OVERRIDE;
353 
354 
355 /*!
356  * @function retain
357  *
358  * @abstract
359  * Retains a reference to the object.
360  *
361  * @discussion
362  * This function increments the reference count of the receiver by 1.
363  * If you need to maintain a reference to an object
364  * outside the context in which you received it,
365  * you should always retain it immediately.
366  */
367 	virtual void retain() const APPLE_KEXT_OVERRIDE;
368 
369 
370 /*!
371  * @function release
372  *
373  * @abstract
374  * Releases a reference to the object,
375  * freeing it immediately if the reference count drops to zero.
376  *
377  * @discussion
378  * This function decrements the reference count of the receiver by 1.
379  * If the reference count drops to zero,
380  * the object is immediately freed using
381  * <code>@link
382  * //apple_ref/cpp/instm/OSObject/free/virtualvoid/()
383  * free@/link</code>.
384  */
385 	virtual void release() const APPLE_KEXT_OVERRIDE;
386 
387 
388 /*!
389  * @function taggedRetain
390  *
391  * @abstract
392  * Retains a reference to the object with an optional
393  * tag used for reference-tracking.
394  *
395  * @param tag      Used for tracking collection references.
396  *
397  * @discussion
398  * Kernel extensions should not use this function.
399  * It is for use by OSCollection and subclasses to track
400  * inclusion in collections.
401  *
402  * If you need to maintain a reference to an object
403  * outside the context in which you received it,
404  * you should always retain it immediately.
405  */
406 	virtual void taggedRetain(const void * tag = NULL) const APPLE_KEXT_OVERRIDE;
407 
408 
409 /*!
410  * @function taggedRelease
411  *
412  * @abstract
413  * Releases a tagged reference to an object,
414  * freeing it immediately if the reference count
415  * drops to zero.
416  *
417  * @param tag      Used for tracking collection references.
418  *
419  * @discussion
420  * Kernel extensions should not use this function.
421  * It is for use by OSCollection and subclasses to track
422  * inclusion in collections.
423  */
424 	virtual void taggedRelease(const void * tag = NULL) const APPLE_KEXT_OVERRIDE;
425 // 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
426 
427 
428 /*!
429  * @function serialize
430  *
431  * @abstract
432  * Overridden by subclasses to archive the receiver into the provided
433  * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link object.
434  *
435  * @param serializer The OSSerialize object.
436  *
437  * @result
438  * <code>true</code> if serialization succeeds, <code>false</code> if not.
439  *
440  * @discussion
441  * OSObject's implementation writes a string indicating that
442  * the class of the object receiving the function call
443  * is not serializable.
444  * Subclasses that can meaningfully encode themselves
445  * in I/O Kit-style property list XML can override this function to do so.
446  * See
447  * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link
448  * for more information.
449  */
450 	virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE;
451 
452 #ifdef XNU_KERNEL_PRIVATE
453 #if IOTRACKING
454 	void trackingAccumSize(size_t size);
455 #endif
456 
457 	bool taggedTryRetain(const void *tag) const;
458 
459 	bool iterateObjects(void * refcon, bool (*callback)(void * refcon, OSObject * object));
460 #ifdef __BLOCKS__
461 	bool iterateObjects(bool (^block)(OSObject * object));
462 #endif /* __BLOCKS__ */
463 
464 #endif /* XNU_KERNEL_PRIVATE */
465 
466 // Unused Padding
467 	OSMetaClassDeclareReservedUnused(OSObject, 0);
468 	OSMetaClassDeclareReservedUnused(OSObject, 1);
469 	OSMetaClassDeclareReservedUnused(OSObject, 2);
470 	OSMetaClassDeclareReservedUnused(OSObject, 3);
471 	OSMetaClassDeclareReservedUnused(OSObject, 4);
472 	OSMetaClassDeclareReservedUnused(OSObject, 5);
473 	OSMetaClassDeclareReservedUnused(OSObject, 6);
474 	OSMetaClassDeclareReservedUnused(OSObject, 7);
475 	OSMetaClassDeclareReservedUnused(OSObject, 8);
476 	OSMetaClassDeclareReservedUnused(OSObject, 9);
477 	OSMetaClassDeclareReservedUnused(OSObject, 10);
478 	OSMetaClassDeclareReservedUnused(OSObject, 11);
479 	OSMetaClassDeclareReservedUnused(OSObject, 12);
480 	OSMetaClassDeclareReservedUnused(OSObject, 13);
481 	OSMetaClassDeclareReservedUnused(OSObject, 14);
482 	OSMetaClassDeclareReservedUnused(OSObject, 15);
483 };
484 
485 #endif /* !_LIBKERN_OSOBJECT_H */
486