static int worker( const char *path) { int sd, ret; char response[128]; /*set_loadctl_defaults();*/ sd = nsock_unix( path, NSOCK_TCP | NSOCK_CONNECT); if( sd < 0) { printf( "Failed to connect to query socket '%s': %s: %s\n", path, nsock_strerror( sd), strerror( errno)); return 1; } ret = nsock_printf_nul( sd, "@wproc register name=Core Ping Worker %d;pid=%d;plugin=check_ping", getpid(), getpid()); if( ret < 0) { printf( "Failed to register as worker.\n"); return 1; } ret = read( sd, response, 3); if( ret != 3) { printf( "Failed to read response from wproc manager\n"); return 1; } if( memcmp( response, "OK", 3)) { read( sd, response + 3, sizeof(response) - 4); response[ sizeof( response) - 2] = 0; printf( "Failed to register with wproc manager: %s\n", response); return 1; } enter_worker( sd, start_cmd); return 0; }
struct worker_process *spawn_worker(void (*init_func)(void *), void *init_arg) { int sv[2]; int pid; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) return NULL; pid = fork(); if (pid < 0) { close(sv[0]); close(sv[1]); return NULL; } /* parent leaves the child */ if (pid) { worker_process *worker = calloc(1, sizeof(worker_process)); close(sv[1]); if (!worker) { kill(SIGKILL, pid); close(sv[0]); return NULL; } worker->sd = sv[0]; worker->pid = pid; worker->ioc = iocache_create(1 * 1024 * 1024); /* 1 socket for master, 2 fd's for each child */ worker->max_jobs = (iobroker_max_usable_fds() - 1) / 2; worker->jobs = calloc(worker->max_jobs, sizeof(worker_job *)); return worker; } /* child closes parent's end of socket and gets busy */ close(sv[0]); if (init_func) { init_func(init_arg); } enter_worker(sv[1]); /* not reached, ever */ exit(EXIT_FAILURE); }
static simple_worker *spawn_worker(void (*init_func)(void *), void *init_arg) { int sv[2]; int pid; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) return NULL; pid = fork(); if (pid < 0) { close(sv[0]); close(sv[1]); return NULL; } /* parent leaves the child */ if (pid) { simple_worker *worker = calloc(1, sizeof(simple_worker)); close(sv[1]); if (!worker) { kill(SIGKILL, pid); close(sv[0]); return NULL; } worker->sd = sv[0]; worker->pid = pid; worker->ioc = iocache_create(1 * 1024 * 1024); return worker; } /* child closes parent's end of socket and gets busy */ close(sv[0]); if (init_func) { init_func(init_arg); } enter_worker(sv[1], start_cmd); /* not reached, ever */ exit(EXIT_FAILURE); }