ntp_worker.h revision 290001
1/*
2 * ntp_worker.h
3 */
4
5#ifndef NTP_WORKER_H
6#define NTP_WORKER_H
7
8#include "ntp_workimpl.h"
9
10#ifdef WORKER
11# if defined(WORK_THREAD) && defined(WORK_PIPE)
12#  ifdef HAVE_SEMAPHORE_H
13#   include <semaphore.h>
14#  endif
15# endif
16#include "ntp_stdlib.h"
17
18/* #define TEST_BLOCKING_WORKER */	/* ntp_config.c ntp_intres.c */
19
20typedef enum blocking_work_req_tag {
21	BLOCKING_GETNAMEINFO,
22	BLOCKING_GETADDRINFO,
23} blocking_work_req;
24
25typedef void (*blocking_work_callback)(blocking_work_req, void *, size_t, void *);
26
27typedef enum blocking_magic_sig_e {
28	BLOCKING_REQ_MAGIC  = 0x510c7ecf,
29	BLOCKING_RESP_MAGIC = 0x510c7e54,
30} blocking_magic_sig;
31
32/*
33 * The same header is used for both requests to and responses from
34 * the child.  In the child, done_func and context are opaque.
35 */
36typedef struct blocking_pipe_header_tag {
37	size_t			octets;
38	blocking_magic_sig	magic_sig;
39	blocking_work_req	rtype;
40	u_int			child_idx;
41	blocking_work_callback	done_func;
42	void *			context;
43} blocking_pipe_header;
44
45# ifdef WORK_THREAD
46#  ifdef WORK_PIPE
47typedef pthread_t *	thr_ref;
48typedef sem_t *		sem_ref;
49#  else
50typedef HANDLE		thr_ref;
51typedef HANDLE		sem_ref;
52#  endif
53# endif
54
55/*
56 *
57 */
58#ifdef WORK_FORK
59typedef struct blocking_child_tag {
60	int	reusable;
61	int	pid;
62	int	req_write_pipe;		/* parent */
63	int	resp_read_pipe;
64	void *	resp_read_ctx;
65	int	req_read_pipe;		/* child */
66	int	resp_write_pipe;
67	int	ispipe;
68} blocking_child;
69#elif defined(WORK_THREAD)
70typedef struct blocking_child_tag {
71/*
72 * blocking workitems and blocking_responses are dynamically-sized
73 * one-dimensional arrays of pointers to blocking worker requests and
74 * responses.
75 */
76	int			reusable;
77	thr_ref			thread_ref;
78	u_int			thread_id;
79	blocking_pipe_header * volatile * volatile
80				workitems;
81	volatile size_t		workitems_alloc;
82	size_t			next_workitem;	 /* parent */
83	size_t			next_workeritem; /* child */
84	blocking_pipe_header * volatile * volatile
85				responses;
86	volatile size_t		responses_alloc;
87	size_t			next_response;	/* child */
88	size_t			next_workresp;	/* parent */
89	/* event handles / sem_t pointers */
90	/* sem_ref		child_is_blocking; */
91	sem_ref			blocking_req_ready;
92	sem_ref			wake_scheduled_sleep;
93#ifdef WORK_PIPE
94	int			resp_read_pipe;	/* parent */
95	int			resp_write_pipe;/* child */
96	int			ispipe;
97	void *			resp_read_ctx;	/* child */
98#else
99	sem_ref			blocking_response_ready;
100#endif
101} blocking_child;
102
103#endif	/* WORK_THREAD */
104
105extern	blocking_child **	blocking_children;
106extern	size_t			blocking_children_alloc;
107extern	int			worker_per_query;	/* boolean */
108extern	int			intres_req_pending;
109
110extern	u_int	available_blocking_child_slot(void);
111extern	int	queue_blocking_request(blocking_work_req, void *,
112				       size_t, blocking_work_callback,
113				       void *);
114extern	int	queue_blocking_response(blocking_child *,
115					blocking_pipe_header *, size_t,
116					const blocking_pipe_header *);
117extern	void	process_blocking_resp(blocking_child *);
118extern	int	send_blocking_req_internal(blocking_child *,
119					   blocking_pipe_header *,
120					   void *);
121extern	int	send_blocking_resp_internal(blocking_child *,
122					    blocking_pipe_header *);
123extern	blocking_pipe_header *
124		receive_blocking_req_internal(blocking_child *);
125extern	blocking_pipe_header *
126		receive_blocking_resp_internal(blocking_child *);
127extern	int	blocking_child_common(blocking_child *);
128extern	void	exit_worker(int)
129			__attribute__ ((__noreturn__));
130extern	int	worker_sleep(blocking_child *, time_t);
131extern	void	worker_idle_timer_fired(void);
132extern	void	interrupt_worker_sleep(void);
133extern	int	req_child_exit(blocking_child *);
134#ifndef HAVE_IO_COMPLETION_PORT
135extern	int	pipe_socketpair(int fds[2], int *is_pipe);
136extern	void	close_all_beyond(int);
137extern	void	close_all_except(int);
138extern	void	kill_asyncio	(int);
139#endif
140
141# ifdef WORK_PIPE
142typedef	void	(*addremove_io_fd_func)(int, int, int);
143extern	addremove_io_fd_func		addremove_io_fd;
144# else
145extern	void	handle_blocking_resp_sem(void *);
146typedef	void	(*addremove_io_semaphore_func)(sem_ref, int);
147extern	addremove_io_semaphore_func	addremove_io_semaphore;
148# endif
149
150# ifdef WORK_FORK
151extern	int				worker_process;
152# endif
153
154#endif	/* WORKER */
155
156#if defined(HAVE_DROPROOT) && defined(WORK_FORK)
157extern void	fork_deferred_worker(void);
158#else
159# define	fork_deferred_worker()	do {} while (0)
160#endif
161
162#endif	/* !NTP_WORKER_H */
163