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