xref: /xnu-11215/iokit/Kernel/IOEventSource.cpp (revision cc9a6355)
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 
31 HISTORY
32     1998-7-13	Godfrey van der Linden(gvdl)
33         Created.
34 ]*/
35 #include <IOKit/IOLib.h>
36 
37 #include <IOKit/IOEventSource.h>
38 #include <IOKit/IOWorkLoop.h>
39 #include <libkern/Block.h>
40 
41 #define super OSObject
42 
43 OSDefineMetaClassAndAbstractStructors(IOEventSource, OSObject)
44 
45 OSMetaClassDefineReservedUnused(IOEventSource, 0);
46 OSMetaClassDefineReservedUnused(IOEventSource, 1);
47 OSMetaClassDefineReservedUnused(IOEventSource, 2);
48 OSMetaClassDefineReservedUnused(IOEventSource, 3);
49 OSMetaClassDefineReservedUnused(IOEventSource, 4);
50 OSMetaClassDefineReservedUnused(IOEventSource, 5);
51 OSMetaClassDefineReservedUnused(IOEventSource, 6);
52 OSMetaClassDefineReservedUnused(IOEventSource, 7);
53 
54 bool IOEventSource::checkForWork() { return false; }
55 
56 /* inline function implementations */
57 
58 #if IOKITSTATS
59 
60 #define IOStatisticsRegisterCounter() \
61 do { \
62 	reserved->counter = IOStatistics::registerEventSource(inOwner); \
63 } while (0)
64 
65 #define IOStatisticsUnregisterCounter() \
66 do { \
67 	if (reserved) \
68 		IOStatistics::unregisterEventSource(reserved->counter); \
69 } while (0)
70 
71 #define IOStatisticsOpenGate() \
72 do { \
73 	IOStatistics::countOpenGate(reserved->counter); \
74 } while (0)
75 
76 #define IOStatisticsCloseGate() \
77 do { \
78 	IOStatistics::countCloseGate(reserved->counter); \
79 } while (0)
80 
81 #else
82 
83 #define IOStatisticsRegisterCounter()
84 #define IOStatisticsUnregisterCounter()
85 #define IOStatisticsOpenGate()
86 #define IOStatisticsCloseGate()
87 
88 #endif /* IOKITSTATS */
89 
90 void IOEventSource::signalWorkAvailable()
91 {
92 	workLoop->signalWorkAvailable();
93 }
94 
95 void IOEventSource::openGate()
96 {
97 	IOStatisticsOpenGate();
98 	workLoop->openGate();
99 }
100 
101 void IOEventSource::closeGate()
102 {
103 	workLoop->closeGate();
104 	IOStatisticsCloseGate();
105 }
106 
107 bool IOEventSource::tryCloseGate()
108 {
109 	bool res;
110 	if ((res = workLoop->tryCloseGate())) {
111 		IOStatisticsCloseGate();
112 	}
113 	return res;
114 }
115 
116 int IOEventSource::sleepGate(void *event, UInt32 type)
117 {
118 	int res;
119 	IOStatisticsOpenGate();
120 	res = workLoop->sleepGate(event, type);
121 	IOStatisticsCloseGate();
122 	return res;
123 }
124 
125 int IOEventSource::sleepGate(void *event, AbsoluteTime deadline, UInt32 type)
126 {
127 	int res;
128 	IOStatisticsOpenGate();
129 	res = workLoop->sleepGate(event, deadline, type);
130 	IOStatisticsCloseGate();
131 	return res;
132 }
133 
134 void IOEventSource::wakeupGate(void *event, bool oneThread) { workLoop->wakeupGate(event, oneThread); }
135 
136 
137 bool IOEventSource::init(OSObject *inOwner,
138                          Action inAction)
139 {
140     if (!inOwner)
141         return false;
142 
143     owner = inOwner;
144 
145     if ( !super::init() )
146         return false;
147 
148     (void) setAction(inAction);
149     enabled = true;
150 
151     if(!reserved) {
152         reserved = IONew(ExpansionData, 1);
153         if (!reserved) {
154             return false;
155         }
156     }
157 
158     IOStatisticsRegisterCounter();
159 
160     return true;
161 }
162 
163 void IOEventSource::free( void )
164 {
165     IOStatisticsUnregisterCounter();
166 
167 	if ((kActionBlock & flags) && actionBlock) Block_release(actionBlock);
168 
169     if (reserved)
170 		IODelete(reserved, ExpansionData, 1);
171 
172     super::free();
173 }
174 
175 void IOEventSource::setRefcon(void *newrefcon)
176 {
177 	refcon = newrefcon;
178 }
179 
180 void * IOEventSource::getRefcon() const
181 {
182 	return refcon;
183 }
184 
185 IOEventSource::Action IOEventSource::getAction() const
186 {
187 	if (kActionBlock & flags) return NULL;
188 	return (action);
189 }
190 
191 IOEventSource::ActionBlock IOEventSource::getActionBlock(ActionBlock) const
192 {
193 	if (kActionBlock & flags) return actionBlock;
194 	return (NULL);
195 }
196 
197 void IOEventSource::setAction(Action inAction)
198 {
199 	if ((kActionBlock & flags) && actionBlock) Block_release(actionBlock);
200     action = inAction;
201 }
202 
203 void IOEventSource::setActionBlock(ActionBlock block)
204 {
205 	if ((kActionBlock & flags) && actionBlock) Block_release(actionBlock);
206 	actionBlock = Block_copy(block);
207 	flags |= kActionBlock;
208 }
209 
210 IOEventSource *IOEventSource::getNext() const { return eventChainNext; };
211 
212 void IOEventSource::setNext(IOEventSource *inNext)
213 {
214     eventChainNext = inNext;
215 }
216 
217 void IOEventSource::enable()
218 {
219     enabled = true;
220     if (workLoop)
221         return signalWorkAvailable();
222 }
223 
224 void IOEventSource::disable()
225 {
226     enabled = false;
227 }
228 
229 bool IOEventSource::isEnabled() const
230 {
231     return enabled;
232 }
233 
234 void IOEventSource::setWorkLoop(IOWorkLoop *inWorkLoop)
235 {
236     if ( !inWorkLoop )
237         disable();
238     workLoop = inWorkLoop;
239 }
240 
241 IOWorkLoop *IOEventSource::getWorkLoop() const
242 {
243     return workLoop;
244 }
245 
246 bool IOEventSource::onThread() const
247 {
248     return (workLoop != 0) && workLoop->onThread();
249 }
250