xref: /freebsd/contrib/ntp/include/ntp_worker.h (revision 4436b51dff5736e74da464946049ea6899a88938)
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 
20 typedef enum blocking_work_req_tag {
21 	BLOCKING_GETNAMEINFO,
22 	BLOCKING_GETADDRINFO,
23 } blocking_work_req;
24 
25 typedef void (*blocking_work_callback)(blocking_work_req, void *, size_t, void *);
26 
27 typedef 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  */
36 typedef 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
47 typedef pthread_t *	thr_ref;
48 typedef sem_t *		sem_ref;
49 #  else
50 typedef HANDLE		thr_ref;
51 typedef HANDLE		sem_ref;
52 #  endif
53 # endif
54 
55 /*
56  *
57  */
58 #ifdef WORK_FORK
59 typedef 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)
70 typedef 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 
105 extern	blocking_child **	blocking_children;
106 extern	size_t			blocking_children_alloc;
107 extern	int			worker_per_query;	/* boolean */
108 extern	int			intres_req_pending;
109 
110 extern	u_int	available_blocking_child_slot(void);
111 extern	int	queue_blocking_request(blocking_work_req, void *,
112 				       size_t, blocking_work_callback,
113 				       void *);
114 extern	int	queue_blocking_response(blocking_child *,
115 					blocking_pipe_header *, size_t,
116 					const blocking_pipe_header *);
117 extern	void	process_blocking_resp(blocking_child *);
118 extern	int	send_blocking_req_internal(blocking_child *,
119 					   blocking_pipe_header *,
120 					   void *);
121 extern	int	send_blocking_resp_internal(blocking_child *,
122 					    blocking_pipe_header *);
123 extern	blocking_pipe_header *
124 		receive_blocking_req_internal(blocking_child *);
125 extern	blocking_pipe_header *
126 		receive_blocking_resp_internal(blocking_child *);
127 extern	int	blocking_child_common(blocking_child *);
128 extern	void	exit_worker(int)
129 			__attribute__ ((__noreturn__));
130 extern	int	worker_sleep(blocking_child *, time_t);
131 extern	void	worker_idle_timer_fired(void);
132 extern	void	interrupt_worker_sleep(void);
133 extern	int	req_child_exit(blocking_child *);
134 #ifndef HAVE_IO_COMPLETION_PORT
135 extern	int	pipe_socketpair(int fds[2], int *is_pipe);
136 extern	void	close_all_beyond(int);
137 extern	void	close_all_except(int);
138 extern	void	kill_asyncio	(int);
139 #endif
140 
141 # ifdef WORK_PIPE
142 typedef	void	(*addremove_io_fd_func)(int, int, int);
143 extern	addremove_io_fd_func		addremove_io_fd;
144 # else
145 extern	void	handle_blocking_resp_sem(void *);
146 typedef	void	(*addremove_io_semaphore_func)(sem_ref, int);
147 extern	addremove_io_semaphore_func	addremove_io_semaphore;
148 # endif
149 
150 # ifdef WORK_FORK
151 extern	int				worker_process;
152 # endif
153 
154 #endif	/* WORKER */
155 
156 #if defined(HAVE_DROPROOT) && defined(WORK_FORK)
157 extern void	fork_deferred_worker(void);
158 #else
159 # define	fork_deferred_worker()	do {} while (0)
160 #endif
161 
162 #endif	/* !NTP_WORKER_H */
163