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