/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. HISTORY 1998-10-30 Godfrey van der Linden(gvdl) Created */ #ifndef _LIBKERN_OSOBJECT_H #define _LIBKERN_OSOBJECT_H #include #if defined(__clang__) #pragma clang diagnostic ignored "-Woverloaded-virtual" #endif class OSSymbol; class OSString; /*! * @header * * @abstract * This header declares the OSObject class, * which is the concrete root of the Libkern C++ class hierarchy. */ /*! * @class OSObject * * @abstract * OSObject is the concrete root class * of the Libkern and I/O Kit C++ class hierarchy. * * @discussion * OSObject defines the minimal functionality * required of Libkern and I/O Kit C++ classes: * tie-in to the run-time type information facility, * the dynamic allocation/initialization paradigm, * and reference counting. * While kernel extensions are free to use their own C++ classes internally, * any interaction they have with Libkern or the I/O Kit will require * classes ultimately derived from OSObject. * * Run-Time Type Information * * OSObject is derived from the abstract root class * @link //apple_ref/doc/class/OSMetaClassBase OSMetaClassBase@/link, * which declares (and defines many of) the primitives * on which the run-time type information facility is based. * A parallel inheritance hierarchy of metaclass objects * provides run-time introspection, including access to class names, * inheritance, and safe type-casting. * See @link //apple_ref/doc/class/OSMetaClass OSMetaClass@/link * for more information. * * Dynamic Allocation/Initialization * * The kernel-resident C++ runtime does not support exceptions, * so Libkern classes cannot use standard C++ object * constructors and destructors, * which use exceptions to report errors. * To support error-handling during instance creation, then, * OSObject separates object allocation from initialization. * You can create a new OSObject-derived instance * with the new operator, * but this does nothing more than allocate memory * and initialize the reference count to 1. * Following this, you must call a designated initialization function * and check its bool return value. * If the initialization fails, * you must immediately call * @link * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() * release@/link * on the instance and handle the failure in whatever way is appropriate. * Many Libkern and I/O Kit classes define static instance-creation functions * (beginning with the word "with") * to make construction a one-step process for clients. * * Reference Counting * * OSObject provides reference counting services using the * @link * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/() * retain@/link, * @link * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() * release()@/link, * @link * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int) * release(int freeWhen)@/link * and * @link * //apple_ref/cpp/instm/OSObject/free/virtualvoid/() * free@/link * functions. * The public interface to the reference counting is * @link * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/() * retain@/link, * and * @link * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() * release@/link; * @link * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int) * release(int freeWhen)@/link * is provided * for objects that have internal retain cycles. * * In general, a subclass is expected to only override * @link * //apple_ref/cpp/instm/OSObject/free/virtualvoid/() * free@/link. * It may also choose to override * @link * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int) * release(int freeWhen)@/link * if the object has a circular retain count, as noted above. * * Use Restrictions * * With very few exceptions in the I/O Kit, all Libkern-based C++ * classes, functions, and macros are unsafe * to use in a primary interrupt context. * Consult the I/O Kit documentation related to primary interrupts * for more information. * * Concurrency Protection * * The basic features of OSObject are thread-safe. * Most Libkern subclasses are not, and require locking or other protection * if instances are shared between threads. * I/O Kit driver objects are either designed for use within thread-safe contexts * or designed to inherently be thread-safe. * Always check the individual class documentation to see what * steps are necessary for concurrent use of instances. */ class OSObject : public OSMetaClassBase { OSDeclareAbstractStructors(OSObject) #if IOKITSTATS friend class IOStatistics; #endif private: /* Not to be included in headerdoc. * * @var retainCount Number of references held on this instance. */ mutable int retainCount; protected: // xx-review: seems not to be used, should we deprecate? /*! * @function release * * @abstract * Releases a reference to an object, * freeing it immediately if the reference count * drops below the specified threshold. * * @param freeWhen If decrementing the reference count makes it * >= freeWhen, the object is immediately freed. * * @discussion * If the receiver has freeWhen or fewer references * after its reference count is decremented, * it is immediately freed. * * This version of release * can be used to break certain retain cycles in object graphs. * In general, however, it should be avoided. */ virtual void release(int freeWhen) const; /*! * @function taggedRelease * * @abstract * Releases a tagged reference to an object, * freeing it immediately if the reference count * drops below the specified threshold. * * @param tag Used for tracking collection references. * @param freeWhen If decrementing the reference count makes it * >= freeWhen, the object is immediately freed. * * @discussion * Kernel extensions should not use this function. * It is for use by OSCollection and subclasses to track * inclusion in collections. * * If the receiver has freeWhen or fewer references * after its reference count is decremented, * it is immediately freed. * * This version of release * can be used to break certain retain cycles in object graphs. * In general, however, it should be avoided. */ virtual void taggedRelease(const void * tag, const int freeWhen) const; /*! * @function init * * @abstract * Initializes a newly-allocated object. * * @result * true on success, false on failure. * * @discussion * Classes derived from OSObject must override the primary init method * of their parent. * In general most implementations call * super::init() * before doing local initialisation. * If the superclass call fails then return false immediately. * If the subclass encounters a failure then it should return false. */ virtual bool init(); /*! * @function free * * @abstract * Deallocates/releases resources held by the object. * * @discussion * Classes derived from OSObject should override this function * to deallocate or release all dynamic resources held by the instance, * then call the superclass's implementation. * * Caution: *
    *
  1. You can not assume that you have completed initialization * before free is called, * so be very careful in your implementation.
  2. *
  3. OSObject's implementation performs the C++ delete * of the instance, so be sure that you call the superclass * implementation last in your implementation.
  4. *
  5. free must not fail; * all resources must be deallocated or released on completion.
  6. *
