1/*
2   Unix SMB/CIFS implementation.
3
4   generalised event loop handling
5
6   INTERNAL STRUCTS. THERE ARE NO API GUARANTEES.
7   External users should only ever have to include this header when
8   implementing new tevent backends.
9
10   Copyright (C) Stefan Metzmacher 2005-2009
11
12     ** NOTE! The following LGPL license applies to the tevent
13     ** library. This does NOT imply that all of Samba is released
14     ** under the LGPL
15
16   This library is free software; you can redistribute it and/or
17   modify it under the terms of the GNU Lesser General Public
18   License as published by the Free Software Foundation; either
19   version 3 of the License, or (at your option) any later version.
20
21   This library is distributed in the hope that it will be useful,
22   but WITHOUT ANY WARRANTY; without even the implied warranty of
23   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   Lesser General Public License for more details.
25
26   You should have received a copy of the GNU Lesser General Public
27   License along with this library; if not, see <http://www.gnu.org/licenses/>.
28*/
29
30struct tevent_req {
31	/**
32	 * @brief What to do on completion
33	 *
34	 * This is used for the user of an async request, fn is called when
35	 * the request completes, either successfully or with an error.
36	 */
37	struct {
38		/**
39		 * @brief Completion function
40		 * Completion function, to be filled by the API user
41		 */
42		tevent_req_fn fn;
43		/**
44		 * @brief Private data for the completion function
45		 */
46		void *private_data;
47	} async;
48
49	/**
50	 * @brief Private state pointer for the actual implementation
51	 *
52	 * The implementation doing the work for the async request needs to
53	 * keep around current data like for example a fd event. The user of
54	 * an async request should not touch this.
55	 */
56	void *data;
57
58	/**
59	 * @brief A function to overwrite the default print function
60	 *
61	 * The implementation doing the work may want to implement a
62	 * custom function to print the text representation of the async
63	 * request.
64	 */
65	tevent_req_print_fn private_print;
66
67	/**
68	 * @brief A function to cancel the request
69	 *
70	 * The implementation might want to set a function
71	 * that is called when the tevent_req_cancel() function
72	 * was called.
73	 */
74	tevent_req_cancel_fn private_cancel;
75
76	/**
77	 * @brief Internal state of the request
78	 *
79	 * Callers should only access this via functions and never directly.
80	 */
81	struct {
82		/**
83		 * @brief The talloc type of the data pointer
84		 *
85		 * This is filled by the tevent_req_create() macro.
86		 *
87		 * This for debugging only.
88		 */
89		const char *private_type;
90
91		/**
92		 * @brief The location where the request was created
93		 *
94		 * This uses the __location__ macro via the tevent_req_create()
95		 * macro.
96		 *
97		 * This for debugging only.
98		 */
99		const char *create_location;
100
101		/**
102		 * @brief The location where the request was finished
103		 *
104		 * This uses the __location__ macro via the tevent_req_done(),
105		 * tevent_req_error() or tevent_req_nomem() macro.
106		 *
107		 * This for debugging only.
108		 */
109		const char *finish_location;
110
111		/**
112		 * @brief The location where the request was canceled
113		 *
114		 * This uses the __location__ macro via the
115		 * tevent_req_cancel() macro.
116		 *
117		 * This for debugging only.
118		 */
119		const char *cancel_location;
120
121		/**
122		 * @brief The external state - will be queried by the caller
123		 *
124		 * While the async request is being processed, state will remain in
125		 * TEVENT_REQ_IN_PROGRESS. A request is finished if
126		 * req->state>=TEVENT_REQ_DONE.
127		 */
128		enum tevent_req_state state;
129
130		/**
131		 * @brief status code when finished
132		 *
133		 * This status can be queried in the async completion function. It
134		 * will be set to 0 when everything went fine.
135		 */
136		uint64_t error;
137
138		/**
139		 * @brief the immediate event used by tevent_req_post
140		 *
141		 */
142		struct tevent_immediate *trigger;
143
144		/**
145		 * @brief the timer event if tevent_req_set_endtime was used
146		 *
147		 */
148		struct tevent_timer *timer;
149	} internal;
150};
151
152struct tevent_fd {
153	struct tevent_fd *prev, *next;
154	struct tevent_context *event_ctx;
155	int fd;
156	uint16_t flags; /* see TEVENT_FD_* flags */
157	tevent_fd_handler_t handler;
158	tevent_fd_close_fn_t close_fn;
159	/* this is private for the specific handler */
160	void *private_data;
161	/* this is for debugging only! */
162	const char *handler_name;
163	const char *location;
164	/* this is private for the events_ops implementation */
165	uint16_t additional_flags;
166	void *additional_data;
167};
168
169struct tevent_timer {
170	struct tevent_timer *prev, *next;
171	struct tevent_context *event_ctx;
172	struct timeval next_event;
173	tevent_timer_handler_t handler;
174	/* this is private for the specific handler */
175	void *private_data;
176	/* this is for debugging only! */
177	const char *handler_name;
178	const char *location;
179	/* this is private for the events_ops implementation */
180	void *additional_data;
181};
182
183struct tevent_immediate {
184	struct tevent_immediate *prev, *next;
185	struct tevent_context *event_ctx;
186	tevent_immediate_handler_t handler;
187	/* this is private for the specific handler */
188	void *private_data;
189	/* this is for debugging only! */
190	const char *handler_name;
191	const char *create_location;
192	const char *schedule_location;
193	/* this is private for the events_ops implementation */
194	void (*cancel_fn)(struct tevent_immediate *im);
195	void *additional_data;
196};
197
198struct tevent_signal {
199	struct tevent_signal *prev, *next;
200	struct tevent_context *event_ctx;
201	int signum;
202	int sa_flags;
203	tevent_signal_handler_t handler;
204	/* this is private for the specific handler */
205	void *private_data;
206	/* this is for debugging only! */
207	const char *handler_name;
208	const char *location;
209	/* this is private for the events_ops implementation */
210	void *additional_data;
211};
212
213struct tevent_debug_ops {
214	void (*debug)(void *context, enum tevent_debug_level level,
215		      const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
216	void *context;
217};
218
219void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
220		  const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
221
222struct tevent_context {
223	/* the specific events implementation */
224	const struct tevent_ops *ops;
225
226	/* list of fd events - used by common code */
227	struct tevent_fd *fd_events;
228
229	/* list of timed events - used by common code */
230	struct tevent_timer *timer_events;
231
232	/* list of immediate events - used by common code */
233	struct tevent_immediate *immediate_events;
234
235	/* list of signal events - used by common code */
236	struct tevent_signal *signal_events;
237
238	/* this is private for the events_ops implementation */
239	void *additional_data;
240
241	/* pipe hack used with signal handlers */
242	struct tevent_fd *pipe_fde;
243	int pipe_fds[2];
244
245	/* debugging operations */
246	struct tevent_debug_ops debug_ops;
247
248	/* info about the nesting status */
249	struct {
250		bool allowed;
251		uint32_t level;
252		tevent_nesting_hook hook_fn;
253		void *hook_private;
254	} nesting;
255};
256
257
258int tevent_common_context_destructor(struct tevent_context *ev);
259int tevent_common_loop_wait(struct tevent_context *ev,
260			    const char *location);
261
262int tevent_common_fd_destructor(struct tevent_fd *fde);
263struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev,
264				       TALLOC_CTX *mem_ctx,
265				       int fd,
266				       uint16_t flags,
267				       tevent_fd_handler_t handler,
268				       void *private_data,
269				       const char *handler_name,
270				       const char *location);
271void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
272				   tevent_fd_close_fn_t close_fn);
273uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
274void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
275
276struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
277					     TALLOC_CTX *mem_ctx,
278					     struct timeval next_event,
279					     tevent_timer_handler_t handler,
280					     void *private_data,
281					     const char *handler_name,
282					     const char *location);
283struct timeval tevent_common_loop_timer_delay(struct tevent_context *);
284
285void tevent_common_schedule_immediate(struct tevent_immediate *im,
286				      struct tevent_context *ev,
287				      tevent_immediate_handler_t handler,
288				      void *private_data,
289				      const char *handler_name,
290				      const char *location);
291bool tevent_common_loop_immediate(struct tevent_context *ev);
292
293struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
294					       TALLOC_CTX *mem_ctx,
295					       int signum,
296					       int sa_flags,
297					       tevent_signal_handler_t handler,
298					       void *private_data,
299					       const char *handler_name,
300					       const char *location);
301int tevent_common_check_signal(struct tevent_context *ev);
302void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se);
303
304bool tevent_standard_init(void);
305bool tevent_select_init(void);
306#ifdef HAVE_EPOLL
307bool tevent_epoll_init(void);
308#endif
309