xref: /xnu-8792.81.2/iokit/IOKit/IOCommandPool.h (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
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 /*
30  *
31  *	Copyright (c) 2000 Apple Computer, Inc.  All rights reserved.
32  *
33  *	HISTORY
34  *
35  *	2001-01-17	gvdl	Re-implement on IOCommandGate::commandSleep
36  *	11/13/2000	CJS	Created IOCommandPool class and implementation
37  *
38  */
39 
40 /*!
41  * @header IOCommandPool
42  * @abstract
43  * This header contains the IOCommandPool class definition.
44  */
45 
46 #ifndef _IOKIT_IO_COMMAND_POOL_H_
47 #define _IOKIT_IO_COMMAND_POOL_H_
48 
49 /*
50  * Kernel
51  */
52 
53 #if defined(KERNEL) && defined(__cplusplus)
54 
55 #include <kern/kern_types.h>
56 #include <kern/queue.h>
57 #include <IOKit/IOCommand.h>
58 #include <IOKit/IOCommandGate.h>
59 #include <IOKit/IOService.h>
60 #include <IOKit/IOWorkLoop.h>
61 #include <libkern/c++/OSPtr.h>
62 
63 /*!
64  * @class IOCommandPool
65  * @abstract Manipulates a pool of commands which inherit from IOCommand.
66  * @discussion
67  * The IOCommandPool class is used to manipulate a pool of commands which
68  * inherit from IOCommand. It includes a factory method to create a pool
69  * of a certain size. Once the factory method is invoked, the semaphore
70  * is set to zero. The caller must then put commands in the pool by creating
71  * the command (via the controller's factory method or a memory allocation)
72  * and calling the returnCommand method with the newly created command as its
73  * argument.
74  */
75 
76 class IOCommandPool : public OSObject
77 {
78 	OSDeclareDefaultStructors(IOCommandPool);
79 
80 
81 protected:
82 
83 	queue_head_t fQueueHead; /* head of the queue of elements available */
84 	UInt32 fSleepers;       /* Count of threads sleeping on this pool */
85 	OSPtr<IOCommandGate> fSerializer; /* command gate used for serializing pool access */
86 
87 /*! @struct ExpansionData
88  *   @discussion This structure will be used to expand the capablilties of the IOEventSource in the future.
89  */
90 	struct ExpansionData { };
91 
92 /*! @var reserved
93  *   Reserved for future use.  (Internal use only)  */
94 	ExpansionData *reserved;
95 
96 /*!
97  * @const kIOCommandPoolDefaultSize
98  * @abstract The default size of any command pool.
99  * @discussion
100  * kIOCommandPoolDefaultSize is the default size of any command pool.
101  * The default size was determined to be the smallest size for which
102  * a pool makes sense.
103  */
104 
105 	static const UInt32 kIOCommandPoolDefaultSize = 2;
106 
107 /*
108  * Free all of this object's outstanding resources.
109  */
110 
111 	virtual void free(void) APPLE_KEXT_OVERRIDE;
112 
113 
114 public:
115 
116 /*!
117  * @function initWithWorkLoop
118  * @abstract Primary initializer for an IOCommandPool object.
119  * @discussion Primary initializer for an IOCommandPool.
120  * Should probably use IOCommandPool::withWorkLoop() as it is easier to use.
121  * @param workLoop
122  * The workloop that this command pool should synchronize with.
123  * @result Returns true if command pool was successfully initialized.
124  */
125 	virtual bool initWithWorkLoop(IOWorkLoop *workLoop);
126 
127 /*!
128  * @function withWorkLoop
129  * @abstract Primary factory method for the IOCommandPool class
130  * @discussion
131  * The withWorkLoop method is what is known as a factory method. It creates
132  * a new instance of an IOCommandPool and returns a pointer to that object.
133  * @param inWorkLoop
134  * The workloop that this command pool should synchronize with.
135  * @result
136  * Returns a pointer to an instance of IOCommandPool if successful,
137  * otherwise NULL.
138  */
139 
140 	static OSPtr<IOCommandPool> withWorkLoop(IOWorkLoop *inWorkLoop);
141 
142 /*!
143  * @function init
144  * @abstract Should never be used, obsolete. See initWithWorkLoop.
145  */
146 	virtual bool init(IOService *inOwner,
147 	    IOWorkLoop *inWorkLoop,
148 	    UInt32 inSize = kIOCommandPoolDefaultSize);
149 
150 /*!
151  * @function withWorkLoop
152  * @abstract Should never be used, obsolete. See IOCommandPool::withWorkLoop.
153  */
154 	static OSPtr<IOCommandPool> commandPool(IOService *inOwner,
155 	    IOWorkLoop *inWorkLoop,
156 	    UInt32 inSize = kIOCommandPoolDefaultSize);
157 
158 
159 /*!
160  * @function getCommand
161  * @discussion The getCommand method is used to get a pointer to an object of type IOCommand from the pool.
162  * @param blockForCommand
163  * If the caller would like to have its thread slept until a command is
164  * available, it should pass true, else false.
165  * @result
166  * If the caller passes true in blockForCommand, getCommand guarantees that
167  * the result will be a pointer to an IOCommand object from the pool. If
168  * the caller passes false, s/he is responsible for checking whether a non-NULL
169  * pointer was returned.
170  */
171 
172 	virtual OSPtr<IOCommand> getCommand(
173 		bool blockForCommand = true);
174 
175 /*!
176  * @function returnCommand
177  * @discussion
178  * The returnCommand method is used to place an object of type IOCommand
179  * into the pool, whether it be the first time, or the 1000th time.
180  * @param command
181  * The command to place in the pool.
182  */
183 
184 	virtual void returnCommand(LIBKERN_CONSUMED IOCommand *command);
185 
186 protected:
187 
188 /*!
189  * @function gatedGetCommand
190  * @discussion
191  * The gatedGetCommand method is used to serialize the extraction of a
192  * command from the pool behind a command gate, runAction-ed by getCommand.
193  * @param command
194  * A pointer to a pointer to an IOCommand object where the returned
195  * command will be stored.
196  * @param blockForCommand
197  * A bool that indicates whether to block the request until a command
198  * becomes available.
199  * @result
200  * Returns kIOReturnNoResources if no command is available and the client
201  * doesn't wish to block until one does become available.
202  * kIOReturnSuccess if the vCommand argument is valid.
203  */
204 	virtual IOReturn gatedGetCommand(
205 		LIBKERN_RETURNS_NOT_RETAINED IOCommand **command, bool blockForCommand);
206 
207 /*!
208  * @function gatedReturnCommand
209  * @discussion
210  * The gatedReturnCommand method is used to serialize the return of a
211  * command to the pool behind a command gate, runAction-ed by returnCommand.
212  * @param command
213  * A pointer to the IOCommand object to be returned to the pool.
214  * @result
215  * Always returns kIOReturnSuccess if the vCommand argument is valid.
216  */
217 	virtual IOReturn gatedReturnCommand(IOCommand *command);
218 
219 private:
220 	OSMetaClassDeclareReservedUnused(IOCommandPool, 0);
221 	OSMetaClassDeclareReservedUnused(IOCommandPool, 1);
222 	OSMetaClassDeclareReservedUnused(IOCommandPool, 2);
223 	OSMetaClassDeclareReservedUnused(IOCommandPool, 3);
224 	OSMetaClassDeclareReservedUnused(IOCommandPool, 4);
225 	OSMetaClassDeclareReservedUnused(IOCommandPool, 5);
226 	OSMetaClassDeclareReservedUnused(IOCommandPool, 6);
227 	OSMetaClassDeclareReservedUnused(IOCommandPool, 7);
228 };
229 
230 #endif  /* defined(KERNEL) && defined(__cplusplus) */
231 
232 #endif  /* _IOKIT_IO_COMMAND_POOL_H_ */
233