X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=blobdiff_plain;f=src%2FIRCQueue.c;h=a7cc1a4d00fd52521ba0cc108a3db83c9dbf0d69;hp=c30a27efb8f819f551f88fe9b7153c7e25bbd154;hb=HEAD;hpb=c254e7d9a1622b19aae9b4ebecb4082657288f4a diff --git a/src/IRCQueue.c b/src/IRCQueue.c index c30a27e..a7cc1a4 100644 --- a/src/IRCQueue.c +++ b/src/IRCQueue.c @@ -1,5 +1,5 @@ -/* IRCQueue.c - NeonServ v5.1 - * Copyright (C) 2011 Philipp Kreil (pk910) +/* IRCQueue.c - NeonServ v5.6 + * Copyright (C) 2011-2012 Philipp Kreil (pk910) * * 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 @@ -16,8 +16,11 @@ */ #include "IRCQueue.h" #include "ClientSocket.h" +#include "IOHandler.h" +#include "tools.h" +#include "log.h" -#define MAXPENALTY 6 +#define MAXPENALTY 8 /* 4 messages */ struct QueueEntry { char *msg; @@ -26,20 +29,25 @@ struct QueueEntry { struct BotQueue { struct ClientSocket *client; - int penalty; + struct IODescriptor *iofd; + int penalty : 8; + int rem_penalty : 8; struct QueueEntry *fastqueue_first, *fastqueue_last; struct QueueEntry *normalqueue_first, *normalqueue_last; struct QueueEntry *textqueue_first, *textqueue_last; }; +static IOHANDLER_CALLBACK(queue_callback); + static struct BotQueue *initialize_queue(struct ClientSocket *client) { struct BotQueue *queue = malloc(sizeof(*queue)); if (!queue) { - perror("malloc() failed"); + printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__); return NULL; } queue->client = client; client->queue = queue; + queue->iofd = NULL; queue->penalty = 0; queue->fastqueue_first = NULL; queue->fastqueue_last = NULL; @@ -50,12 +58,19 @@ static struct BotQueue *initialize_queue(struct ClientSocket *client) { return queue; } +static int calculate_penalty(char *message) { + int msglen = strlen(message); + int penalty = (2 + msglen / 100); + return penalty; +} + int queue_add(struct ClientSocket *client, char* msg, int len) { if(!client->queue) client->queue = initialize_queue(client); struct BotQueue *queue = client->queue; char *args = strstr(msg, " "); int type; + int add_queue = 0; if(args) { *args = '\0'; if(!stricmp(msg, "MODE")) @@ -75,47 +90,82 @@ int queue_add(struct ClientSocket *client, char* msg, int len) { *args = ' '; } else type = 2; - struct QueueEntry *entry = malloc(sizeof(*entry)); - if (!entry) { - perror("malloc() failed"); - return 0; + + //check if we need to queue + switch(type) { + case 1: + if(queue->textqueue_first) { + add_queue = 1; + break; + } + case 2: + if(queue->normalqueue_first) { + add_queue = 1; + break; + } + case 3: + if(queue->fastqueue_first) { + add_queue = 1; + break; + } + default: + if(queue->penalty >= MAXPENALTY) + add_queue = 1; + break; } - entry->msg = strdup(msg); - entry->next = NULL; - if(type == 1) { //low priority - if(queue->textqueue_last) { - queue->textqueue_last->next = entry; - queue->textqueue_last = entry; - } else { - queue->textqueue_last = entry; - queue->textqueue_first = entry; + + if(!add_queue) { + int penalty = calculate_penalty(msg); + write_socket_force(client, msg, len); + queue->penalty += penalty; + if(!queue->iofd) { + struct timeval timeout; + gettimeofday(&timeout, NULL); + if(queue->penalty >= MAXPENALTY) + queue->rem_penalty = (queue->penalty - MAXPENALTY)+1; + else + queue->rem_penalty = queue->penalty; + timeout.tv_sec += queue->rem_penalty; + queue->iofd = iohandler_timer(timeout, queue_callback); + queue->iofd->data = queue; } - } else if(type == 2) { //normal priority - if(queue->normalqueue_last) { - queue->normalqueue_last->next = entry; - queue->normalqueue_last = entry; - } else { - queue->normalqueue_last = entry; - queue->normalqueue_first = entry; + } else { + struct QueueEntry *entry = malloc(sizeof(*entry)); + if (!entry) { + printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__); + return 0; } - } else if(type == 3) { //high priority - if(queue->fastqueue_last) { - queue->fastqueue_last->next = entry; - queue->fastqueue_last = entry; - } else { - queue->fastqueue_last = entry; - queue->fastqueue_first = entry; + entry->msg = strdup(msg); + entry->next = NULL; + if(type == 1) { //low priority + if(queue->textqueue_last) { + queue->textqueue_last->next = entry; + queue->textqueue_last = entry; + } else { + queue->textqueue_last = entry; + queue->textqueue_first = entry; + } + } else if(type == 2) { //normal priority + if(queue->normalqueue_last) { + queue->normalqueue_last->next = entry; + queue->normalqueue_last = entry; + } else { + queue->normalqueue_last = entry; + queue->normalqueue_first = entry; + } + } else if(type == 3) { //high priority + if(queue->fastqueue_last) { + queue->fastqueue_last->next = entry; + queue->fastqueue_last = entry; + } else { + queue->fastqueue_last = entry; + queue->fastqueue_first = entry; + } } } return 1; } -static int calculate_penalty(char *message) { - int msglen = strlen(message); - int penalty = (2 + msglen / 100); - return penalty; -} - static void dequeue_bot(struct ClientSocket *client) { if(client->queue->penalty >= MAXPENALTY) return; int penalty; @@ -183,37 +233,34 @@ void queue_destroy(struct ClientSocket *client) { free(entry->msg); free(entry); } + if(client->queue->iofd) + iohandler_close(client->queue->iofd); free(client->queue); client->queue = NULL; } -static struct timeval lastloop; -void queue_init() { - gettimeofday(&lastloop, NULL); -} - - -void queue_loop() { - struct ClientSocket *bot; - struct timeval now; - gettimeofday(&now, NULL); - long mtime, seconds, useconds; - seconds = now.tv_sec - lastloop.tv_sec; - useconds = now.tv_usec - lastloop.tv_usec; - mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5; - int fullseconds = mtime/1000; - if(fullseconds) { - lastloop.tv_sec += fullseconds; - for(bot = getBots(0, NULL); bot; bot = getBots(0, bot)) { - if(bot->queue && bot->queue->penalty) { - bot->queue->penalty -= fullseconds; - if(bot->queue->penalty < 0) - bot->queue->penalty = 0; - } +static IOHANDLER_CALLBACK(queue_callback) { + struct BotQueue *queue = event->iofd->data; + switch(event->type) { + case IOEVENT_TIMEOUT: + queue->penalty -= queue->rem_penalty; + dequeue_bot(queue->client); + if(queue->penalty > 0) { + struct timeval timeout; + gettimeofday(&timeout, NULL); + if(queue->penalty >= MAXPENALTY) + queue->rem_penalty = (queue->penalty - MAXPENALTY)+1; + else + queue->rem_penalty = queue->penalty; + timeout.tv_sec += queue->rem_penalty; + queue->iofd = iohandler_timer(timeout, queue_callback); + queue->iofd->data = queue; + } else { + queue->iofd = NULL; + queue->penalty = 0; } - } - for(bot = getBots(0, NULL); bot; bot = getBots(0, bot)) { - if(bot->queue) - dequeue_bot(bot); + break; + default: + break; } }