static const char *run_case(struct Worker *client, struct Worker *server) { struct event_base *base = NULL; int spair[2]; const char *res = "huh"; bool done = false; ignore_sigpipe(); base = event_init(); client->evbase = base; server->evbase = base; tt_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == 0); tt_assert(socket_setup(spair[0], true)); tt_assert(socket_setup(spair[1], true)); str_check(start_worker(client, spair[1]), "OK"); str_check(start_worker(server, spair[0]), "OK"); while (client->ctx || server->ctx) tt_assert(event_base_loop(base, EVLOOP_ONCE) == 0); done = true; end: res = check_errors(client, server); free_worker(client); free_worker(server); event_base_free(base); return done ? res : "fail"; }
void mergesort(int **array, int lo, int hi, worker_pool *wp) { LOGGER(); int mid = (hi + lo) / 2; pthread_t *th1, *th2; if (lo < hi){ /* spin up a new thread to handle it if we can, if not, continue */ /* in the current thread */ if(!(th1 = start_worker(array, lo, mid, wp))){ mergesort(array, lo, mid, wp); } if(!(th2 = start_worker(array, mid + 1, hi, wp))){ mergesort(array, mid + 1, hi, wp); } /* block until as many threads return as necessary */ if(th1){ return_worker(wp, th1); } if(th2){ return_worker(wp, th2); } merge(array, lo, mid, hi); } }
void* scan_worker(void *args) { int current_id; while (1) { current_id = 0; pthread_mutex_lock(&lock); if (id_queue[scan_index] <= 0) { /* queue is empty */ if (settings.verbose > 0) { printf("[scan_worker] cond_wait id\n"); } pthread_cond_wait(&cond, &lock); if (settings.verbose > 0) { printf("[scan_worker] cond_wait_done id\n"); } } if (id_queue[scan_index] > 0) { current_id = id_queue[scan_index]; id_queue[scan_index] = 0; scan_index++; if (scan_index >= settings.queuesize) scan_index = 0; } pthread_mutex_unlock(&lock); /* now check current id */ if (current_id >0) { pthread_mutex_lock(&workerlock); if (concurrent_workers >= settings.workernum) { if (settings.verbose > 0) { printf("[scan_worker] cond_wait worker\n"); } pthread_cond_wait(&workercond, &workerlock); if (settings.verbose > 0) { printf("[scan_worker] cond_wait_done worker\n"); } } if (concurrent_workers < settings.workernum) { concurrent_workers++; if (settings.verbose > 1) { printf("[scan_worker] start a worker (%d), num %d max%d\n", current_id, concurrent_workers, settings.workernum); } } else { current_id = 0; } pthread_mutex_unlock(&workerlock); if (current_id > 0) start_worker(current_id); current_id = 0; } } return NULL; }
void WINAPI NWNXServiceStart(DWORD argc, LPTSTR *argv) { DWORD status; DWORD specificError; TCHAR serviceName[64]; NWNXServiceStatus.dwServiceType = SERVICE_WIN32; NWNXServiceStatus.dwCurrentState = SERVICE_START_PENDING; NWNXServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; NWNXServiceStatus.dwWin32ExitCode = 0; NWNXServiceStatus.dwServiceSpecificExitCode = 0; NWNXServiceStatus.dwCheckPoint = 0; NWNXServiceStatus.dwWaitHint = 0; _stprintf_s(serviceName, 64, wxT("NWNX4-%d"), serviceNo); NWNXServiceStatusHandle = RegisterServiceCtrlHandler(serviceName, NWNXServiceCtrlHandler); if (NWNXServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) { wxLogError(wxT("* RegisterServiceCtrlHandler failed %d"), GetLastError()); return; } // Initialization code goes here. status = NWNXServiceInitialization(argc,argv, &specificError); // Handle error condition if (status != NO_ERROR) { NWNXServiceStatus.dwCurrentState = SERVICE_STOPPED; NWNXServiceStatus.dwCheckPoint = 0; NWNXServiceStatus.dwWaitHint = 0; NWNXServiceStatus.dwWin32ExitCode = status; NWNXServiceStatus.dwServiceSpecificExitCode = specificError; SetServiceStatus(NWNXServiceStatusHandle, &NWNXServiceStatus); return; } // Initialization complete - report running status. NWNXServiceStatus.dwCurrentState = SERVICE_RUNNING; NWNXServiceStatus.dwCheckPoint = 0; NWNXServiceStatus.dwWaitHint = 0; if (!SetServiceStatus(NWNXServiceStatusHandle, &NWNXServiceStatus)) { status = GetLastError(); wxLogError(wxT("* SetServiceStatus error %ld"), status); } // This is where the service does its work. start_worker(); return; }
work_queue_for_tests::work_queue_for_tests (const sync_function_type & sync_func) : work_queue (work_queue::dont_start_worker ()) , _current_time_point (work_queue::clock_type::now ()) , _time_forwarding_flag (false) , _time_forwarding_completed () , _time_forwarding_client_id (work_queue::INVALID_CLIENT_ID) , _sync_function (sync_func) { _time_forwarding_client_id = get_client_id (); start_worker (); }
void convert(rs2::frameset& frameset) override { start_worker( [this, &frameset] { for (size_t i = 0; i < frameset.size(); i++) { auto frame = frameset[i].as<rs2::depth_frame>(); if (frame && (_streamType == rs2_stream::RS2_STREAM_ANY || frame.get_profile().stream_type() == _streamType)) { if (frames_map_get_and_set(frame.get_profile().stream_type(), frame.get_frame_number())) { continue; } std::stringstream filename; filename << _filePath << "_" << frame.get_profile().stream_name() << "_" << frame.get_frame_number() << ".csv"; std::string filenameS = filename.str(); add_sub_worker( [filenameS, frame] { std::ofstream fs(filenameS, std::ios::trunc); if (fs) { for (int y = 0; y < frame.get_height(); y++) { auto delim = ""; for (int x = 0; x < frame.get_width(); x++) { fs << delim << frame.get_distance(x, y); delim = ","; } fs << '\n'; } fs.flush(); } }); } } wait_sub_workers(); }); }
void convert(rs2::frameset& frameset) override { start_worker( [this, &frameset] { for (size_t i = 0; i < frameset.size(); i++) { rs2::video_frame frame = frameset[i].as<rs2::video_frame>(); if (frame && (_streamType == rs2_stream::RS2_STREAM_ANY || frame.get_profile().stream_type() == _streamType)) { if (frames_map_get_and_set(frame.get_profile().stream_type(), frame.get_frame_number())) { continue; } if (frame.get_profile().stream_type() == rs2_stream::RS2_STREAM_DEPTH) { frame = _colorizer(frame); } std::stringstream filename; filename << _filePath << "_" << frame.get_profile().stream_name() << "_" << frame.get_frame_number() << ".png"; std::string filenameS = filename.str(); add_sub_worker( [filenameS, frame] { stbi_write_png( filenameS.c_str() , frame.get_width() , frame.get_height() , frame.get_bytes_per_pixel() , frame.get_data() , frame.get_stride_in_bytes() ); }); } } wait_sub_workers(); }); }
/* * Start the number of worker processes requested in the server * configuration. * * Returns a pointer to an array of PIDs on success and NULL on error. */ static pid_t *create_workers(int passive_sock) { size_t i, j; pid_t *pids = malloc(g_config.num_workers * sizeof(pid_t)); if (!pids) { log_perror(NULL, "Couldn't allocate array to store worker PIDs"); return NULL; } for (i = 0; i < g_config.num_workers; ++i) { if ((pids[i] = start_worker(passive_sock)) == -1) { log_perror(NULL, "Couldn't fork worker to handle connections"); for (j = 0; i < i; ++j) { kill(pids[j], SIGTERM); } return NULL; } } return pids; }
int thread_init(int num_of_threads){ int i; pthread_mutex_init(&init_lock, NULL); pthread_cond_init(&init_cond, NULL); pthread_mutex_init(&cqi_freelist_lock, NULL); cqi_freelist = NULL; thread_cgs = calloc(num_of_threads, sizeof(thread_cg)); if(!thread_cgs){ perror("can't alloc thread_cg"); exit(1); } dispatcher_thread.base = main_base; dispatcher_thread.thread_id = pthread_self(); for(i = 0; i < num_of_threads; i++){ int fds[2]; if(pipe(fds)){ perror("can't create notify pipe"); exit(1); } thread_cgs[i].read_fd = fds[0]; thread_cgs[i].write_fd = fds[1]; setup_thread(&thread_cgs[i]); } //未完成,需要等待现成完成setup,然后才退出函数 for(i = 0; i < num_of_threads; i++){ start_worker(worker_libevent, &thread_cgs[i]); } pthread_mutex_lock(&init_lock); while (init_count < NUM_OF_THREADS) { pthread_cond_wait(&init_cond, &init_lock); } pthread_mutex_unlock(&init_lock); }
int start_workers() { int i = 0; // int fd[2]; // pid_t pid; master_pid = getpid(); for(i = 0; i < WORKER_NUM; i++){ /*if(socketpair( AF_UNIX, SOCK_STREAM, 0, fd) < 0) { perror( "socketpair()" ); return L_HTTP_FAIL; } if(set_nonblocking(fd[0]) == L_HTTP_FAIL || set_nonblocking(fd[1]) == L_HTTP_FAIL) return L_HTTP_FAIL; if ((pid = fork ()) == 0) { printf("fork success: %d\n", getpid()); worker_main(fd); exit(1); } else if(pid < 0){ syslog (LOG_INFO, "fork error"); printf("fork error"); return L_HTTP_FAIL; } workers[i].pid = pid; workers[i].slot = i; workers[i].fd[0] = fd[0]; workers[i].fd[1] = fd[1]; close(fd[1]); */ start_worker(i); } return L_HTTP_SUCCESS; }
int reset_worker(pid_t pid) { int i = 0; for(i = 0; i < WORKER_NUM; i++) { if(workers[i].pid == pid) { workers[i].pid = -1; close(workers[i].fd[0]); workers[i].fd[0] = -1; workers[i].fd[1] = -1; syslog(LOG_INFO, "proc:%d reset", pid); break; } } if(i == WORKER_NUM) return L_HTTP_FAIL; //todo: restart a worker return start_worker(i); }
void fake_main(void) { signal(SIGPIPE, SIG_IGN); int listenfd, err, i; pid_t pid;//, contact[WORKER]; struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons((getuid() == 0) ? 80 : 8080); if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) FATAL("FAKE_MAIN.SOCKET"); if((err = bind(listenfd, (SA *)&servaddr, sizeof(servaddr))) < 0) FATAL("FAKE_MAIN.BIND"); if((err = listen(listenfd, 1024)) < 0) FATAL("FAKE_MAIN.LISTEN"); for(i = 0; i < WORKER; ++i) { if((pid = fork()) == 0) start_worker(listenfd); else if(pid < 0) //contact[i] = pid; FATAL("FAKE_MAIN.FORK"); } for(;;) { //TODO pause(); } }
int main (int argc, char *argv[]) { int from_z3[2]; int from_yices[2]; int status; if (argc < 2) { fprintf(stderr, "usage: %s file\n", argv[0]); exit(1); } FILE *z3file = fopen(argv[1], "r"); FILE *yicesfile = fopen(argv[1], "r"); assert(z3file != NULL); assert(yicesfile != NULL); //Set up the pipes to talk to the solvers status = pipe(from_z3); assert(status == 0); status = pipe(from_yices); assert(status == 0); start_solver(Z3, fileno(z3file), from_z3[1]); start_solver(YICES, fileno(yicesfile), from_yices[1]); assert(z3file != NULL); assert(yicesfile != NULL); fclose(z3file); fclose(yicesfile); //Set up our in process sockets context = zmq_ctx_new (); //Setup the controller as the sink void *responder = zmq_socket (context, ZMQ_PULL); int rc = zmq_bind (responder, "inproc://controller"); assert (rc == 0); //Set to receive all messages //int sk = zmq_setsockopt (responder, ZMQ_SUBSCRIBE, NULL, 0); //assert (sk == 0); //Set up our workers (Solvers) void *skz3 = zmq_socket(context, ZMQ_PUSH); rc = zmq_connect(skz3, "inproc://controller"); assert (rc == 0); void *skyices = zmq_socket(context, ZMQ_PUSH); rc = zmq_connect(skyices, "inproc://controller"); assert (rc == 0); //Start the controller / worker threads pthread_t control; status = pthread_create(&control, NULL, control_worker, (void*)responder); assert(status == 0); start_worker(Z3, skz3, from_z3[0]); start_worker(YICES, skyices, from_yices[0]); while(1) sched_yield(); return 0; }
int main(int argc, char** argv) { fprintf(stderr, "\nMinecraft 1.2.5 virtual client packet generator\n"); char address[256]; char port[256]; int i; fprintf(stderr, "Server Address : "); fgets(address, 256, stdin); fprintf(stderr, "Server Port : "); fgets(port, 256, stdin); /* for(i=0; i<strlen(address); i++){ if(address[i]=='\n') address[i]='\0'; } for(i=0; i<strlen(port); i++){ if(address[i]=='\n') address[i]='\0'; } */ struct sockaddr_in addr; memset(&addr, 0x00, sizeof(addr) ); addr.sin_family = AF_INET; addr.sin_port = htons(atoi(port)); addr.sin_addr.s_addr = inet_addr(address); if( addr.sin_addr.s_addr == INADDR_NONE ){ perror("bad address"); exit(1); } pid_t *pid_worker=(pid_t *)malloc(sizeof(pid_t)*NUM_WORKERS); if(pid_worker==NULL) { perror("pid_worker malloc()"); } int *sv_worker=(int *)malloc(sizeof(int)*NUM_WORKERS); if(sv_worker==NULL) { perror("sv_worker malloc()"); } fprintf(stderr,"\n"); for(i=0; i<NUM_WORKERS; i++){ int sv[2]; if(socketpair(AF_UNIX,SOCK_STREAM,0,sv)!=0) { perror("master socketpair()"); } pid_worker[i]=start_worker(addr, sv[1]); sv_worker[i]=dup(sv[0]); close(sv[0]); close(sv[1]); fprintf(stderr, "\rNow constructing client [%d of %d]\t", i+1, NUM_WORKERS); usleep(100000); } fprintf(stderr, "\n Done. %d clients sending %dpackets.\n",NUM_WORKERS, PACKETS_SEC); while(1){ sleep(1); } return 0; }
long main(long argc, char ** argv) { char c_low_limit[10]; char c_top_limit[10]; long n_low_limit; long n_top_limit; long n_top_low_flag=0;//only to parse incoming parameters long residue; struct Processes processes[10]; memset(c_low_limit, '\0', strlen(c_low_limit)); memset(c_top_limit, '\0', strlen(c_top_limit)); if(argc != 5) { printf("Error. Use format: \n -p <process_count> -r <low_limit>:<top_limit>\n"); return 1; } long i=1; for(i=0;i<strlen(argv[4]);i++) { if(argv[4][i]!=':') { if(n_top_low_flag==0) { strncat(c_low_limit, &argv[4][i],1); } else { strncat(c_top_limit, &argv[4][i],1); } } else { n_top_low_flag = 1; n_low_limit = atoi(c_low_limit); } } n_top_limit = atoi(c_top_limit); if((n_top_limit - n_low_limit) % atoi(argv[2])==0) { residue = (n_top_limit - n_low_limit) % atoi(argv[2]); } else { residue = 0; } for(i=0;i<atoi(argv[2])&&getppid()!=0;i++) { char pathname[40]; char range[40]; char temp_string[10]; char p_number[4]; memset(range, '\0', strlen(range)); memset(temp_string, '\0', strlen(temp_string)); memset(pathname, '\0', strlen(pathname)); memset(p_number, '\0', strlen(p_number)); strcat(pathname,"worker\0"); sprintf(p_number,"%d", i); strcat(pathname,p_number); if (mkfifo(&pathname, S_IRUSR|S_IWUSR)) { printf("Can not create FIFO"); return 1; } processes[i].p_low_limit = ((n_top_limit-residue-n_low_limit)/atoi(argv[2]))*i+n_low_limit; processes[i].p_top_limit = ((n_top_limit-residue-n_low_limit)/atoi(argv[2]))+processes[i].p_low_limit; processes[i].fifofd = open(pathname,O_RDWR); if(processes[i].fifofd==-1) { printf("Could not open named pipe"); return 1; } sprintf(temp_string, ":%d", processes[i].p_top_limit); sprintf(range, "%d", processes[i].p_low_limit); strcat(range, temp_string); write(processes[i].fifofd,range,strlen(range)); processes[i].p_number = i; processes[i].pid = fork(); if(processes[i].pid==0) { start_worker(i); return 0; } else { printf("created new proccess with id %d\n", processes[i].pid ); printf("range: %s\n", range); } } for(i=0;(i<atoi(argv[2]))&&processes[0].pid;i++) { char p_number[5]; char buff[100000]; char pathname[20]; memset(buff,'\0',strlen(buff)); memset(pathname, '\0', strlen(pathname)); printf("wait to complete pid %d\n", processes[i].pid ); waitpid(processes[i].pid,NULL,NULL); read(processes[i].fifofd,buff,100000 ); printf(buff); strcpy(pathname,"worker\0"); sprintf(p_number,"%d",i); strcat(pathname, p_number); unlink(pathname); } return 0; }
ThreadedOFStreamWriter::ThreadedOFStreamWriter( std::ofstream* stream ) : StreamWriter( ), _stream( stream ), _msg_queue( ), _writethread( ), _writers_hold( ), _stream_name() { start_worker(); }
int workqueue_init(struct thread_data *td, struct workqueue *wq, workqueue_fn *fn, unsigned max_pending) { unsigned int running; int i, error; wq->max_workers = max_pending; wq->td = td; wq->fn = fn; wq->work_seq = 0; wq->next_free_worker = 0; pthread_cond_init(&wq->flush_cond, NULL); pthread_mutex_init(&wq->flush_lock, NULL); pthread_mutex_init(&wq->stat_lock, NULL); wq->workers = calloc(wq->max_workers, sizeof(struct submit_worker)); for (i = 0; i < wq->max_workers; i++) if (start_worker(wq, i)) break; wq->max_workers = i; if (!wq->max_workers) goto err; /* * Wait for them all to be started and initialized */ error = 0; do { struct submit_worker *sw; running = 0; pthread_mutex_lock(&wq->flush_lock); for (i = 0; i < wq->max_workers; i++) { sw = &wq->workers[i]; pthread_mutex_lock(&sw->lock); if (sw->flags & SW_F_RUNNING) running++; if (sw->flags & SW_F_ERROR) error++; pthread_mutex_unlock(&sw->lock); } if (error || running == wq->max_workers) { pthread_mutex_unlock(&wq->flush_lock); break; } pthread_cond_wait(&wq->flush_cond, &wq->flush_lock); pthread_mutex_unlock(&wq->flush_lock); } while (1); if (!error) return 0; err: log_err("Can't create rate workqueue\n"); td_verror(td, ESRCH, "workqueue_init"); workqueue_exit(wq); return 1; }
/* main tests */ int main (int argc, char **argv, char **env) { argc = argc; argv = argv; env = env; int status, chld, rc; int tests = 125; int rrc; char cmd[150]; char *result, *error, *message, *output; plan(tests); mod_gm_opt = malloc(sizeof(mod_gm_opt_t)); set_default_options(mod_gm_opt); #ifdef EMBEDDEDPERL char p1[150]; snprintf(p1, 150, "--p1_file=worker/mod_gearman_p1.pl"); parse_args_line(mod_gm_opt, p1, 0); init_embedded_perl(env); #endif char options[150]; snprintf(options, 150, "--server=127.0.0.1:%d", GEARMAND_TEST_PORT); ok(parse_args_line(mod_gm_opt, options, 0) == 0, "parse_args_line()"); mod_gm_opt->debug_level = GM_LOG_ERROR; worker_logfile = my_tmpfile(); if(!ok(worker_logfile != NULL, "created temp logile: %s", worker_logfile)) { diag("could not create temp logfile"); exit( EXIT_FAILURE ); } /* first fire up a gearmand server and one worker */ start_gearmand((void*)NULL); sleep(2); start_worker((void*)NULL); sleep(2); /* wait one second and catch died procs */ while((chld = waitpid(-1, &status, WNOHANG)) != -1 && chld > 0) { diag( "waitpid() %d exited with %d\n", chld, status); status = 0; } if(!ok(gearmand_pid > 0, "'gearmand started with port %d and pid: %d", GEARMAND_TEST_PORT, gearmand_pid)) { diag("make sure gearmand is in your PATH. Common locations are /usr/sbin or /usr/local/sbin"); exit( EXIT_FAILURE ); } if(!ok(pid_alive(gearmand_pid) == TRUE, "gearmand alive")) { check_logfile("/tmp/gearmand.log", 3); kill(gearmand_pid, SIGTERM); kill(worker_pid, SIGTERM); exit( EXIT_FAILURE ); } if(!ok(worker_pid > 0, "worker started with pid: %d", worker_pid)) diag("could not start worker"); if(!ok(pid_alive(worker_pid) == TRUE, "worker alive")) { check_logfile(worker_logfile, 3); kill(gearmand_pid, SIGTERM); kill(worker_pid, SIGTERM); exit( EXIT_FAILURE ); } skip(gearmand_pid <= 0 || worker_pid <= 0, tests-3, /* Number of tests to skip */ "Skipping all tests, no need to go on without gearmand or worker"); /* create server / clients */ mod_gm_opt->transportmode = GM_ENCODE_ONLY; create_modules(); /* send big job */ send_big_jobs(GM_ENCODE_ONLY); //diag_queues(); wait_for_empty_queue("eventhandler", 20); wait_for_empty_queue("service", 20); //diag_queues(); do_result_work(1); //diag_queues(); wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5); /***************************************** * test check */ //diag_queues(); test_servicecheck(GM_ENCODE_ONLY, "./t/crit.pl"); //diag_queues(); wait_for_empty_queue("eventhandler", 20); wait_for_empty_queue("service", 5); //diag_queues(); do_result_work(1); //diag_queues(); wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5); //diag_queues(); like(last_result, "test plugin CRITICAL", "stdout output from ./t/crit.pl"); like(last_result, "some errors on stderr", "stderr output from ./t/crit.pl"); /***************************************** * test check2 */ //diag_queues(); test_servicecheck(GM_ENCODE_ONLY, "./t/both"); //diag_queues(); wait_for_empty_queue("eventhandler", 20); wait_for_empty_queue("service", 5); //diag_queues(); do_result_work(1); //diag_queues(); wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5); like(last_result, "stdout output", "stdout output from ./t/both"); like(last_result, "stderr output", "stderr output from ./t/both"); /* try to send some data with base64 only */ //diag_queues(); test_eventhandler(GM_ENCODE_ONLY); //diag_queues(); test_servicecheck(GM_ENCODE_ONLY, NULL); //diag_queues(); wait_for_empty_queue("eventhandler", 20); wait_for_empty_queue("service", 5); //diag_queues(); do_result_work(1); //diag_queues(); wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5); sleep(1); kill(worker_pid, SIGTERM); waitpid(worker_pid, &status, 0); ok(status == 0, "worker (%d) exited with exit code %d", worker_pid, real_exit_code(status)); status = 0; check_no_worker_running(worker_logfile); check_logfile(worker_logfile, 0); char * test_keys[] = { "12345", "test", "test key 123", "me make you loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong key" }; /* ignore some signals for now */ signal(SIGTERM, SIG_IGN); int i; for(i=0;i<4;i++) { mod_gm_opt->transportmode = GM_ENCODE_AND_ENCRYPT; start_worker((void *)test_keys[i]); mod_gm_crypt_init( test_keys[i] ); ok(1, "initialized with key: %s", test_keys[i]); test_eventhandler(GM_ENCODE_AND_ENCRYPT); test_servicecheck(GM_ENCODE_AND_ENCRYPT, NULL); wait_for_empty_queue("eventhandler", 20); wait_for_empty_queue("service", 5); do_result_work(1); wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5); sleep(1); kill(worker_pid, SIGTERM); waitpid(worker_pid, &status, 0); ok(status == 0, "worker (%d) exited with exit code %d", worker_pid, real_exit_code(status)); status = 0; check_no_worker_running(worker_logfile); check_logfile(worker_logfile, 0); } /***************************************** * send_gearman */ snprintf(cmd, 150, "./send_gearman --server=127.0.0.1:%d --key=testtest --host=test --service=test --message=test --returncode=0", GEARMAND_TEST_PORT); rrc = real_exit_code(run_check(cmd, &result, &error)); cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc); like(result, "^\\s*$", "output from ./send_gearman"); free(result); free(error); /***************************************** * send_multi */ snprintf(cmd, 150, "./send_multi --server=127.0.0.1:%d --host=blah < t/data/send_multi.txt", GEARMAND_TEST_PORT); rrc = real_exit_code(run_check(cmd, &result, &error)); cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc); like(result, "send_multi OK: 2 check_multi child checks submitted", "output from ./send_multi"); free(result); free(error); /***************************************** * check_gearman */ snprintf(cmd, 150, "./check_gearman -H 127.0.0.1:%d -s check -a -q worker_test", GEARMAND_TEST_PORT); rrc = real_exit_code(run_check(cmd, &result, &error)); cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc); like(result, "check_gearman OK - sending background job succeded", "output from ./check_gearman"); /* cleanup */ free(result); free(error); free_client(&client); free_worker(&worker); /* shutdown gearmand */ rc = send2gearmandadmin("shutdown\n", "127.0.0.1", GEARMAND_TEST_PORT, &output, &message); ok(rc == 0, "rc of send2gearmandadmin %d", rc); like(output, "OK", "output contains OK"); free(message); free(output); /* wait 5 seconds to shutdown */ for(i=0;i<=5;i++) { waitpid(gearmand_pid, &status, WNOHANG); if(pid_alive(gearmand_pid) == FALSE) { todo(); ok(status == 0, "gearmand (%d) exited with: %d", gearmand_pid, real_exit_code(status)); endtodo; break; } sleep(1); } if(pid_alive(gearmand_pid) == TRUE) { /* kill it the hard way */ kill(gearmand_pid, SIGTERM); waitpid(gearmand_pid, &status, 0); ok(status == 0, "gearmand (%d) exited with exit code %d", gearmand_pid, real_exit_code(status)); status = 0; ok(false, "gearmand had to be killed!"); } todo(); check_logfile("/tmp/gearmand.log", status != 0 ? 2 : 0); endtodo; status = 0; kill(worker_pid, SIGTERM); waitpid(worker_pid, &status, 0); ok(status == 0, "worker (%d) exited with exit code %d", worker_pid, real_exit_code(status)); check_no_worker_running(worker_logfile); status = 0; #ifdef EMBEDDEDPERL deinit_embedded_perl(0); #endif free(last_result); free(worker_logfile); endskip; mod_gm_free_opt(mod_gm_opt); return exit_status(); }
void worker_mgr_t::check_load(uint32_t ctx_num) { if (!m_exiting && m_worker_num < m_max_worker_num && (ctx_num > m_worker_num * WORKER_LOAD_THRESHOLD)) { start_worker(ctx_num); } }
size_t get_worker(void) { // get a worker // off, so we don't check worker 0 a million times static size_t off = -1; static int tries = 0; ++off; int which; for(which=0;which<numworkers;++which) { size_t derp = (which+off)%numworkers; switch(workers[derp].status) { case IDLE: workers[derp].status = BUSY; PFD(derp).events = POLLIN; tries = 0; return derp; }; } if(tries < 3) { ++tries; // if we timeout 3 times, stop waiting for idle workers. return -1; } /* no idle found, try starting some workers */ if(numworkers < MAXWORKERS) { // add a worker to the end if(start_worker()) { tries = 0; return numworkers-1; } } else { reap_workers(); for(which=0;which<numworkers;++which) { if(workers[which].status == DOOMED) { /* if 995 ns left (expiration - now) and doom delay is 1000ns 1000 - 995 < 50, so wait a teensy bit longer please */ Time diff = timediff(DOOM_DELAY, timediff(workers[which].expiration, getnow())); if(diff.tv_nsec > 50) { // waited too long, kill the thing. kill_worker(which); if(start_worker()) { tries = 0; return numworkers-1; } } } } } if(wait_for_accept()) { if(accept_workers()) { return get_worker(); } } // have to wait until the new worker connects errno = EAGAIN; // eh return -1; }
int main(int argc, char **argv) { int passive_sock = -1; struct sigaction sig = { 0 }; pid_t *worker_pids = NULL; /* Record out PID for future reference. */ g_server_pid = getpid(); /* Set up logging. */ openlog("seamonster", LOG_PERROR | LOG_PID, LOG_DAEMON); /* Set up signal handling. */ sig.sa_handler = sigterm_handler; if (sigaction(SIGTERM, &sig, NULL)) { perror("Couldn't set SIGTERM handler\n"); return 1; } /* Parse command line arguments. */ errno = 0; if (parse_config(argc, argv)) { return !!errno; } /* If requested, run as a daemon and set up logging. */ if (g_config.daemonize && daemonize()) { return 1; } /* Create a passive socket to listen for connection requests. */ if ((passive_sock = create_passive_sock()) == -1) { return 1; } log_info(NULL, "Listening on port %hu", g_config.port); /* Fork off some children to handle clients. */ log_info(NULL, "Starting with %lu worker%s", (unsigned long) g_config.num_workers, g_config.num_workers != 1 ? "s" : ""); log_info(NULL, "Serving %lu connection%s each", (unsigned long) g_config.conns_per_worker, g_config.conns_per_worker != 1 ? "s" : ""); if (!(worker_pids = create_workers(passive_sock))) { return 1; } /* Kill all workers on when the parent terminates cleanly, and restart any * workers that die prematurely. */ for (;;) { size_t i; pid_t worker_pid; int stat_loc; /* On SIGTERM, kill all worker processes. */ if (g_terminating == 1) { log_info(NULL, "Killing workers on SIGTERM"); for (i = 0; i < g_config.num_workers; ++i) { if (worker_pids[i] != -1) { kill(worker_pids[i], SIGTERM); } } g_terminating = 2; } /* Wait for something to happen to a worker. (If there are no more workers * to wait for, then we're done.) */ if ((worker_pid = wait(&stat_loc)) == -1) { if (errno == ECHILD) { break; } if (errno == EINTR) { continue; } log_perror(NULL, "Couldn't wait for workers to die"); return 1; } /* If we aren't currently terminating, then we should restart workers when * they die. */ if (!g_terminating && (WIFEXITED(stat_loc) || WIFSIGNALED(stat_loc))) { log_warn(NULL, "Worker %ld died; restarting", (long) worker_pid); for (i = 0; i < g_config.num_workers; ++i) { if (worker_pids[i] == worker_pid) { if ((worker_pids[i] = start_worker(passive_sock)) == -1) { log_perror(NULL, "Couldn't restart worker"); } break; } } } } return 0; }
int main(int argc, char **argv) { INIT_GLB_VARS(); SET_PROCESS_ROLE(PROCESS_ROLE_MASTER); SET_CHILD_PROCESS(PROCESS_ROLE_MASTER, getpid()); /* 此处注册清理函数, 以便主进程由于某些原因退出时, kill掉 * 启动的所有子进程. 但man atexit可知, 通过fork的子进程会 * 继承atexit的注册链, 而exec后将抛弃此注册链. * <NOTE> 此处不考虑fork子进程也执行此函数带来的影响 */ (void)atexit(kill_child_all); if (log_init() == RET_ERR) { SDNS_LOG_ERR("LOG init failed"); exit(EXIT_FAILURE); } if (zone_init() == RET_ERR) { SDNS_LOG_ERR("ZONE init failed"); exit(EXIT_FAILURE); } if (get_options(argc, argv) == RET_ERR) { SDNS_LOG_ERR("parse cmdline failed"); usage_help(); exit(EXIT_FAILURE); } if (IS_PROCESS_ROLE(PROCESS_ROLE_SIGNALLER)) { process_option_signal(); exit(EXIT_SUCCESS); } if (IS_PROCESS_ROLE(PROCESS_ROLE_HELPER)) { usage_help(); exit(EXIT_SUCCESS); } if (start_monitor() == RET_ERR) { exit(EXIT_FAILURE); } if (parse_conf() == RET_ERR) { exit(EXIT_FAILURE); } if (IS_PROCESS_ROLE(PROCESS_ROLE_TESTER)) { SDNS_LOG_DEBUG("配置文件测试OK"); print_parse_res(); exit(EXIT_SUCCESS); } if (pkt_engine_init() == RET_ERR) { SDNS_LOG_ERR("engine init failed"); exit(EXIT_FAILURE); } if (set_required_signal() == RET_ERR || block_required_signal() == RET_ERR) { SDNS_LOG_ERR("signal init failed"); exit(EXIT_FAILURE); } if (sort_init() == RET_ERR) { SDNS_LOG_ERR("sort init failed"); exit(EXIT_FAILURE); } start_worker(); if (start_pkt_engine() == RET_ERR) { SDNS_LOG_ERR("start engine failed"); exit(EXIT_FAILURE); } for(;;) { (void)wait_required_signal(); (void)process_signals(); } exit(EXIT_SUCCESS); }
/* * Adds a HASH to the message using @hash_key, or adds "NOHASH" if @hash_key is %NULL * * If there is an error, then gda_connection_add_event_string() is called * * @out_status_chr, if NOT NULL will contain the 1st char of the <status> node's contents */ xmlDocPtr _gda_web_send_message_to_frontend (GdaConnection *cnc, WebConnectionData *cdata, WebMessageType msgtype, const gchar *message, const gchar *hash_key, gchar *out_status_chr) { SoupMessage *msg; guint status; gchar *h_message; gchar *real_url; static gint counter = 0; if (out_status_chr) *out_status_chr = 0; /* handle the need to run the worker to get an initial sessionID */ g_rec_mutex_lock (& (cdata->mutex)); cdata->worker_needed = TRUE; if (!cdata->worker_running && !cdata->session_id) { g_rec_mutex_unlock (& (cdata->mutex)); start_worker (cnc, cdata); g_rec_mutex_lock (& (cdata->mutex)); if (! cdata->worker_running) { gda_connection_add_event_string (cnc, _("Could not run PHP script on the server")); cdata->worker_needed = FALSE; g_rec_mutex_unlock (& (cdata->mutex)); return NULL; } } /* prepare new message */ g_assert (cdata->session_id); real_url = g_strdup_printf ("%s?%s&c=%d", cdata->front_url, cdata->session_id, counter++); g_rec_mutex_unlock (& (cdata->mutex)); msg = soup_message_new ("POST", real_url); if (!msg) { gda_connection_add_event_string (cnc, _("Invalid HOST/SCRIPT '%s'"), real_url); g_free (real_url); return NULL; } g_free (real_url); /* check context */ g_rec_mutex_lock (& (cdata->mutex)); if (gda_connection_get_transaction_status (cnc) && (!cdata->worker_running || ((msgtype == MESSAGE_EXEC) && (cdata->last_exec_counter != cdata->worker_counter)))) { /* update cdata->last_exec_counter so next statement can be run */ cdata->last_exec_counter = cdata->worker_counter; gda_connection_add_event_string (cnc, _("The transaction has been automatically rolled back")); g_object_unref (msg); gda_connection_internal_reset_transaction_status (cnc); g_rec_mutex_unlock (& (cdata->mutex)); return NULL; } if (! cdata->worker_running) { g_rec_mutex_unlock (& (cdata->mutex)); start_worker (cnc, cdata); g_rec_mutex_lock (& (cdata->mutex)); if (! cdata->worker_running) { gda_connection_add_event_string (cnc, _("Could not run PHP script on the server")); g_object_unref (msg); g_rec_mutex_unlock (& (cdata->mutex)); return NULL; } } g_rec_mutex_unlock (& (cdata->mutex)); /* finalize and send message */ if (hash_key) { gchar *md5str; md5str = g_compute_hmac_for_string (G_CHECKSUM_MD5, hash_key, strlen (hash_key), message, -1); GString *string; string = g_string_new (md5str); g_free (md5str); g_string_append_c (string, '\n'); g_string_append (string, message); h_message = g_string_free (string, FALSE); } else h_message = g_strdup_printf ("NOHASH\n%s", message); #ifdef DEBUG_WEB_PROV g_print ("=== START of request ===\n%s\n=== END of request ===\n", h_message); #endif soup_message_set_request (msg, "text/plain", SOUP_MEMORY_COPY, h_message, strlen (h_message)); g_free (h_message); g_object_set (G_OBJECT (cdata->front_session), SOUP_SESSION_TIMEOUT, 20, NULL); status = soup_session_send_message (cdata->front_session, msg); g_rec_mutex_lock (& (cdata->mutex)); cdata->worker_needed = FALSE; g_rec_mutex_unlock (& (cdata->mutex)); if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { gda_connection_add_event_string (cnc, msg->reason_phrase); g_object_unref (msg); return NULL; } xmlDocPtr doc; guint counter_id; doc = _gda_web_decode_response (cnc, cdata, msg->response_body, out_status_chr, &counter_id); g_object_unref (msg); g_rec_mutex_lock (& (cdata->mutex)); if (msgtype == MESSAGE_EXEC) cdata->last_exec_counter = counter_id; g_rec_mutex_unlock (& (cdata->mutex)); return doc; }
void worker_mgr_t::start() { start_worker(1); }