Esempio n. 1
0
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";
}
Esempio n. 2
0
static int start_worker(struct workqueue *wq, unsigned int index,
			struct sk_out *sk_out)
{
	struct submit_worker *sw = &wq->workers[index];
	int ret;

	INIT_FLIST_HEAD(&sw->work_list);

	ret = mutex_cond_init_pshared(&sw->lock, &sw->cond);
	if (ret)
		return ret;

	sw->wq = wq;
	sw->index = index;
	sw->sk_out = sk_out;

	if (wq->ops.alloc_worker_fn) {
		ret = wq->ops.alloc_worker_fn(sw);
		if (ret)
			return ret;
	}

	ret = pthread_create(&sw->thread, NULL, worker_thread, sw);
	if (!ret) {
		pthread_mutex_lock(&sw->lock);
		sw->flags = SW_F_IDLE;
		pthread_mutex_unlock(&sw->lock);
		return 0;
	}

	free_worker(sw, NULL);
	return 1;
}
Esempio n. 3
0
static void shutdown_worker(struct submit_worker *sw, unsigned int *sum_cnt)
{
	struct thread_data *parent = sw->wq->td;

	pthread_join(sw->thread, NULL);
	(*sum_cnt)++;
	sum_thread_stats(&parent->ts, &sw->td.ts, *sum_cnt);
	free_worker(sw);
}
Esempio n. 4
0
static int start_worker(struct workqueue *wq, unsigned int index)
{
	struct submit_worker *sw = &wq->workers[index];
	int ret;

	INIT_FLIST_HEAD(&sw->work_list);
	pthread_cond_init(&sw->cond, NULL);
	pthread_mutex_init(&sw->lock, NULL);
	sw->wq = wq;
	sw->index = index;

	ret = pthread_create(&sw->thread, NULL, worker_thread, sw);
	if (!ret) {
		pthread_mutex_lock(&sw->lock);
		sw->flags = SW_F_IDLE;
		pthread_mutex_unlock(&sw->lock);
		return 0;
	}

	free_worker(sw);
	return 1;
}
Esempio n. 5
0
void threadpool_destroy(thread_pool_t *destroyme, int flag)
{
    thread_pool_t *pool =(thread_pool_t *)destroyme;
    worker_node_t *wp;
    int oldtype;
    printf("cur threads:[%d]\n", pool->worker.cur);

    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
    pthread_cleanup_push((task_fun)pthread_mutex_unlock, (void *)&pool->mutex);

    if(flag)
    {
        for(wp = pool->worker.head; wp; wp = wp->next) pthread_cancel(wp->tid);
    }else
    {
        pthread_mutex_lock(&pool->mutex);
        pool->state = PEXIT;
        pthread_mutex_unlock(&pool->mutex);

        while(pool->worker.cur)
        {
            pthread_cond_broadcast(&pool->job_posted);
            usleep(100);
        }
    }
    free_worker(&pool->worker);
    free_task(&pool->task);
    free_task(&pool->emg_task);

    pthread_cleanup_pop(0);

    pthread_mutex_destroy(&pool->mutex);
    pthread_cond_destroy(&pool->job_posted);
    pthread_cond_destroy(&pool->job_taken);

    free(pool);
    printf("destroy_threadpool ok\n");
    return;
}
Esempio n. 6
0
/* 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();
}
Esempio n. 7
0
static void shutdown_worker(struct submit_worker *sw, unsigned int *sum_cnt)
{
	pthread_join(sw->thread, NULL);
	free_worker(sw, sum_cnt);
}