<commit_before>/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Monkey HTTP Daemon
 *  ------------------
 *  Copyright (C) 2001-2012, <NAME>. <<EMAIL>>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>

#include "monkey.h"
#include "mk_connection.h"
#include "mk_scheduler.h"
#include "mk_memory.h"
#include "mk_epoll.h"
#include "mk_request.h"
#include "mk_cache.h"
#include "mk_config.h"
#include "mk_clock.h"
#include "mk_signals.h"
#include "mk_plugin.h"
#include "mk_utils.h"
#include "mk_macros.h"

/*
 * Returns the worker id which should take a new incomming connection,
 * it returns the worker id with less active connections
 */
static inline int _next_target()
{
    int i;
    int target = 0;
    unsigned long long tmp = 0, cur = 0;

    cur = sched_list[0].accepted_connections - sched_list[0].closed_connections;
    if (cur == 0)
        return 0;

    /* Finds the lowest load worker */
    for (i = 1; i < config->workers; i++) {
        tmp = sched_list[i].accepted_connections - sched_list[i].closed_connections;
        if (tmp < cur) {
            target = i;
            cur = tmp;

            if (cur == 0)
                break;
        }
    }

    /* If sched_list[target] worker is full then the whole server too, because it has the lowest load. */
    if(cur >= config->worker_capacity) {
        MK_TRACE("Too many clients: %i", config->worker_capacity * config->workers);
        return -1;
    }

    return target;
}

/*
 * Assign a new incomming connection to a specific worker thread, this call comes
 * from the main monkey process.
 */
inline int mk_sched_add_client(int remote_fd)
{
    int r, t=0;
    struct sched_list_node *sched;

    /* Next worker target */
    t = _next_target();

    if (t == -1) {
        MK_TRACE("[FD %i] Over Capacity, drop!", remote_fd);
        return -1;
    }

    sched = &sched_list[t];

    MK_TRACE("[FD %i] Balance to WID %i", remote_fd, sched->idx);

    r  = mk_epoll_add(sched->epoll_fd, remote_fd, MK_EPOLL_WRITE,
                      MK_EPOLL_LEVEL_TRIGGERED);

    /* If epoll has failed, decrement the active connections counter */
    if (r == 0) {
        sched->accepted_connections++;
    }

    return r;
}

/*
 * Register a new client connection into the scheduler, this call takes place
 * inside the worker/thread context.
 */
int mk_sched_register_client(int remote_fd, struct sched_list_node *sched)
{
    int ret;
    struct sched_connection *sched_conn;
    struct mk_list *av_queue = &sched->av_queue;
    unsigned long long active_connections;

    active_connections = sched->accepted_connections - sched->closed_connections;
    if (active_connections < config->worker_capacity) {
        sched_conn = mk_list_entry_first(av_queue, struct sched_connection, _head);

        /* Before to continue, we need to run plugin stage 10 */
        ret = mk_plugin_stage_run(MK_PLUGIN_STAGE_10,
                                  remote_fd,
                                  sched_conn, NULL, NULL);

        /* Close connection, otherwise continue */
        if (ret == MK_PLUGIN_RET_CLOSE_CONX) {
            mk_conn_close(remote_fd);
            return MK_PLUGIN_RET_CLOSE_CONX;
        }

        mk_list_del(&sched_conn->_head);
        mk_list_add(&sched_conn->_head, &sched->busy_queue);

        /* Socket and status */
        sched_conn->socket = remote_fd;
        sched_conn->status = MK_SCHEDULER_CONN_PENDING;
        sched_conn->arrive_time = log_current_utime;
    }


    return -1;
}

static void mk_sched_thread_lists_init()
{
    struct mk_list *cs_list;

    /* client_session mk_list */
    cs_list = mk_mem_malloc(sizeof(struct mk_list));
    mk_list_init(cs_list);
    mk_sched_set_request_list(cs_list);
}<commit_msg>Scheduler: remove unneeded active_connections check<commit_after>/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Monkey HTTP Daemon
 *  ------------------
 *  Copyright (C) 2001-2012, <NAME>. <<EMAIL>>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>

