예제 #1
0
 void init() {
     const int id(get_thread_num());
     if (id == 0)
         init_master();
     else
         init_worker(id);
 }
예제 #2
0
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);
}
예제 #3
0
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
}
예제 #4
0
파일: dmq.c 프로젝트: 4N7HR4X/kamailio
/**
 * 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;
}
예제 #5
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;
}
예제 #6
0
파일: worker.c 프로젝트: tohojo/http-getter
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;
}
예제 #7
0
파일: worker.c 프로젝트: tohojo/http-getter
static int reset_worker(struct worker_data *data)
{
	destroy_worker(data);
	return init_worker(data);
}
예제 #8
0
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;
}
예제 #9
0
/** 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);
}
예제 #10
0
/*
 * 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);
}