xref: /xnu-8020.140.41/iokit/DriverKit/IODataQueueDispatchSource.iig (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1/*
2 * Copyright (c) 2019-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#ifndef _IOKIT_UIODATAQUEUEDISPATCHSOURCE_H
30#define _IOKIT_UIODATAQUEUEDISPATCHSOURCE_H
31
32#include <DriverKit/IODispatchQueue.iig>
33#include <DriverKit/IOMemoryDescriptor.iig>
34
35typedef void (^IODataQueueClientEnqueueEntryBlock)(void *data, size_t dataSize);
36typedef void (^IODataQueueClientDequeueEntryBlock)(const void *data, size_t dataSize);
37
38class NATIVE KERNEL IODataQueueDispatchSource : public IODispatchSource
39{
40public:
41
42    /*!
43     * @brief       Create an IODataQueueDispatchSource for a shared memory data queue.
44     * @param       queueByteCount The size of the queue in bytes.
45     * @param       queue IODispatchQueue the source is attached to. Note that the DataAvailable
46     *              and DataServiced handlers are invoked on the queue set for the target method
47     *              of the OSAction, not this queue.
48     * @param       source Created source with +1 retain count to be released by the caller.
49     * @return      kIOReturnSuccess on success. See IOReturn.h for error codes.
50     */
51	static kern_return_t
52	Create(
53		uint64_t queueByteCount,
54	    IODispatchQueue * queue,
55	    IODataQueueDispatchSource ** source);
56
57	virtual bool
58	init() override;
59
60	virtual void
61	free() override;
62
63    /*!
64     * @brief       As a consumer, set the handler block to run when the queue becomes non-empty.
65     * @param       action OSAction instance specifying the callback method. The OSAction object will be retained
66     *              until SetHandler is called again or the event source is cancelled.
67     *              The DataAvailable handler is invoked on the queue set for the target method of the OSAction.
68     * @return      kIOReturnSuccess on success. See IOReturn.h for error codes.
69     */
70	virtual kern_return_t
71	SetDataAvailableHandler(
72	OSAction * action TYPE(DataAvailable));
73
74    /*!
75     * @brief       As a producer, set the handler block to run when the queue becomes non-full, after an attempt
76     *              to enqueue data failed.
77     * @param       action OSAction instance specifying the callback method. The OSAction object will be retained
78     *              until SetHandler is called again or the event source is cancelled.
79     *              The DataServiced handler is invoked on the queue set for the target method of the OSAction.
80     * @return      kIOReturnSuccess on success. See IOReturn.h for error codes.
81     */
82	virtual kern_return_t
83	SetDataServicedHandler(
84	OSAction * action TYPE(DataServiced));
85
86    /*!
87     * @brief       Control the enable state of the interrupt source.
88     * @param       enable Pass true to enable the source or false to disable.
89     * @param       handler Optional block to be executed after the interrupt has been disabled and any pending
90     *              interrupt handlers completed.
91     * @return      kIOReturnSuccess on success. See IOReturn.h for error codes.
92     */
93	virtual kern_return_t
94	SetEnableWithCompletion(
95		bool enable,
96		IODispatchSourceCancelHandler handler) override LOCAL;
97
98    /*!
99     * @brief       Cancel all callbacks from the event source.
100     * @discussion  After cancellation, the source can only be freed. It cannot be reactivated.
101     * @param       handler Handler block to be invoked after any callbacks have completed.
102     * @return      kIOReturnSuccess on success. See IOReturn.h for error codes.
103     */
104	virtual kern_return_t
105	Cancel(IODispatchSourceCancelHandler handler) override LOCAL;
106
107
108    /*!
109     * @brief       As a consumer, check if the data queue is non-empty.
110     * @return      True if the queue is non-empty.
111     */
112	bool
113	IsDataAvailable(void) LOCALONLY;
114
115    /*!
116     * @brief       As a consumer, get access to the next queue entry without dequeuing it.
117     * @param       callback to invoked if the queue is non-empty with the next entry to be dequeued.
118     * @return      kIOReturnSuccess if the callback was invoked.
119     *              kIOReturnUnderrun if the queue was empty.
120     *              kIOReturnError if the queue was corrupt.
121     */
122	kern_return_t
123	Peek(IODataQueueClientDequeueEntryBlock callback) LOCALONLY;
124
125    /*!
126     * @brief       As a consumer, dequeue the next queue entry.
127     * @param       callback invoked if the queue was non-empty with the entry that was dequeued.
128     * @return      kIOReturnSuccess if the callback was invoked.
129     *              kIOReturnUnderrun if the queue was empty.
130     *              kIOReturnError if the queue was corrupt.
131     */
132	kern_return_t
133	Dequeue(IODataQueueClientDequeueEntryBlock callback) LOCALONLY;
134
135    /*!
136     * @brief       As a producer, enqueue a queue entry.
137     * @param       dataSize size of the data to enqueue.
138     * @param       callback invoked if the queue has enough space to enqueue the data.
139     * @return      kIOReturnSuccess if the callback was invoked.
140     *              kIOReturnOverrun if the queue was full.
141     *              kIOReturnError if the queue was corrupt.
142     */
143	kern_return_t
144	Enqueue(uint32_t dataSize, IODataQueueClientEnqueueEntryBlock callback) LOCALONLY;
145
146    /*!
147     * @brief       As a consumer, dequeue the next queue entry, but don't send any DataServiced notification.
148     * @param       sendDataServiced Flag that indicates a DataServiced notification would have sent.
149     *              It should be initialized to false before a series of calls to this method,
150     *              and if true after those calls, the notification sent with SendDataServiced().
151     * @param       callback invoked if the queue was non-empty with the entry that was dequeued.
152     * @return      kIOReturnSuccess if the callback was invoked.
153     *              kIOReturnUnderrun if the queue was empty.
154     *              kIOReturnError if the queue was corrupt.
155     */
156	kern_return_t
157	DequeueWithCoalesce(bool * sendDataServiced, IODataQueueClientDequeueEntryBlock callback) LOCALONLY;
158
159    /*!
160     * @brief       As a producer, enqueue a queue entry, but don't send any DataAvailable notification.
161     * @param       dataSize size of the data to enqueue
162     * @param       sendDataAvailable Flag that indicates a DataAvailable notification would have been sent.
163     *              It should be initialized to false before a series of calls to this method,
164     *              and if true after those calls, the notification sent with SendDataAvailable().
165     * @param       callback invoked if the queue has enough space to enqueue the data.
166     * @return      kIOReturnSuccess if the callback was invoked.
167     *              kIOReturnOverrun if the queue was full.
168     *              kIOReturnError if the queue was corrupt.
169     */
170	kern_return_t
171	EnqueueWithCoalesce(uint32_t dataSize,  bool * sendDataAvailable, IODataQueueClientEnqueueEntryBlock callback) LOCALONLY;
172
173    /*!
174     * @brief       As a consumer, send the DataServiced notification indicated by DequeueWithCoalesce.
175	 */
176	void
177	SendDataServiced(void) LOCALONLY;
178
179    /*!
180     * @brief       As a producer, send the DataAvailable notification indicated by EnqueueWithCoalesce.
181	 */
182	void
183	SendDataAvailable(void) LOCALONLY;
184
185private:
186	virtual kern_return_t
187	CopyMemory(
188	IOMemoryDescriptor ** memory);
189
190	virtual kern_return_t
191	CopyDataAvailableHandler(
192	OSAction ** action);
193
194	virtual kern_return_t
195	CopyDataServicedHandler(
196	OSAction ** action);
197
198	virtual kern_return_t
199	CheckForWork(bool synchronous) override LOCAL;
200
201	virtual void
202	DataAvailable(
203		OSAction * action TARGET) LOCAL = 0;
204
205	virtual void
206	DataServiced(
207		OSAction * action TARGET) LOCAL = 0;
208};
209
210#endif /* ! _IOKIT_UIODATAQUEUEDISPATCHSOURCE_H */
211