void init() { const int id(get_thread_num()); if (id == 0) init_master(); else init_worker(id); }
static void reboot(struct line line) { line.data++; line.len--; close(sockets->net[0].fd); init_worker(); q_puts(&sockets->net[0].sendq, "RESTORE"); q_putl(&sockets->net[0].sendq, line, 1); }
static void init() { struct sigaction sig = { .sa_handler = SIG_IGN, }; sigaction(SIGPIPE, &sig, NULL); sigaction(SIGCHLD, &sig, NULL); sig.sa_handler = sig2child; sigaction(SIGHUP, &sig, NULL); sigaction(SIGUSR1, &sig, NULL); sigaction(SIGUSR2, &sig, NULL); fclose(stdin); fclose(stdout); sockets = malloc(sizeof(struct iostate) + 16 * sizeof(struct sockifo)); sockets->size = 16; sockets->count = 1; sockets->net[0].state.type = TYPE_MPLEX; init_worker(); q_puts(&sockets->net[0].sendq, "BOOT 12\n"); writable(&sockets->net[0]); #if SSL_ENABLED ssl_gblinit(); #endif }
/** * initialize children */ static int child_init(int rank) { int i, newpid; if (rank == PROC_MAIN) { /* fork worker processes */ for(i = 0; i < num_workers; i++) { init_worker(&workers[i]); LM_DBG("starting worker process %d\n", i); newpid = fork_process(PROC_NOCHLDINIT, "DMQ WORKER", 0); if(newpid < 0) { LM_ERR("failed to form process\n"); return -1; } else if(newpid == 0) { /* child - this will loop forever */ worker_loop(i); } else { workers[i].pid = newpid; } } /* notification_node - the node from which the Kamailio instance * gets the server list on startup. * the address is given as a module parameter in dmq_notification_address * the module MUST have this parameter if the Kamailio instance is not * a master in this architecture */ if(dmq_notification_address.s) { notification_node = add_server_and_notify(&dmq_notification_address); if(!notification_node) { LM_ERR("cannot retrieve initial nodelist from %.*s\n", STR_FMT(&dmq_notification_address)); return -1; } } return 0; } if(rank == PROC_INIT || rank == PROC_TCP_MAIN) { /* do nothing for the main process */ return 0; } pid = my_pid(); return 0; }
int init_supervisor(supervisor_thread_t *thiz, tesr_config_t *config) { LOG_LOC; int ret = 0; if(thiz && config) { thiz->config = config; if(thiz->config->num_workers == 0) { LOG_WARN("you are running in single threaded mode (num_workers=0)\n"); } ret = bind_dgram_socket(&thiz->sd, &thiz->addr, thiz->config->recv_port); if (ret == 0) { LOG_ERROR("could not bind dgram socket\n"); exit(EXIT_FAILURE); } else { thiz->queue = create_queue(); init_queue(thiz->queue); connect_pipe(&thiz->int_fd, &thiz->ext_fd); thiz->event_loop = EV_DEFAULT; //or ev_default_loop (0); //Set up rate limiting thiz->rate_limiter = create_rate_limiter(); init_rate_limiter(thiz->rate_limiter, thiz->config->irl_max, thiz->config->irl_inactivity_timeout, thiz->config->irl_garbage_collect_count); //Initialize pthread thiz->next_thread_idx = 0; thiz->worker_threads = create_worker_array(thiz->config->num_workers); //We must initialize workers last as we pass the supervisor data to them int th=0; for(th=0; th < thiz->config->num_workers; th++) { thiz->worker_threads[th] = create_worker(); init_worker(thiz->worker_threads[th], thiz, th); pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&thiz->worker_threads[th]->thread, &attr, worker_thread_run, thiz->worker_threads[th]); } ev_io_init(&thiz->udp_read_watcher, udp_read_cb, thiz->sd, EV_READ); ev_io_init(&thiz->inbox_watcher, udp_write_cb, thiz->int_fd, EV_READ); ev_signal_init(&thiz->sigint_watcher, sigint_cb, SIGINT); ev_signal_init(&thiz->sigchld_watcher, sigchld_cb, SIGCHLD); } } return ret; }
static int run_worker(struct worker_data *data) { char buf[PIPE_BUF+1] = {}; char outbuf[PIPE_BUF+1] = {}; char *urls[MAX_URLS]; size_t urls_c; char *p; int res, i; ssize_t len; double bytes; long header_bytes; if(init_worker(data)) return -1; while(1) { if((len = msg_read(data->pipe_r, buf, sizeof(buf))) == -1) { return EXIT_FAILURE; } buf[len] = '\0'; if(strncmp(buf, "STOP", 4) == 0 || len == 0) return destroy_worker(data); if(strncmp(buf, "RESET", 5) == 0) { if((res = reset_worker(data)) != 0) { len = sprintf(outbuf, "ERR %d", res); msg_write(data->pipe_w, outbuf, len); } else { msg_write(data->pipe_w, "OK", sizeof("OK")); } continue; } if(strncmp(buf, "URLLIST ", 8) == 0) { p = buf + 8; data->chunk.enabled = 1; } else if(strncmp(buf, "URL ", 4) == 0) { p = buf + 4; } else { fprintf(stderr, "Unrecognised command '%s'!\n", buf); break; } if(data->debug) { fprintf(stderr, "Getting URL '%s'.\n", p); } curl_easy_setopt(data->curl, CURLOPT_URL, p); data->chunk.size = 0; if((res = curl_easy_perform(data->curl)) != CURLE_OK) { len = sprintf(outbuf, "ERR %d", res); msg_write(data->pipe_w, outbuf, len); } else { if((res = curl_easy_getinfo(data->curl, CURLINFO_SIZE_DOWNLOAD, &bytes)) != CURLE_OK || (res = curl_easy_getinfo(data->curl, CURLINFO_HEADER_SIZE, &header_bytes)) != CURLE_OK ) { fprintf(stderr, "cURL error: %s\n", curl_easy_strerror(res)); } if(data->chunk.enabled == 0) { len = sprintf(outbuf, "OK %lu bytes", (long)bytes + header_bytes); msg_write(data->pipe_w, outbuf, len); } else { urls_c = parse_urls(data->chunk.memory, data->chunk.size, urls, MAX_URLS); len = sprintf(outbuf, "OK %lu bytes %lu urls", (long)bytes + header_bytes, (long)urls_c); msg_write(data->pipe_w, outbuf, len); for(i = 0; i < urls_c; i++) { len = sprintf(outbuf, "%s", urls[i]); msg_write(data->pipe_w, outbuf, len); free(urls[i]); } data->chunk.enabled = 0; } } } return 0; }
static int reset_worker(struct worker_data *data) { destroy_worker(data); return init_worker(data); }
int main(int argc, char **argv) { int forks = 1; array_t(char*) addr_set; array_init(addr_set); char *keyfile = NULL; const char *config = NULL; char *keyfile_buf = NULL; /* Long options. */ int c = 0, li = 0, ret = 0; struct option opts[] = { {"addr", required_argument, 0, 'a'}, {"config", required_argument, 0, 'c'}, {"keyfile",required_argument, 0, 'k'}, {"forks",required_argument, 0, 'f'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; while ((c = getopt_long(argc, argv, "a:c:f:k:vVh", opts, &li)) != -1) { switch (c) { case 'a': array_push(addr_set, optarg); break; case 'c': config = optarg; break; case 'f': g_interactive = 0; forks = atoi(optarg); if (forks == 0) { kr_log_error("[system] error '-f' requires number, not '%s'\n", optarg); return EXIT_FAILURE; } #if (!defined(UV_VERSION_HEX)) || (!defined(SO_REUSEPORT)) if (forks > 1) { kr_log_error("[system] libuv 1.7+ is required for SO_REUSEPORT support, multiple forks not supported\n"); return EXIT_FAILURE; } #endif break; case 'k': keyfile_buf = malloc(PATH_MAX); assert(keyfile_buf); /* Check if the path is absolute */ if (optarg[0] == '/') { keyfile = strdup(optarg); } else { /* Construct absolute path, the file may not exist */ keyfile = realpath(".", keyfile_buf); if (keyfile) { int len = strlen(keyfile); int namelen = strlen(optarg); if (len + namelen < PATH_MAX - 1) { keyfile[len] = '/'; memcpy(keyfile + len + 1, optarg, namelen + 1); keyfile = strdup(keyfile); /* Duplicate */ } else { keyfile = NULL; /* Invalidate */ } } } free(keyfile_buf); if (!keyfile) { kr_log_error("[system] keyfile '%s': not writeable\n", optarg); return EXIT_FAILURE; } break; case 'v': kr_debug_set(true); break; case 'V': kr_log_info("%s, version %s\n", "Knot DNS Resolver", PACKAGE_VERSION); return EXIT_SUCCESS; case 'h': case '?': help(argc, argv); return EXIT_SUCCESS; default: help(argc, argv); return EXIT_FAILURE; } } /* Switch to rundir. */ if (optind < argc) { const char *rundir = argv[optind]; if (access(rundir, W_OK) != 0) { kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno)); return EXIT_FAILURE; } ret = chdir(rundir); if (ret != 0) { kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno)); return EXIT_FAILURE; } if(config && access(config, R_OK) != 0) { kr_log_error("[system] rundir '%s'\n", rundir); kr_log_error("[system] config '%s': %s\n", config, strerror(errno)); return EXIT_FAILURE; } } kr_crypto_init(); /* Fork subprocesses if requested */ int fork_count = forks; while (--forks > 0) { int pid = fork(); if (pid < 0) { perror("[system] fork"); return EXIT_FAILURE; } /* Forked process */ if (pid == 0) { kr_crypto_reinit(); break; } } /* Block signals. */ uv_loop_t *loop = uv_default_loop(); uv_signal_t sigint, sigterm; uv_signal_init(loop, &sigint); uv_signal_init(loop, &sigterm); uv_signal_start(&sigint, signal_handler, SIGINT); uv_signal_start(&sigterm, signal_handler, SIGTERM); /* Create a server engine. */ knot_mm_t pool = { .ctx = mp_new (4096), .alloc = (knot_mm_alloc_t) mp_alloc }; struct engine engine; ret = engine_init(&engine, &pool); if (ret != 0) { kr_log_error("[system] failed to initialize engine: %s\n", kr_strerror(ret)); return EXIT_FAILURE; } /* Create worker */ struct worker_ctx *worker = init_worker(loop, &engine, &pool, forks, fork_count); if (!worker) { kr_log_error("[system] not enough memory\n"); return EXIT_FAILURE; } /* Bind to sockets and run */ for (size_t i = 0; i < addr_set.len; ++i) { int port = 53; const char *addr = set_addr(addr_set.at[i], &port); ret = network_listen(&engine.net, addr, (uint16_t)port, NET_UDP|NET_TCP); if (ret != 0) { kr_log_error("[system] bind to '%s#%d' %s\n", addr, port, knot_strerror(ret)); ret = EXIT_FAILURE; } } /* Start the scripting engine */ if (ret == 0) { ret = engine_start(&engine, config ? config : "config"); if (ret == 0) { if (keyfile) { auto_free char *cmd = afmt("trust_anchors.file = '%s'", keyfile); if (!cmd) { kr_log_error("[system] not enough memory\n"); return EXIT_FAILURE; } engine_cmd(&engine, cmd); lua_settop(engine.L, 0); } /* Run the event loop */ ret = run_worker(loop, &engine); } } /* Cleanup. */ array_clear(addr_set); engine_deinit(&engine); worker_reclaim(worker); mp_delete(pool.ctx); if (ret != 0) { ret = EXIT_FAILURE; } kr_crypto_cleanup(); return ret; }
/** Initialise the tweed library - must be called before any other * tweed calls */ int init_tweed(int workers_requested, int(*main_func)(struct generic_task_desc *,void*), void* main_args) { int i, err; if (workers_requested < 1) { fprintf(stderr, "Error initalizing tweed - requested less than 1 worker\n"); return -1; } num_workers = workers_requested; workers = (struct worker_desc *) malloc ( num_workers * sizeof(struct worker_desc)); // alloc task stack space for all workers, leave space for alignment task_stack_space = malloc (TWEED_TASK_STACK_SIZE * (num_workers + 1)); char * curr_stack_space = (char*)(((unsigned long)task_stack_space + TWEED_TASK_STACK_SIZE) & ~TWEED_TASK_STACK_MASK); // Initialize worker data-structures for (i=0; i<num_workers; i++) { init_worker(i, curr_stack_space); curr_stack_space += TWEED_TASK_STACK_SIZE; } // create dispatchers on all other cores required for num_workers for (i=1; i<num_workers; i++) { err = domain_new_dispatcher(i + disp_get_core_id(), domain_spanned_callback, (void*)(uintptr_t)i); if (err_is_fail(err)) { DEBUG_ERR(err, "domain_new_dispatcher failed"); printf("%d failed\n", i); } } // wait for all dispatchers to come up while (num_dispatchers < num_workers) { messages_wait_and_handle_next(); } num_dispatchers = 1; // reset // start work stealing threads on newly created domains for (i = 1; i < num_workers; i++) { struct worker_args * args = (struct worker_args *) malloc ( sizeof(struct worker_args)); args->id = i; args->origin = disp_get_core_id(); err = domain_thread_create_on(i + disp_get_core_id(), start_worker_thread, args); if (err_is_fail(err)) { DEBUG_ERR(err, "Failed to run a function on remote core"); } } // wait for all dispatchers to come up while (num_dispatchers < num_workers) { messages_wait_and_handle_next(); } // now start the main worker on the current dispatcher return main_worker(0, main_func, main_args); }
/* * initialize tm4c */ void init_satellite() { FPUEnable(); FPULazyStackingEnable(); /* * init clock */ MAP_SysCtlClockSet(SYSCTL_SYSDIV_3 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN); //66.6..MHz MAP_IntMasterEnable(); /* * Enable peripherals */ MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); //for LED indication MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); //for UART MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //for IRQ and SW_EN MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //for SPI /* * configure */ MAP_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, SIGNAL_LOW); //off MAP_GPIOPinConfigure(GPIO_PA0_U0RX); MAP_GPIOPinConfigure(GPIO_PA1_U0TX); MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig(UART_PORT, UART_BAUDRATE, SysCtlClockGet()); MAP_GPIOIntDisable(GPIO_PORTB_BASE, SIGNAL_HIGH); //interrupt disable MAP_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_2); //IRQ as input MAP_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); MAP_GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_FALLING_EDGE); //enable interrupt MAP_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_5); //sw enable MAP_GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_DIR_MODE_OUT); MAP_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD); MAP_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, SIGNAL_LOW); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); MAP_GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_0); MAP_GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); MAP_GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0, SIGNAL_HIGH); //chip select MAP_GPIOIntEnable(GPIO_PORTB_BASE, GPIO_PIN_2); //enable interrupt for WLAN_IRQ pin SpiCleanGPIOISR(); //clear interrupt status MAP_IntEnable(INT_GPIOB); //spi init_worker(); setState(READY); }