*/ virtual void free(); /*! * @function operator delete * * @abstract * Frees the memory of the object itself. * * @param mem A pointer to the object's memory. * @param size The size of the object's block of memory. * * @discussion * Never use delete on objects derived from OSObject; * use * @link * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() * release@/link * instead. */ static void operator delete(void * mem, size_t size); public: /*! * @function operator new * * @abstract * Allocates memory for an instance of the class. * * @param size The number of bytes to allocate * * @result * A pointer to block of memory if available, NULL otherwise. */ static void * operator new(size_t size); /*! * @function getRetainCount * * @abstract * Returns the reference count of the object. * * @result * The reference count of the object. */ virtual int getRetainCount() const; /*! * @function retain * * @abstract * Retains a reference to the object. * * @discussion * This function increments the reference count of the receiver by 1. * If you need to maintain a reference to an object * outside the context in which you received it, * you should always retain it immediately. */ virtual void retain() const; /*! * @function release * * @abstract * Releases a reference to the object, * freeing it immediately if the reference count drops to zero. * * @discussion * This function decrements the reference count of the receiver by 1. * If the reference count drops to zero, * the object is immediately freed using * @link * //apple_ref/cpp/instm/OSObject/free/virtualvoid/() * free@/link. */ virtual void release() const; /*! * @function taggedRetain * * @abstract * Retains a reference to the object with an optional * tag used for reference-tracking. * * @param tag Used for tracking collection references. * * @discussion * Kernel extensions should not use this function. * It is for use by OSCollection and subclasses to track * inclusion in collections. * * If you need to maintain a reference to an object * outside the context in which you received it, * you should always retain it immediately. */ virtual void taggedRetain(const void * tag = 0) const; /*! * @function taggedRelease * * @abstract * Releases a tagged reference to an object, * freeing it immediately if the reference count * drops to zero. * * @param tag Used for tracking collection references. * * @discussion * Kernel extensions should not use this function. * It is for use by OSCollection and subclasses to track * inclusion in collections. */ virtual void taggedRelease(const void * tag = 0) const; // 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 /*! * @function serialize * * @abstract * Overridden by subclasses to archive the receiver into the provided * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link object. * * @param serializer The OSSerialize object. * * @result * true if serialization succeeds, false if not. * * @discussion * OSObject's implementation writes a string indicating that * the class of the object receiving the function call * is not serializable. * Subclasses that can meaningfully encode themselves * in I/O Kit-style property list XML can override this function to do so. * See * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link * for more information. */ virtual bool serialize(OSSerialize * serializer) const; // Unused Padding OSMetaClassDeclareReservedUnused(OSObject, 0); OSMetaClassDeclareReservedUnused(OSObject, 1); OSMetaClassDeclareReservedUnused(OSObject, 2); OSMetaClassDeclareReservedUnused(OSObject, 3); OSMetaClassDeclareReservedUnused(OSObject, 4); OSMetaClassDeclareReservedUnused(OSObject, 5); OSMetaClassDeclareReservedUnused(OSObject, 6); OSMetaClassDeclareReservedUnused(OSObject, 7); OSMetaClassDeclareReservedUnused(OSObject, 8); OSMetaClassDeclareReservedUnused(OSObject, 9); OSMetaClassDeclareReservedUnused(OSObject, 10); OSMetaClassDeclareReservedUnused(OSObject, 11); OSMetaClassDeclareReservedUnused(OSObject, 12); OSMetaClassDeclareReservedUnused(OSObject, 13); OSMetaClassDeclareReservedUnused(OSObject, 14); OSMetaClassDeclareReservedUnused(OSObject, 15); }; #endif /* !_LIBKERN_OSOBJECT_H */