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