ntp_worker.h revision 275970
1275970Scy/*
2275970Scy * ntp_worker.h
3275970Scy */
4275970Scy
5275970Scy#ifndef NTP_WORKER_H
6275970Scy#define NTP_WORKER_H
7275970Scy
8275970Scy#include "ntp_workimpl.h"
9275970Scy
10275970Scy#ifdef WORKER
11275970Scy# if defined(WORK_THREAD) && defined(WORK_PIPE)
12275970Scy#  ifdef HAVE_SEMAPHORE_H
13275970Scy#   include <semaphore.h>
14275970Scy#  endif
15275970Scy# endif
16275970Scy#include "ntp_stdlib.h"
17275970Scy
18275970Scy/* #define TEST_BLOCKING_WORKER */	/* ntp_config.c ntp_intres.c */
19275970Scy
20275970Scytypedef enum blocking_work_req_tag {
21275970Scy	BLOCKING_GETNAMEINFO,
22275970Scy	BLOCKING_GETADDRINFO,
23275970Scy} blocking_work_req;
24275970Scy
25275970Scytypedef void (*blocking_work_callback)(blocking_work_req, void *, size_t, void *);
26275970Scy
27275970Scytypedef enum blocking_magic_sig_e {
28275970Scy	BLOCKING_REQ_MAGIC  = 0x510c7ecf,
29275970Scy	BLOCKING_RESP_MAGIC = 0x510c7e54,
30275970Scy} blocking_magic_sig;
31275970Scy
32275970Scy/*
33275970Scy * The same header is used for both requests to and responses from
34275970Scy * the child.  In the child, done_func and context are opaque.
35275970Scy */
36275970Scytypedef struct blocking_pipe_header_tag {
37275970Scy	size_t			octets;
38275970Scy	blocking_magic_sig	magic_sig;
39275970Scy	blocking_work_req	rtype;
40275970Scy	u_int			child_idx;
41275970Scy	blocking_work_callback	done_func;
42275970Scy	void *			context;
43275970Scy} blocking_pipe_header;
44275970Scy
45275970Scy# ifdef WORK_THREAD
46275970Scy#  ifdef WORK_PIPE
47275970Scytypedef pthread_t *	thr_ref;
48275970Scytypedef sem_t *		sem_ref;
49275970Scy#  else
50275970Scytypedef HANDLE		thr_ref;
51275970Scytypedef HANDLE		sem_ref;
52275970Scy#  endif
53275970Scy# endif
54275970Scy
55275970Scy/*
56275970Scy *
57275970Scy */
58275970Scy#ifdef WORK_FORK
59275970Scytypedef struct blocking_child_tag {
60275970Scy	int	reusable;
61275970Scy	int	pid;
62275970Scy	int	req_write_pipe;		/* parent */
63275970Scy	int	resp_read_pipe;
64275970Scy	void *	resp_read_ctx;
65275970Scy	int	req_read_pipe;		/* child */
66275970Scy	int	resp_write_pipe;
67275970Scy	int	ispipe;
68275970Scy} blocking_child;
69275970Scy#elif defined(WORK_THREAD)
70275970Scytypedef struct blocking_child_tag {
71275970Scy/*
72275970Scy * blocking workitems and blocking_responses are dynamically-sized
73275970Scy * one-dimensional arrays of pointers to blocking worker requests and
74275970Scy * responses.
75275970Scy */
76275970Scy	int			reusable;
77275970Scy	thr_ref			thread_ref;
78275970Scy	u_int			thread_id;
79275970Scy	blocking_pipe_header * volatile * volatile
80275970Scy				workitems;
81275970Scy	volatile size_t		workitems_alloc;
82275970Scy	size_t			next_workitem;	 /* parent */
83275970Scy	size_t			next_workeritem; /* child */
84275970Scy	blocking_pipe_header * volatile * volatile
85275970Scy				responses;
86275970Scy	volatile size_t		responses_alloc;
87275970Scy	size_t			next_response;	/* child */
88275970Scy	size_t			next_workresp;	/* parent */
89275970Scy	/* event handles / sem_t pointers */
90275970Scy	/* sem_ref		child_is_blocking; */
91275970Scy	sem_ref			blocking_req_ready;
92275970Scy	sem_ref			wake_scheduled_sleep;
93275970Scy#ifdef WORK_PIPE
94275970Scy	int			resp_read_pipe;	/* parent */
95275970Scy	int			resp_write_pipe;/* child */
96275970Scy	int			ispipe;
97275970Scy	void *			resp_read_ctx;	/* child */
98275970Scy#else
99275970Scy	sem_ref			blocking_response_ready;
100275970Scy#endif
101275970Scy} blocking_child;
102275970Scy
103275970Scy#endif	/* WORK_THREAD */
104275970Scy
105275970Scyextern	blocking_child **	blocking_children;
106275970Scyextern	size_t			blocking_children_alloc;
107275970Scyextern	int			worker_per_query;	/* boolean */
108275970Scyextern	int			intres_req_pending;
109275970Scy
110275970Scyextern	u_int	available_blocking_child_slot(void);
111275970Scyextern	int	queue_blocking_request(blocking_work_req, void *,
112275970Scy				       size_t, blocking_work_callback,
113275970Scy				       void *);
114275970Scyextern	int	queue_blocking_response(blocking_child *,
115275970Scy					blocking_pipe_header *, size_t,
116275970Scy					const blocking_pipe_header *);
117275970Scyextern	void	process_blocking_resp(blocking_child *);
118275970Scyextern	int	send_blocking_req_internal(blocking_child *,
119275970Scy					   blocking_pipe_header *,
120275970Scy					   void *);
121275970Scyextern	int	send_blocking_resp_internal(blocking_child *,
122275970Scy					    blocking_pipe_header *);
123275970Scyextern	blocking_pipe_header *
124275970Scy		receive_blocking_req_internal(blocking_child *);
125275970Scyextern	blocking_pipe_header *
126275970Scy		receive_blocking_resp_internal(blocking_child *);
127275970Scyextern	int	blocking_child_common(blocking_child *);
128275970Scyextern	void	exit_worker(int)
129275970Scy			__attribute__ ((__noreturn__));
130275970Scyextern	int	worker_sleep(blocking_child *, time_t);
131275970Scyextern	void	worker_idle_timer_fired(void);
132275970Scyextern	void	interrupt_worker_sleep(void);
133275970Scyextern	int	req_child_exit(blocking_child *);
134275970Scy#ifndef HAVE_IO_COMPLETION_PORT
135275970Scyextern	int	pipe_socketpair(int fds[2], int *is_pipe);
136275970Scyextern	void	close_all_beyond(int);
137275970Scyextern	void	close_all_except(int);
138275970Scyextern	void	kill_asyncio	(int);
139275970Scy#endif
140275970Scy
141275970Scy# ifdef WORK_PIPE
142275970Scytypedef	void	(*addremove_io_fd_func)(int, int, int);
143275970Scyextern	addremove_io_fd_func		addremove_io_fd;
144275970Scy# else
145275970Scyextern	void	handle_blocking_resp_sem(void *);
146275970Scytypedef	void	(*addremove_io_semaphore_func)(sem_ref, int);
147275970Scyextern	addremove_io_semaphore_func	addremove_io_semaphore;
148275970Scy# endif
149275970Scy
150275970Scy# ifdef WORK_FORK
151275970Scyextern	int				worker_process;
152275970Scy# endif
153275970Scy
154275970Scy#endif	/* WORKER */
155275970Scy
156275970Scy#if defined(HAVE_DROPROOT) && defined(WORK_FORK)
157275970Scyextern void	fork_deferred_worker(void);
158275970Scy#else
159275970Scy# define	fork_deferred_worker()	do {} while (0)
160275970Scy#endif
161275970Scy
162275970Scy#endif	/* !NTP_WORKER_H */
163