]> git.saurik.com Git - apple/xnu.git/blob - iokit/IOKit/IOEventSource.h
xnu-4903.221.2.tar.gz
[apple/xnu.git] / iokit / IOKit / IOEventSource.h
1 /*
2 * Copyright (c) 1998-2000, 2009 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-7-13 Godfrey van der Linden(gvdl)
32 Created.
33 1998-10-30 Godfrey van der Linden(gvdl)
34 Converted to C++
35 */
36 #ifndef _IOKIT_IOEVENTSOURCE_H
37 #define _IOKIT_IOEVENTSOURCE_H
38
39 #include <sys/cdefs.h>
40
41 #include <libkern/c++/OSObject.h>
42
43 #include <IOKit/IOLib.h>
44 #include <IOKit/system.h>
45 #include <IOKit/IOWorkLoop.h>
46
47 #if IOKITSTATS
48 #include <IOKit/IOStatisticsPrivate.h>
49 #endif
50
51 __BEGIN_DECLS
52 #include <mach/clock_types.h>
53 #include <kern/clock.h>
54 __END_DECLS
55
56 /*!
57 @class IOEventSource : public OSObject
58 @abstract Abstract class for all work-loop event sources.
59 @discussion The IOEventSource declares the abstract super class that all
60 event sources must inherit from if an IOWorkLoop is to receive events from them.
61 <br><br>
62 An event source can represent any event that should cause the work-loop of a
63 device to wake up and perform work. Two examples of event sources are the
64 IOInterruptEventSource which delivers interrupt notifications and IOCommandGate
65 which delivers command requests.
66 <br><br>
67 A kernel module can always use the work-loop model for serialising access to
68 anything at all. The IOEventSource is used for communicating events to the
69 work-loop, and the chain of event sources should be used to walk the possible
70 event sources and demultipex them. Note a particular instance of an event
71 source may only be a member of 1 linked list chain. If you need to move it
72 between chains than make sure it is removed from the original chain before
73 attempting to move it.
74 <br><br>
75 The IOEventSource makes no attempt to maintain the consistency of its internal data across multi-threading. It is assumed that the user of these basic tools will protect the data that these objects represent in some sort of device wide instance lock. For example the IOWorkLoop maintains the event chain by using an IOCommandGate and thus single threading access to its state.
76 <br><br>
77 All subclasses of IOEventSource that wish to perform work on the work-loop thread are expected to implement the checkForWork() member function. As of Mac OS X, 10.7 (Darwin 11), checkForWork is no longer pure virtual, and should not be overridden if there is no work to be done.
78
79 <br><br>
80 checkForWork() is the key method in this class. It is called by some work-loop when convienient and is expected to evaluate its internal state and determine if an event has occurred since the last call. In the case of an event having occurred then the instance defined target(owner)/action will be called. The action is stored as an ordinary C function pointer but the first parameter is always the owner. This means that a C++ member function can be used as an action function though this depends on the ABI.
81 <br><br>
82 Although the eventChainNext variable contains a reference to the next event source in the chain this reference is not retained. The list 'owner' i.e. the client that creates the event, not the work-loop, is expected to retain the source.
83 */
84 class IOEventSource : public OSObject
85 {
86 OSDeclareAbstractStructors(IOEventSource)
87 friend class IOWorkLoop;
88 #if IOKITSTATS
89 friend class IOStatistics;
90 #endif
91
92 public:
93 /*!
94 @typedef Action
95 @discussion Placeholder type for C++ function overloading discrimination.
96 As the all event sources require an action and it has to be stored somewhere
97 and be of some type, this is that type.
98 @param owner
99 Target of the function, can be used as a refcon. The owner is set
100 during initialisation. Note if a C++ function was specified this parameter
101 is implicitly the first paramter in the target member function's parameter list.
102 */
103 typedef void (*Action)(OSObject *owner, ...);
104
105 /*! @defined IOEventSourceAction
106 @discussion Backward compatibilty define for the old non-class scoped type definition. See $link IOEventSource::Action */
107 #define IOEventSourceAction IOEventSource::Action
108
109 #ifdef __BLOCKS__
110 typedef IOReturn (^ActionBlock)();
111 #endif /* __BLOCKS__ */
112
113 protected:
114 /*! @var eventChainNext
115 The next event source in the event chain. nil at end of chain. */
116 IOEventSource *eventChainNext;
117
118 /*! @var owner The owner object called when an event has been delivered. */
119 OSObject *owner;
120
121 /*! @var action
122 The action method called when an event has been delivered */
123
124 #if XNU_KERNEL_PRIVATE
125 union { Action action; ActionBlock actionBlock; };
126 #else /* XNU_KERNEL_PRIVATE */
127 Action action;
128 #endif /* !XNU_KERNEL_PRIVATE */
129
130 /*! @var enabled
131 Is this event source enabled to deliver requests to the work-loop. */
132 bool enabled;
133
134 #if XNU_KERNEL_PRIVATE
135 enum
136 {
137 kPassive = 0x0001,
138 kActive = 0x0002,
139 kActionBlock = 0x0004,
140 kSubClass0 = 0x0008,
141 };
142 uint8_t eventSourceReserved1[1];
143 uint16_t flags;
144 #if __LP64__
145 uint8_t eventSourceReserved2[4];
146 #endif /* __LP64__ */
147
148 #endif /* XNU_KERNEL_PRIVATE */
149
150 /*! @var workLoop What is the work-loop for this event source. */
151 IOWorkLoop *workLoop;
152
153 /*! @var refcon What ever the client wants to do, see $link setRefcon. */
154 void *refcon;
155
156 /*! @struct ExpansionData
157 @discussion This structure will be used to expand the capablilties of the IOEventSource in the future.
158 */
159 struct ExpansionData {
160 #if IOKITSTATS
161 struct IOEventSourceCounter *counter;
162 #else
163 void *iokitstatsReserved;
164 #endif
165 };
166
167 /*! @var reserved
168 Reserved for future use. (Internal use only) */
169 ExpansionData *reserved;
170
171 /*! @function init
172 @abstract Primary initialiser for the IOEventSource class.
173 @param owner
174 Owner of this instance of an event source. Used as the first parameter
175 of the action callout. Owner must be an OSObject.
176 @param action
177 Pointer to C call out function. Action is a pointer to a C function
178 that gets called when this event source has outstanding work. It will usually
179 be called by the checkForWork member function. The first parameter of the
180 action call out will always be the owner, this allows C++ member functions to
181 be used as actions. Defaults to 0.
182 @result true if the inherited classes and this instance initialise
183 successfully.
184 */
185 virtual bool init(OSObject *owner, IOEventSource::Action action = 0);
186
187 virtual void free( void ) APPLE_KEXT_OVERRIDE;
188
189 /*! @function checkForWork
190 @abstract Virtual member function used by IOWorkLoop for work
191 scheduling.
192 @discussion This function will be called to request a subclass to check
193 its internal state for any work to do and then to call out the owner/action.
194 If this event source never performs any work (e.g. IOCommandGate), this
195 method should not be overridden. NOTE: This method is no longer declared pure
196 virtual. A default implementation is provided in IOEventSource.
197 @result Return true if this function needs to be called again before all its outstanding events have been processed.
198 */
199 virtual bool checkForWork();
200
201 /*! @function setWorkLoop
202 @abstract Set'ter for $link workLoop variable.
203 @param workLoop
204 Target work-loop of this event source instance. A subclass of
205 IOWorkLoop that at least reacts to signalWorkAvailable() and onThread functions.
206 */
207 virtual void setWorkLoop(IOWorkLoop *workLoop);
208
209 /*! @function setNext
210 @abstract Set'ter for $link eventChainNext variable.
211 @param next
212 Pointer to another IOEventSource instance.
213 */
214 virtual void setNext(IOEventSource *next);
215
216 /*! @function getNext
217 @abstract Get'ter for $link eventChainNext variable.
218 @result value of eventChainNext.
219 */
220 virtual IOEventSource *getNext() const;
221
222
223 protected:
224 // Methods to access the IOWorkLoop exported fields
225 void signalWorkAvailable();
226 void openGate();
227 void closeGate();
228 bool tryCloseGate();
229 int sleepGate(void *event, UInt32 type);
230 int sleepGate(void *event, AbsoluteTime deadline, UInt32 type);
231 void wakeupGate(void *event, bool oneThread);
232
233 public:
234 /*! @function setAction
235 @abstract Set'ter for $link action variable.
236 @param action Pointer to a C function of type IOEventSource::Action. */
237 virtual void setAction(IOEventSource::Action action);
238
239 /*! @function getAction
240 @abstract Get'ter for $link action variable.
241 @result value of action. */
242 virtual IOEventSource::Action getAction() const;
243
244 #ifdef __BLOCKS__
245 /*! @function setActionBlock
246 @abstract Setter for action ivar. The current block is released, & the new block is retained.
247 @param block Block pointer of type IOEventSource::ActionBlock. */
248 void setActionBlock(ActionBlock block);
249 /*! @function getActionBlock
250 @abstract Getter for action ivar.
251 @result Block pointer of type IOEventSource::ActionBlock, if set, or NULL. */
252 ActionBlock getActionBlock(ActionBlock) const;
253 #endif /* __BLOCKS__ */
254
255 /*! @function setRefcon
256 @abstract Setter for refcon ivar. This function will assert if a block action has been set.
257 @param refcon Refcon. */
258 void setRefcon(void *refcon);
259 /*! @function getRefcon
260 @abstract Getter for refcon ivar.
261 @result The refcon. This function will assert if a block action has been set. */
262 void * getRefcon() const;
263
264 /*! @function enable
265 @abstract Enable event source.
266 @discussion A subclass implementation is expected to respect the enabled
267 state when checkForWork is called. Calling this function will cause the
268 work-loop to be signalled so that a checkForWork is performed. */
269 virtual void enable();
270
271 /*! @function disable
272 @abstract Disable event source.
273 @discussion A subclass implementation is expected to respect the enabled
274 state when checkForWork is called. */
275 virtual void disable();
276
277 /*! @function isEnabled
278 @abstract Get'ter for $link enable variable.
279 @result true if enabled. */
280 virtual bool isEnabled() const;
281
282 /*! @function getWorkLoop
283 @abstract Get'ter for $link workLoop variable.
284 @result value of workLoop. */
285 virtual IOWorkLoop *getWorkLoop() const;
286
287 /*! @function onThread
288 @abstract Convenience function for workLoop->onThread.
289 @result true if called on the work-loop thread.
290 */
291 virtual bool onThread() const;
292
293 private:
294 OSMetaClassDeclareReservedUnused(IOEventSource, 0);
295 OSMetaClassDeclareReservedUnused(IOEventSource, 1);
296 OSMetaClassDeclareReservedUnused(IOEventSource, 2);
297 OSMetaClassDeclareReservedUnused(IOEventSource, 3);
298 OSMetaClassDeclareReservedUnused(IOEventSource, 4);
299 OSMetaClassDeclareReservedUnused(IOEventSource, 5);
300 OSMetaClassDeclareReservedUnused(IOEventSource, 6);
301 OSMetaClassDeclareReservedUnused(IOEventSource, 7);
302 };
303
304 #endif /* !_IOKIT_IOEVENTSOURCE_H */