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