87 static void master_unthrottle_wrapper(
int unused_event,
void *ptr)
95 master_unthrottle(serv);
112 msg_info(
"throttle released for command %s", serv->
path);
141 const char *myname =
"master_spawn";
145 static unsigned master_generation = 0;
148 if (master_child_table == 0)
168 master_generation += 1;
169 switch (pid = fork()) {
176 msg_warn(
"%s: fork: %m -- throttling", myname);
177 master_throttle(serv);
195 msg_fatal(
"%s: flow pipe read descriptor <= %d",
203 msg_fatal(
"%s: flow pipe read descriptor <= %d",
212 msg_fatal(
"%s: status file descriptor collision", myname);
214 msg_fatal(
"%s: dup2 status_fd: %m", myname);
219 msg_fatal(
"%s: listen file descriptor collision", myname);
247 proc->
gen = master_generation;
251 sizeof(pid), (
void *) proc);
282 sizeof(proc->
pid), (void (*) (
void *)) 0);
300 while ((pid = waitpid((pid_t) - 1, &status, WNOHANG)) > 0) {
302 msg_info(
"master_reap_child: pid %d", pid);
304 (
void *) &pid,
sizeof(pid))) == 0)
305 msg_panic(
"master_reap: unknown pid: %d", pid);
308 #define MASTER_KILL_SIGNAL SIGTERM
309 #define MASTER_SENT_SIGNAL(serv, status) \
310 (MASTER_MARKED_FOR_DELETION(serv) \
311 && WTERMSIG(status) == MASTER_KILL_SIGNAL)
323 if (WIFSTOPPED(status)) {
324 msg_warn(
"process %s pid %d stopped by signal %d",
325 serv->
path, pid, WSTOPSIG(status));
328 if (WIFEXITED(status))
329 msg_warn(
"process %s pid %d exit status %d",
330 serv->
path, pid, WEXITSTATUS(status));
332 msg_warn(
"process %s pid %d killed by signal %d",
333 serv->
path, pid, WTERMSIG(status));
337 msg_warn(
"%s: bad command startup -- throttling", serv->
path);
338 master_throttle(serv);
341 master_delete_child(proc);
358 master_throttle(serv);
359 for (info = list =
binhash_list(master_child_table); *info; info++) {
361 if (proc->
serv == serv)
367 master_unthrottle(serv);
#define MASTER_LIMIT_OK(limit, count)
#define MASTER_KILL_SIGNAL
void master_reap_child(void)
NORETURN msg_panic(const char *fmt,...)
#define MASTER_FLOW_WRITE
BINHASH * binhash_create(ssize_t size)
BINHASH * master_child_table
BINHASH_INFO * binhash_enter(BINHASH *table, const void *key, ssize_t key_len, void *value)
void master_avail_less(MASTER_SERV *, MASTER_PROC *)
#define MASTER_FLAG_THROTTLE
void master_avail_more(MASTER_SERV *, MASTER_PROC *)
#define MASTER_STAT_AVAIL
BINHASH_INFO ** binhash_list(BINHASH *table)
void msg_warn(const char *fmt,...)
VSTRING * vstring_alloc(ssize_t len)
#define MASTER_SENT_SIGNAL(serv, status)
void master_spawn(MASTER_SERV *serv)
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
time_t stress_expire_time
NORETURN msg_fatal(const char *fmt,...)
time_t event_request_timer(EVENT_NOTIFY_TIME_FN callback, void *context, int delay)
void master_wakeup_init(MASTER_SERV *)
void master_avail_listen(MASTER_SERV *)
int event_cancel_timer(EVENT_NOTIFY_TIME_FN callback, void *context)
MSG_CLEANUP_FN msg_cleanup(MSG_CLEANUP_FN cleanup_fn)
#define NORMAL_EXIT_STATUS(status)
void * binhash_find(BINHASH *table, const void *key, ssize_t key_len)
#define MASTER_FLAG_CONDWAKE
void master_delete_children(MASTER_SERV *serv)
void binhash_delete(BINHASH *table, const void *key, ssize_t key_len, void(*free_fn)(void *))
void * mymalloc(ssize_t len)
void msg_info(const char *fmt,...)