Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/ntp/include/ntp_worker.h
Show All 37 Lines | typedef struct blocking_pipe_header_tag { | ||||
blocking_magic_sig magic_sig; | blocking_magic_sig magic_sig; | ||||
blocking_work_req rtype; | blocking_work_req rtype; | ||||
u_int child_idx; | u_int child_idx; | ||||
blocking_work_callback done_func; | blocking_work_callback done_func; | ||||
void * context; | void * context; | ||||
} blocking_pipe_header; | } blocking_pipe_header; | ||||
# ifdef WORK_THREAD | # ifdef WORK_THREAD | ||||
# ifdef WORK_PIPE | # ifdef SYS_WINNT | ||||
typedef pthread_t * thr_ref; | typedef struct { HANDLE thnd; } thread_type; | ||||
typedef sem_t * sem_ref; | typedef struct { HANDLE shnd; } sema_type; | ||||
# else | # else | ||||
typedef HANDLE thr_ref; | typedef pthread_t thread_type; | ||||
typedef HANDLE sem_ref; | typedef sem_t sema_type; | ||||
# endif | # endif | ||||
typedef thread_type *thr_ref; | |||||
typedef sema_type *sem_ref; | |||||
# endif | # endif | ||||
/* | /* | ||||
* | * | ||||
*/ | */ | ||||
#ifdef WORK_FORK | #if defined(WORK_FORK) | ||||
typedef struct blocking_child_tag { | typedef struct blocking_child_tag { | ||||
int reusable; | int reusable; | ||||
int pid; | int pid; | ||||
int req_write_pipe; /* parent */ | int req_write_pipe; /* parent */ | ||||
int resp_read_pipe; | int resp_read_pipe; | ||||
void * resp_read_ctx; | void * resp_read_ctx; | ||||
int req_read_pipe; /* child */ | int req_read_pipe; /* child */ | ||||
int resp_write_pipe; | int resp_write_pipe; | ||||
int ispipe; | int ispipe; | ||||
} blocking_child; | } blocking_child; | ||||
#elif defined(WORK_THREAD) | #elif defined(WORK_THREAD) | ||||
typedef struct blocking_child_tag { | typedef struct blocking_child_tag { | ||||
/* | /* | ||||
* blocking workitems and blocking_responses are dynamically-sized | * blocking workitems and blocking_responses are dynamically-sized | ||||
* one-dimensional arrays of pointers to blocking worker requests and | * one-dimensional arrays of pointers to blocking worker requests and | ||||
* responses. | * responses. | ||||
* | |||||
* IMPORTANT: This structure is shared between threads, and all access | |||||
* that is not atomic (especially queue operations) must hold the | |||||
* 'accesslock' semaphore to avoid data races. | |||||
* | |||||
* The resource management (thread/semaphore creation/destruction) | |||||
* functions and functions just testing a handle are safe because these | |||||
* are only changed by the main thread when no worker is running on the | |||||
* same data structure. | |||||
*/ | */ | ||||
int reusable; | int reusable; | ||||
thr_ref thread_ref; | sem_ref accesslock; /* shared access lock */ | ||||
u_int thread_id; | thr_ref thread_ref; /* thread 'handle' */ | ||||
blocking_pipe_header * volatile * volatile | |||||
/* the reuest queue */ | |||||
blocking_pipe_header ** volatile | |||||
workitems; | workitems; | ||||
volatile size_t workitems_alloc; | volatile size_t workitems_alloc; | ||||
size_t next_workitem; /* parent */ | size_t head_workitem; /* parent */ | ||||
size_t next_workeritem; /* child */ | size_t tail_workitem; /* child */ | ||||
blocking_pipe_header * volatile * volatile | sem_ref workitems_pending; /* signalling */ | ||||
/* the response queue */ | |||||
blocking_pipe_header ** volatile | |||||
responses; | responses; | ||||
volatile size_t responses_alloc; | volatile size_t responses_alloc; | ||||
size_t next_response; /* child */ | size_t head_response; /* child */ | ||||
size_t next_workresp; /* parent */ | size_t tail_response; /* parent */ | ||||
/* event handles / sem_t pointers */ | /* event handles / sem_t pointers */ | ||||
/* sem_ref child_is_blocking; */ | |||||
sem_ref blocking_req_ready; | |||||
sem_ref wake_scheduled_sleep; | sem_ref wake_scheduled_sleep; | ||||
/* some systems use a pipe for notification, others a semaphore. | |||||
* Both employ the queue above for the actual data transfer. | |||||
*/ | |||||
#ifdef WORK_PIPE | #ifdef WORK_PIPE | ||||
int resp_read_pipe; /* parent */ | int resp_read_pipe; /* parent */ | ||||
int resp_write_pipe;/* child */ | int resp_write_pipe; /* child */ | ||||
int ispipe; | int ispipe; | ||||
void * resp_read_ctx; /* child */ | void * resp_read_ctx; /* child */ | ||||
#else | #else | ||||
sem_ref blocking_response_ready; | sem_ref responses_pending; /* signalling */ | ||||
#endif | #endif | ||||
sema_type sem_table[4]; | |||||
thread_type thr_table[1]; | |||||
} blocking_child; | } blocking_child; | ||||
#endif /* WORK_THREAD */ | #endif /* WORK_THREAD */ | ||||
extern blocking_child ** blocking_children; | extern blocking_child ** blocking_children; | ||||
extern size_t blocking_children_alloc; | extern size_t blocking_children_alloc; | ||||
extern int worker_per_query; /* boolean */ | extern int worker_per_query; /* boolean */ | ||||
extern int intres_req_pending; | extern int intres_req_pending; | ||||
extern u_int available_blocking_child_slot(void); | extern u_int available_blocking_child_slot(void); | ||||
extern int queue_blocking_request(blocking_work_req, void *, | extern int queue_blocking_request(blocking_work_req, void *, | ||||
size_t, blocking_work_callback, | size_t, blocking_work_callback, | ||||
void *); | void *); | ||||
extern int queue_blocking_response(blocking_child *, | extern int queue_blocking_response(blocking_child *, | ||||
blocking_pipe_header *, size_t, | blocking_pipe_header *, size_t, | ||||
const blocking_pipe_header *); | const blocking_pipe_header *); | ||||
extern void process_blocking_resp(blocking_child *); | extern void process_blocking_resp(blocking_child *); | ||||
extern int send_blocking_req_internal(blocking_child *, | extern int send_blocking_req_internal(blocking_child *, | ||||
blocking_pipe_header *, | blocking_pipe_header *, | ||||
void *); | void *); | ||||
extern int send_blocking_resp_internal(blocking_child *, | extern int send_blocking_resp_internal(blocking_child *, | ||||
blocking_pipe_header *); | blocking_pipe_header *); | ||||
Show All 40 Lines |