Exemple #1
0
void reload_task(void *data)
{
    RELOAD_TASK = taskself();
    struct ServerTask *srv = data;

    while(1) {
        taskswitch();
        task_clear_signal();

        if(RELOAD) {
            log_info("Reload requested, will load %s from %s", bdata(srv->db_file), bdata(srv->server_id));
            Server *old_srv = Server_queue_latest();
            Server *new_srv = reload_server(old_srv, bdata(srv->db_file), bdata(srv->server_id));
            check(new_srv, "Failed to load the new configuration, exiting.");

            // for this to work handlers need to die more gracefully
            Server_queue_push(new_srv);
        } else {
            log_info("Shutdown requested, goodbye.");
            break;
        }
    }

    taskexit(0);
error:
    taskexit(1);
}
Exemple #2
0
void Handler_task(void *v)
{
    int rc = 0;
    int i = 0;
    Handler *handler = (Handler *)v;
    HandlerParser *parser = NULL;
    int max_targets = Setting_get_int("limits.handler_targets", 128);
    log_info("MAX allowing limits.handler_targets=%d", max_targets);

    parser = HandlerParser_create(max_targets);
    check_mem(parser);

    check(Handler_setup(handler) == 0, "Failed to initialize handler, exiting.");

    while(handler->running && !task_was_signaled()) {
        taskstate("delivering");

        rc = handler_recv_parse(handler, parser);

        if(task_was_signaled()) {
            log_warn("Handler task signaled, exiting.");
            break;
        } else if( rc == -1 || parser->target_count <= 0) {
            log_warn("Skipped invalid message from handler: %s", bdata(handler->send_spec));
            taskdelay(100);
            continue;
        } else {
            for(i = 0; i < (int)parser->target_count; i++) {
                int id = (int)parser->targets[i];
                int fd = Register_fd_for_id(id);
                Connection *conn = fd == -1 ? NULL : Register_fd_exists(fd);

                // don't bother calling process request if there's nothing to handle
                if(conn && fd >= 0) {
                    handler_process_request(handler, id, fd, conn, parser->body);
                } else {
                    // TODO: I believe we need to notify the connection that it is dead too
                    Handler_notify_leave(handler, id);
                }
            }
        }

        HandlerParser_reset(parser);
    }

    handler->running = 0;
    handler->task = NULL;
    HandlerParser_destroy(parser);
    taskexit(0);

error:
    log_err("HANDLER TASK DIED: %s", bdata(handler->send_spec));
    handler->running = 0;
    handler->task = NULL;
    HandlerParser_destroy(parser);
    taskexit(1);
}
Exemple #3
0
void Connection_task(void *v)
{
    Connection *conn = (Connection *)v;
    int i = 0;
    int next = OPEN;

    State_init(&conn->state, &CONN_ACTIONS);

    while(1) {
        if(Filter_activated()) {
            next = Filter_run(next, conn);
            check(next >= CLOSE && next < EVENT_END,
                    "!!! Invalid next event[%d]: %d from filter!", i, next);
        }

        if(next == CLOSE) break;

        next = State_exec(&conn->state, next, (void *)conn);

        check(next >= CLOSE && next < EVENT_END,
                "!!! Invalid next event[%d]: %d, Tell ZED!", i, next);

        if(conn->iob && !conn->iob->closed) {
            Register_ping(IOBuf_fd(conn->iob));
        }

        i++;
    }

error: // fallthrough
    State_exec(&conn->state, CLOSE, (void *)conn);
    Connection_destroy(conn);
    taskexit(0);
}
Exemple #4
0
void Handler_task(void *v)
{
    int rc = 0;
    int i = 0;
    Handler *handler = (Handler *)v;
    HandlerParser *parser = NULL;
    int max_targets = Setting_get_int("limits.handler_targets", 128);
    log_info("MAX allowing limits.handler_targets=%d", 128);

    parser = HandlerParser_create(max_targets);
    check_mem(parser);

    check(Handler_setup(handler) == 0, "Failed to initialize handler, exiting.");

    while(handler->running) {
        taskstate("delivering");

        rc = handler_recv_parse(handler, parser);

        if(rc != -1 && parser->target_count > 0) {
            for(i = 0; i < (int)parser->target_count; i++) {
                int id = (int)parser->targets[i];
                int fd = Register_fd_for_id(id);
                Connection *conn = (Connection *)Register_fd_exists(fd);

                handler_process_request(handler, id, fd, conn, parser->body);
            }
        } else {
            debug("Skipped invalid message from handler: %s", bdata(handler->send_spec));
        }

        HandlerParser_reset(parser);
    }

    HandlerParser_destroy(parser);
    debug("HANDLER EXITED.");
    taskexit(0);

error:
    HandlerParser_destroy(parser);
    log_err("HANDLER TASK DIED");
    taskexit(1);
}
Exemple #5
0
void taskmain(int argc, char *argv[])
{
    LOG_FILE = stderr;
    glob_t profile_glob;
    int rc = 0;
    int i = 0;
    Action *action = NULL;
    tst_t *targets = NULL;
    bstring pid_file = NULL;

    check(argc == 3, "USAGE: procer <profile_dir> <procer_pid_file>");
    pid_file = bfromcstr(argv[2]);

    rc = Unixy_remove_dead_pidfile(pid_file);
    check(rc == 0, "Failed to remove %s, procer is probably already running.", bdata(pid_file));

    rc = Unixy_daemonize();
    check(rc == 0, "Couldn't daemonize, that's not good.");

    rc = chdir(argv[1]);
    check(rc == 0, "Couldn't change to %s profile dir.", argv[1]);

    rc = Unixy_pid_file(pid_file);
    check(rc == 0, "Failed to make the PID file: %s", bdata(pid_file));

    FILE *log = fopen("error.log", "a+");
    check(log, "Couldn't open error.log");
    setbuf(log, NULL);
    LOG_FILE = log;

    bstring dir_glob = bformat("%s/[A-Za-z0-9]*", argv[1]);
    check(dir_glob, "Couldn't make the directory glob.");

    rc = glob(bdata(dir_glob), GLOB_ERR | GLOB_ONLYDIR, NULL, &profile_glob);
    check(rc == 0, "Failed to find directories in the profiles.");

    debug("Loading %zu actions.", profile_glob.gl_pathc);
    for(i = 0; i < profile_glob.gl_pathc; i++) {
        action = Action_create(profile_glob.gl_pathv[i]);
        targets = tst_insert(targets, bdata(action->name), blength(action->name), action);
    }

    // now we setup the dependencies from the settings they've got
    tst_traverse(targets, Action_dependency_assign, targets);
    tst_traverse(targets, Action_start_all, NULL);

    taskexit(0);

error:
    taskexitall(1);
}
Exemple #6
0
static void
taskstart(uint y, uint x)
{
    Task *t;
    ulong z;

    z = x << 16;    /* hide undefined 32-bit shift from 32-bit compilers */
    z <<= 16;
    z |= y;
    t = (Task *) z;

    t->startfn(t->startarg);
    taskexit(0);
}
Exemple #7
0
void
fdtask(void *v)
{
    int i, ms;
    PollResult result;
    int rc = 0;
    
    rc = PollResult_init(POLL, &result);
    check(rc == 0, "Failed to initialize the poll result.");

    tasksystem();
    taskname("fdtask");

    for(;;){
        /* let everyone else run */
        while(taskyield() > 0)
            ;
        /* we're the only one runnable - poll for i/o */
        errno = 0;
        taskstate("poll");

        ms = next_task_sleeptime(500);

        if(SIGNALED) {
            for(i = 0; i < SuperPoll_active_hot(POLL); i++) {
                Task *target = (Task *)SuperPoll_data(POLL, i);
                if(target) taskready(target);
                SuperPoll_compact_down(POLL, i);
            }
        } else {
            rc = SuperPoll_poll(POLL, &result, ms);
            check(rc != -1, "SuperPoll failure, aborting.");

            for(i = 0; i < rc; i++) {
                taskready(result.hits[i].data); 
            }
        }

        wake_sleepers();
    }

    PollResult_clean(&result);
    taskexit(0);

error:
    taskexitall(1);
}
Exemple #8
0
static void
taskstart(uint y, uint x)
{
	Task *t;
	ulong z;

	z = x<<16;	/* hide undefined 32-bit shift from 32-bit compilers */
	z <<= 16;
	z |= y;
	t = (Task*)z;

//print("taskstart %p\n", t);
	t->startfn(t->startarg);
//print("taskexits %p\n", t);
	taskexit(0);
//print("not reacehd\n");
}
Exemple #9
0
static void
taskstart(uint y, uint x)
{
	Task *t;
	ulong z;

	//将2个四字节组成一个8字节64位的地址,指向了所属的Task结构
	z = x<<16;	/* hide undefined 32-bit shift from 32-bit compilers */
	z <<= 16;
	z |= y;
	t = (Task*)z;

//print("taskstart %p\n", t);
	t->startfn(t->startarg);//调用用户的启动地址
//print("taskexits %p\n", t);
	taskexit(0);
//print("not reacehd\n");
}
void taskmain(int argc, char* argv[])
{
	char buf[100];
	//HANDLE ev = CreateEvent(0, TRUE, FALSE, 0);
	FD* h = taskopen(_T("D:\\Tracer.java"), GENERIC_READ, 0, OPEN_EXISTING, 0);
	if (h == 0)
	{
		puts("f****d");
		abort();
	}

	//handlewait(ev);

	while (1)
	{
	if (fdread(h, buf, 99) == -1)
	{
		abort();
	}
	buf[99] = '\0';
	puts(buf);
	}

/*
	if (fdread(h, buf, 100) == -1)
	{
		abort();
	}
	buf[99] = '\0';
	puts(buf);*/


	taskexit(0);


	//taskcreate(test, 0, 32768);
	//while (1)
	//{
	//	puts("turtles");
	//	taskdelay(500);
	//	taskyield();
	//}
}
Exemple #11
0
static void
taskmain(ltctx *lt, void *unused)
{
    int i, n;

    if(argc != 4) {
        fprintf(stderr, "usage: httpload n server url\n");
        fprintf(stderr, "   ex: httpload 4 127.0.0.1 /\n");
        taskexit(lt, 1);
    }
    n = atoi(argv[1]);
    server = argv[2];
    url = argv[3];

    for(i=0; i<n; i++) {
        taskcreate(lt, fetchtask, 0, STACK);
        while(taskyield(lt) > 1)
            ;
        //taskdelay(lt, 1/*ms*/);
    }
}
Exemple #12
0
void Connection_deliver_task(void *v)
{
    Connection *conn=v;
    bstring msg=NULL;
    while(1) {
        msg = Connection_deliver_dequeue(conn);
        check_debug(msg,"Received NULL msg on FD %d, exiting deliver task",IOBuf_fd(conn->iob));
        check(-1 != Connection_deliver_raw_internal(conn,msg),"Error delivering to MSG listener on FD %d, closing them.", IOBuf_fd(conn->iob));
        bdestroy(msg);
        msg=NULL;
    }
error:
    conn->deliverTaskStatus=DT_DYING;
    while(conn->deliverPost > conn->deliverAck) {
        bdestroy(Connection_deliver_dequeue(conn));
    }

    bdestroy(msg);
    if (IOBuf_fd(conn->iob) >= 0)
        shutdown(IOBuf_fd(conn->iob), SHUT_RDWR);
    debug("Deliver Task Shut Down\n");
    conn->deliverTaskStatus=DT_DEAD;
    taskexit(0);
}
Exemple #13
0
void taskmain(int argc, char *argv[])
{
    dbg_set_log(stderr);
    glob_t profile_glob;
    int rc = 0;
    int i = 0;
    Action *action = NULL;
    tst_t *targets = NULL;
    bstring pid_file = NULL;
    char *procer_error_log = NULL;

    m2program = procer_program;

    check(argc == 3, "USAGE: %s <profile_dir> <procer_pid_file>", m2program);
    pid_file = bfromcstr(argv[2]);

    srand(time(NULL)); // simple randomness

    rc = Unixy_remove_dead_pidfile(pid_file);
    check(rc == 0, "Failed to remove %s, %s is probably already running.", bdata(pid_file), m2program);

    rc = Unixy_daemonize(1);
    check(rc == 0, "Couldn't daemonize, that's not good.");

    rc = chdir(argv[1]);
    check(rc == 0, "Couldn't change to %s profile dir.", argv[1]);

    rc = Unixy_pid_file(pid_file);
    check(rc == 0, "Failed to make the PID file: %s", bdata(pid_file));

    if( (procer_error_log = getenv("PROCER_ERROR_LOG")) == NULL)
        procer_error_log = "error.log";
    FILE *log = fopen(procer_error_log, "a+");
    check(log, "Couldn't open error.log");
    setbuf(log, NULL);
    dbg_set_log(log);

    bstring dir_glob = bformat("%s/[A-Za-z0-9]*", argv[1]);
    check(dir_glob, "Couldn't make the directory glob.");

    rc = glob(bdata(dir_glob), GLOB_ERR, NULL, &profile_glob);
    check(rc == 0, "Failed to find directories in the profiles.");

    struct stat sb;
    debug("Loading %zu actions.", profile_glob.gl_pathc);

    start_terminator();

    while(RUNNING) {
        for(i = 0; i < profile_glob.gl_pathc; i++) {
            rc = lstat(profile_glob.gl_pathv[i], &sb);
            check(rc == 0, "Failed to stat file or directory: %s", profile_glob.gl_pathv[i]);

            if (sb.st_mode & S_IFDIR) {
                action = Action_create(profile_glob.gl_pathv[i]);
                targets = tst_insert(targets, bdata(action->name), blength(action->name), action);
            }
        }

        // now we setup the dependencies from the settings they've got
        tst_traverse(targets, Action_dependency_assign, targets);
        tst_traverse(targets, Action_start_all, NULL);

        while(RUNNING) {
            Action_sleep(1);
        }
    }

    log_warn("Exiting as requested from procer.");

    taskexit(0);

error:
    taskexitall(1);
}
Exemple #14
0
//
// This is the router for all new incoming connections. The overall flow
// for what we're doing here is as follows:
//
// First, we'll read the request message that comes in off the new connection.
//
// If a server ID is in the request, we'll attempt to lookup the server task
// in the context routing hash table. If the server task exists in the hash
// table, we'll create a new connection task and add it to the server's
// connection list.
//
// If the server ID is not in the context's routing hash table, we respond to
// the new connection with a suggestion to have the client ask the location
// quorum where the server may be located at. If possible, we should send the
// address and port number of the last known location quorum leader (or any
// location quorum member if the leader is not known).
//
// If the client doesn't send a server ID at all, we'll then try to determine
// what the client wants to do. The remaining options to attempt at this point
// are the following:
//
//   1. Become a client-server instance.
//   2. Respond with the address and port of the location quorum leader (or a
//      location quorum member if the leader is not known).
//   3. Create a new location quorum by becoming a location quorum leader.
//
void TDB_routing_task(TDB_router_t* router)
{
    TDB_msg_client_control_t control_msg_data;
    char new_uuid_string[UUID_STR_LEN];
    uuid_t new_uuid;
    TDB_replica_t* new_replica;

    taskname("router");

    if(TDB_proto_handle_connect_msg(router->accept_fd) != TDB_SUCCESS) {
        LOG(TDB_LOG_ERR, "Did not receive a valid connect message while routing.");
        taskexit(TDB_ERROR);
    }

    if(TDB_proto_receive_control_msg(router->accept_fd, &control_msg_data) != TDB_SUCCESS) {
        LOG(TDB_LOG_ERR, "Did not receive a valid control message while routing.");
        taskexit(TDB_ERROR);
    }
    else {
        if(TDB_proto_send_control_resp_msg(router->accept_fd) != TDB_SUCCESS) {
            LOG(TDB_LOG_ERR, "Failed to send a response to the control message.");
            taskexit(TDB_ERROR);
        }
        else {
            LOG(TDB_LOG_DBG, "Sent response to control message.");
        }
    }

    switch(control_msg_data.action) {

        case TDB_PROTO_CTRL_ATTACH_APPEND:
        case TDB_PROTO_CTRL_ATTACH_DATA:
        case TDB_PROTO_CTRL_ATTACH_VOTE:

            if(TDB_replica_attach(router, control_msg_data.uuid, control_msg_data.action) != TDB_SUCCESS) {
                uuid_unparse(control_msg_data.uuid, new_uuid_string);
                LOG(TDB_LOG_ERR, "Failed to attach to UUID `%s'.", new_uuid_string);
            }
            else {
                LOG(TDB_LOG_DBG, "Attach completed.");
            }

            break;

        case TDB_PROTO_CTRL_PROXY:
            LOG(TDB_LOG_DBG, "Handling control proxy message.");
            LOG(TDB_LOG_ERR, "Not implemented yet.");
            break;

        case TDB_PROTO_CTRL_FOLLOWER:
            LOG(TDB_LOG_DBG, "Handling control follower message.");
            LOG(TDB_LOG_ERR, "Not implemented yet.");
            break;

        case TDB_PROTO_CTRL_LEADER:
            TDB_replica_init(&new_replica);

            if(TDB_bootstrap_leader(new_replica, router->ctx, \
                                    &new_uuid, control_msg_data.path) == TDB_SUCCESS) {
                uuid_unparse(new_uuid, new_uuid_string);
                LOG(TDB_LOG_ERR, "Quorum leader created with UUID `%s'.", new_uuid_string);
                //TODO: return uuid to requestor?
            }
            else {
                LOG(TDB_LOG_ERR, "Failed to bootstrap a quorum leader.");
            }

            break;

        case TDB_PROTO_CTRL_LOCATION:
            TDB_replica_init(&new_replica);

            if(TDB_bootstrap_location(new_replica, router->ctx, \
                                      &new_uuid) == TDB_SUCCESS) {
                uuid_unparse(new_uuid, new_uuid_string);
                LOG(TDB_LOG_ERR, "Location quorum leader created with UUID `%s'.", new_uuid_string);
                //TODO: return uuid to requestor?
            }
            else {
                LOG(TDB_LOG_ERR, "Failed to bootstrap a location quorum leader.");
            }

            break;

        case TDB_PROTO_CTRL_EXIT:
            LOG(TDB_LOG_DBG, "Handling control exit message.");
            LOG(TDB_LOG_ERR, "Not implemented yet.");
            break;

        case TDB_PROTO_CTRL_DESTROY:
            LOG(TDB_LOG_DBG, "Handling control destroy message.");
            LOG(TDB_LOG_ERR, "Not implemented yet.");
            break;

        default:
            LOG(TDB_LOG_ERR, "Encountered unrecognized control message type of `%d'.", \
                control_msg_data.action);
            taskexit(TDB_ERROR);
    }

    LOG(TDB_LOG_DBG, "Completed routing. Exiting task.");
    TDB_free_router(router);

    taskexit(TDB_SUCCESS);
}