#include "monkey.h"
#include "mk_connection.h"
#include "mk_scheduler.h"
#include "mk_memory.h"
#include "mk_epoll.h"
#include "mk_request.h"
#include "mk_cache.h"
#include "mk_config.h"
#include "mk_clock.h"
#include "mk_signals.h"
#include "mk_plugin.h"
#include "mk_utils.h"
#include "mk_macros.h"

/*
 * Returns the worker id which should take a new incomming connection,
 * it returns the worker id with less active connections
 */
static inline int _next_target()
{
    int i;
    int target = 0;
    unsigned long long tmp = 0, cur = 0;

    cur = sched_list[0].accepted_connections - sched_list[0].closed_connections;
    if (cur == 0)
        return 0;

    /* Finds the lowest load worker */
    for (i = 1; i < config->workers; i++) {
        tmp = sched_list[i].accepted_connections - sched_list[i].closed_connections;
        if (tmp < cur) {
            target = i;
            cur = tmp;

            if (cur == 0)
                break;
        }
    }

    /* If sched_list[target] worker is full then the whole server too, because it has the lowest load. */
    if(cur >= config->worker_capacity) {
        MK_TRACE("Too many clients: %i", config->worker_capacity * config->workers);
        return -1;
    }

    return target;
}

/*
 * Assign a new incomming connection to a specific worker thread, this call comes
 * from the main monkey process.
 */
inline int mk_sched_add_client(int remote_fd)
{
    int r, t=0;
    struct sched_list_node *sched;

    /* Next worker target */
    t = _next_target();

    if (t == -1) {
        MK_TRACE("[FD %i] Over Capacity, drop!", remote_fd);
        return -1;
    }

    sched = &sched_list[t];

    MK_TRACE("[FD %i] Balance to WID %i", remote_fd, sched->idx);

    r  = mk_epoll_add(sched->epoll_fd, remote_fd, MK_EPOLL_WRITE,
                      MK_EPOLL_LEVEL_TRIGGERED);

    /* If epoll has failed, decrement the active connections counter */
    if (r == 0) {
        sched->accepted_connections++;
    }

    return r;
}

/*
 * Register a new client connection into the scheduler, this call takes place
 * inside the worker/thread context.
 */
int mk_sched_register_client(int remote_fd, struct sched_list_node *sched)
{
    int ret;
    struct sched_connection *sched_conn;
    struct mk_list *av_queue = &sched->av_queue;

    sched_conn = mk_list_entry_first(av_queue, struct sched_connection, _head);

    /* Before to continue, we need to run plugin stage 10 */
    ret = mk_plugin_stage_run(MK_PLUGIN_STAGE_10,
                              remote_fd,
                              sched_conn, NULL, NULL);

    /* Close connection, otherwise continue */
    if (ret == MK_PLUGIN_RET_CLOSE_CONX) {
        mk_conn_close(remote_fd);
        return MK_PLUGIN_RET_CLOSE_CONX;
    }

    mk_list_del(&sched_conn->_head);
    mk_list_add(&sched_conn->_head, &sched->busy_queue);

    /* Socket and status */
    sched_conn->socket = remote_fd;
    sched_conn->status = MK_SCHEDULER_CONN_PENDING;
    sched_conn->arrive_time = log_current_utime;


    return -1;
}

static void mk_sched_thread_lists_init()
{
    struct mk_list *cs_list;

    /* client_session mk_list */
    cs_list = mk_mem_malloc(sizeof(struct mk_list));
    mk_list_init(cs_list);
    mk_sched_set_request_list(cs_list);
}
{'fraction_non_alphanumeric': 0.10962537296938889, 'fraction_numerical': 0.00906177478174384, 'mean_word_length': 2.8642186165670367, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5173019', 'n_tokens_mistral': 3021, 'n_tokens_neox': 2874, 'n_words': 880}