Esempio n. 1
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);
}
Esempio n. 2
0
int _wait(void *socket, int fd, int rw)
{
    startfdtask();
    check(socket != NULL || fd >= 0, "Attempt to wait on a dead socket/fd: %p or %d", socket, fd);

    int max = 0;
    int hot_add = SuperPoll_active_hot(POLL) < SuperPoll_max_hot(POLL);
    int was_registered = 0;

    if(socket != NULL) {
        taskstate(rw == 'r' ? "read handler" : "write handler");
    } else {
        was_registered = Register_fd_exists(fd) != NULL;
        taskstate(rw == 'r' ? "read fd" : "write fd");
    }

    max = SuperPoll_add(POLL, (void *)taskrunning, socket, fd, rw, hot_add);
    check(max != -1, "Error adding fd: %d or socket: %p to task wait list.", fd, socket);

    taskswitch();

    if(task_was_signaled()) {
        debug("GOT SIGNAL %d AFTER WAIT", taskrunning->signal);
        SuperPoll_del(POLL, socket, fd, hot_add);
        return -1;
    } if(was_registered && Register_fd_exists(fd) == NULL) {
        debug("Socket %d was closed after a wait.", fd);
        return -1;
    } else {
        return 0;
    }

error:
    return -1;
}
Esempio n. 3
0
void tickertask(void *v)
{
    (void)v;

    taskname("ticker");

    while(!task_was_signaled()) {
        THE_CURRENT_TIME_IS = time(NULL);

        int min_wait = Setting_get_int("limits.tick_timer", 10);
        taskdelay(min_wait * 1000);

        // avoid doing this during a reload attempt
        if(!RELOAD) {
            // don't bother if these are all 0
            int min_ping = Setting_get_int("limits.min_ping", DEFAULT_MIN_PING);
            int min_write_rate = Setting_get_int("limits.min_write_rate", DEFAULT_MIN_READ_RATE);
            int min_read_rate = Setting_get_int("limits.min_read_rate", DEFAULT_MIN_WRITE_RATE);

            if(min_ping > 0 || min_write_rate > 0 || min_read_rate > 0) {
                int cleared = Register_cleanout();

                if(cleared > 0) {
                    log_warn("Timeout task killed %d tasks, waiting %d seconds for more.", cleared, min_wait);
                } else {
                    debug("No connections timed out.");
                }
            }

            // do a server queue cleanup to get rid of dead servers
            Server_queue_cleanup();
        }
    }
}
Esempio n. 4
0
static inline void fdtask_shutdown()
{
    int i = 0;

    for(i = 0; i < SuperPoll_active_hot(POLL); i++) {
        SuperPoll_compact_down(POLL, i);
    }

    // move all our sleeping tasks over to the main runqueue
    Task *t = NULL;
    while((t = sleeping.head)){
        deltask(&sleeping, t);
        tasksignal(t, task_was_signaled());
    }
}
Esempio n. 5
0
void fdtask(void *v)
{
    int i, ms;
    PollResult result;
    int rc = 0;
    FDTASK = taskself();
    
    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(task_was_signaled()) {
            fdtask_shutdown();
            task_clear_signal();
            break;
        } 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);
    FDTASK = NULL;
    return;

error:
    taskexitall(1);
}