modified code to use IOHandler functions instead of own ones
[NeonServV5.git] / src / IRCQueue.c
index be472b387d3f383b19d69dbd1a19bb3464dca197..4fa520b02d6e7c7406df2fed83a4fd160727e3ef 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include "IRCQueue.h"
 #include "ClientSocket.h"
+#include "IOHandler.h"
 
 #define MAXPENALTY 8 /* 4 messages */
 
@@ -26,12 +27,16 @@ 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) {
@@ -56,6 +61,7 @@ int queue_add(struct ClientSocket *client, char* msg, int len) {
     struct BotQueue *queue = client->queue;
     char *args = strstr(msg, " ");
     int type;
+    int add_queue = 0;
     if(args) {
         *args = '\0';
         if(!stricmp(msg, "MODE")) 
@@ -75,36 +81,73 @@ 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);
+            queue->rem_penalty = (MAXPENALTY - queue->penalty) + 1;
+            timeout.tv_sec += queue->rem_penalty;
+            queue->iofd = iohandler_timer(timeout, queue_callback);
         }
-    } 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) {
+            perror("malloc() failed");
+            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;
@@ -183,37 +226,30 @@ 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);
+            queue->rem_penalty = (MAXPENALTY - queue->penalty) + 1;
+            timeout.tv_sec += queue->rem_penalty;
+            queue->iofd = iohandler_timer(timeout, queue_callback);
+        } 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;
     }
 }