1/* 2 * ntp_worker.h 3 */ 4 5#ifndef NTP_WORKER_H 6#define NTP_WORKER_H 7 8#include "ntp_workimpl.h" --- 46 unchanged lines hidden (view full) --- 55# endif 56 57/* 58 * 59 */ 60#if defined(WORK_FORK) 61 62typedef struct blocking_child_tag { |
63 int reusable; 64 int pid; 65 int req_write_pipe; /* parent */ 66 int resp_read_pipe; 67 void * resp_read_ctx; 68 int req_read_pipe; /* child */ 69 int resp_write_pipe; 70 int ispipe; 71 volatile u_int resp_ready_seen; /* signal/scan */ 72 volatile u_int resp_ready_done; /* consumer/mainloop */ |
73} blocking_child; 74 75#elif defined(WORK_THREAD) 76 77typedef struct blocking_child_tag { |
78 /* 79 * blocking workitems and blocking_responses are 80 * dynamically-sized one-dimensional arrays of pointers to 81 * blocking worker requests and responses. 82 * 83 * IMPORTANT: This structure is shared between threads, and all 84 * access that is not atomic (especially queue operations) must 85 * hold the 'accesslock' semaphore to avoid data races. 86 * 87 * The resource management (thread/semaphore 88 * creation/destruction) functions and functions just testing a 89 * handle are safe because these are only changed by the main 90 * thread when no worker is running on the same data structure. 91 */ |
92 int reusable; 93 sem_ref accesslock; /* shared access lock */ 94 thr_ref thread_ref; /* thread 'handle' */ 95 96 /* the reuest queue */ 97 blocking_pipe_header ** volatile 98 workitems; 99 volatile size_t workitems_alloc; --- 14 unchanged lines hidden (view full) --- 114 /* some systems use a pipe for notification, others a semaphore. 115 * Both employ the queue above for the actual data transfer. 116 */ 117#ifdef WORK_PIPE 118 int resp_read_pipe; /* parent */ 119 int resp_write_pipe; /* child */ 120 int ispipe; 121 void * resp_read_ctx; /* child */ |
122 volatile u_int resp_ready_seen; /* signal/scan */ 123 volatile u_int resp_ready_done; /* consumer/mainloop */ |
124#else 125 sem_ref responses_pending; /* signalling */ 126#endif 127 sema_type sem_table[4]; 128 thread_type thr_table[1]; 129} blocking_child; 130 131#endif /* WORK_THREAD */ 132 |
133/* we need some global tag to indicate any blocking child may be ready: */ 134extern volatile u_int blocking_child_ready_seen;/* signal/scan */ 135extern volatile u_int blocking_child_ready_done;/* consumer/mainloop */ 136 |
137extern blocking_child ** blocking_children; 138extern size_t blocking_children_alloc; 139extern int worker_per_query; /* boolean */ 140extern int intres_req_pending; 141 142extern u_int available_blocking_child_slot(void); 143extern int queue_blocking_request(blocking_work_req, void *, 144 size_t, blocking_work_callback, 145 void *); 146extern int queue_blocking_response(blocking_child *, 147 blocking_pipe_header *, size_t, 148 const blocking_pipe_header *); 149extern void process_blocking_resp(blocking_child *); |
150extern void harvest_blocking_responses(void); |
151extern int send_blocking_req_internal(blocking_child *, 152 blocking_pipe_header *, 153 void *); 154extern int send_blocking_resp_internal(blocking_child *, 155 blocking_pipe_header *); 156extern blocking_pipe_header * 157 receive_blocking_req_internal(blocking_child *); 158extern blocking_pipe_header * --- 37 unchanged lines hidden --- |