new buffering strategy

This commit is contained in:
anon 2024-06-28 21:56:53 +02:00
parent 43d31d6b79
commit f06b358d0f
7 changed files with 160 additions and 131 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.gdb_history .gdb_history
*.o *.o
*.out
hibot hibot

View File

@ -6,7 +6,6 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <signal.h> #include <signal.h>
#include <sys/time.h>
extern syntax_setter_t syntax_functions[]; extern syntax_setter_t syntax_functions[];
@ -31,111 +30,30 @@ char * username_root(const char * const fullname){
return r; return r;
} }
typedef struct { void on_request_timeout(int unused) {
int is_active; (void)(unused);
char * user; drop_request(request_queue[0]);
language_t language;
struct itimerval timer;
char * buffer[128]; // XXX: no overflow detection/avertion
unsigned int buffer_head; // is implemented on this bunch
} request_t;
void init_request(request_t * request) {
request->is_active = 0;
request->timer.it_value.tv_sec = 0;
request->timer.it_value.tv_usec = 0;
request->timer.it_interval.tv_sec = 0;
request->timer.it_interval.tv_usec = 0;
request->buffer_head = 0;
} }
request_t request_queue__[message_queue_size]; void flush_request(request_t * request) {
request_t * request_queue[message_queue_size]; // Message header
unsigned int request_queue_head = 0;
static inline
void touch_request_timer(request_t * request) {
request->timer.it_value.tv_sec = message_timeout;
setitimer(ITIMER_REAL, &(request->timer), NULL);
}
void activate_request(request_t * request) {
request->is_active = 1;
/* message header */
char * short_name = username_root(request->user); char * short_name = username_root(request->user);
irc_message(short_name); irc_message(short_name);
free(short_name); free(short_name);
}
request_t * take_request(const char * const user, language_t language) { // Message body
for (unsigned int i = 0; i < request_queue_head; i++) { syntax_count = 0;
if(!strcmp(request_queue[i]->user, user)) { syntax_functions[request->language]();
return request_queue[i]; for (unsigned i = 0; i < request->buffer_head; i++) {
} irc_message(syntax_highlight(request->buffer[i]));
} }
if (request_queue_head == message_queue_size) { // Message footer
return NULL;
}
request_t * request = request_queue[request_queue_head];
request->language = language;
request->user = strdup(user);
if (request_queue_head == 0) {
activate_request(request);
}
++request_queue_head;
char * log_message;
asprintf(&log_message, "Took message: %p (%d)", (void*)request, request_queue_head);
log_notice(log_message);
free(log_message);
return request;
}
void drop_reqest() {
request_t * request = request_queue[0];
if (message_queue_size > 1) {
for (unsigned int i = 0; i < request_queue_head; i++) {
request_queue[i] = request_queue[i+1];
}
request_queue[request_queue_head] = request;
}
--request_queue_head;
request->is_active = 0;
free(request->user);
if (request_queue_head) {
activate_request(request_queue[0]);
for (unsigned int i = 0; i < request_queue[0]->buffer_head; i++) {
irc_message(request_queue[0]->buffer[i]);
free(request_queue[0]->buffer[i]);
}
request_queue[0]->buffer_head = 0;
touch_request_timer(request_queue[0]);
}
char * log_message;
asprintf(&log_message, "Dropped message: %p (%d)", (void*)request, request_queue_head);
log_notice(log_message);
free(log_message);
}
void on_message_timeout(int unused) {
(void)unused;
/* message footer */
irc_message("--"); irc_message("--");
drop_reqest(request_queue); logf_notice("Flushed message: %p (%d)", (void*)request, request_queue_head);
drop_request(request);
} }
static static
@ -165,6 +83,7 @@ void irc_help() {
irc_message(" !<language> // set language for next message"); irc_message(" !<language> // set language for next message");
irc_message(" <code> // echo this code"); irc_message(" <code> // echo this code");
irc_message(" !<language> <code> // set language and echo code"); irc_message(" !<language> <code> // set language and echo code");
irc_message(" !-- // flush all code");
irc_message("--"); irc_message("--");
} }
@ -182,10 +101,7 @@ void event_connect(irc_session_t * session,
log_notice("IRC connection secured."); log_notice("IRC connection secured.");
irc_cmd_join(session, channel, 0); irc_cmd_join(session, channel, 0);
char * buffer; logf_notice("Joined destination channel: `%s`.", channel);
asprintf(&buffer, "Joined destination channel: `%s`.", channel);
log_notice(buffer);
free(buffer);
} }
static static
@ -194,6 +110,7 @@ void event_disconnect(irc_session_t * session,
const char * origin, const char * origin,
const char ** params, const char ** params,
unsigned int count) { unsigned int count) {
(void)session;
(void)event; (void)event;
(void)origin; (void)origin;
(void)params; (void)params;
@ -218,6 +135,11 @@ void event_privmsg(irc_session_t * session,
/* Is command */ /* Is command */
if (*message == '!') { if (*message == '!') {
if (!strcmp(message, "!help")) {
irc_help();
goto END;
}
/* */
terminator = message; terminator = message;
while (*terminator != ' ') { while (*terminator != ' ') {
if (*terminator == '\0') { if (*terminator == '\0') {
@ -227,38 +149,39 @@ void event_privmsg(irc_session_t * session,
++terminator; ++terminator;
} }
*terminator = '\0'; *terminator = '\0';
/* */ /* */
if (!strcmp(message, "!help")) { {
irc_help(); request_t * request = take_request(origin);
goto END;
} if (!strcmp(message, "!--")) {
/* get language */ if (request) {
for (char * s = message + 1; *s != '\0'; s++) { flush_request(request);
*s = toupper(*s); }
} goto END;
int l = translate_language(message + 1); }
message = terminator + 1;
if (l != -1) { /* get language */
language = l; for (char * s = message + 1; *s != '\0'; s++) {
syntax_count = 0; *s = toupper(*s);
syntax_functions[language](); }
} int l = translate_language(message + 1);
message = terminator + 1;
if (l != -1) {
request->language = l;
}
}
} }
/* Is code */ /* Is code */
if (is_code) { if (is_code) {
request_t * request = take_request(origin, language); request_t * request = take_request(origin);
if (!request) { if (!request) {
irc_private_message(origin, message_queue_full_message); irc_private_message(origin, message_queue_full_message);
goto END; goto END;
} }
if (request->is_active) { touch_request_timer(request);
touch_request_timer(request); request->buffer[request->buffer_head++] = strdup(message);
irc_message(syntax_highlight(message));
} else {
request->buffer[request->buffer_head++] = strdup(syntax_highlight(message));
}
} }
END: END:
@ -302,7 +225,7 @@ int connect_bot(const char * const server, const short port) {
request_queue[i] = &request_queue__[i]; request_queue[i] = &request_queue__[i];
init_request(request_queue[i]); init_request(request_queue[i]);
} }
signal(SIGALRM, on_message_timeout); signal(SIGALRM, on_request_timeout);
irc_connect(session, irc_connect(session,
server, server,

View File

@ -2,7 +2,7 @@
const char * const username = PROGRAM_NAME; const char * const username = PROGRAM_NAME;
const char * const password = ""; const char * const password = "";
const int message_timeout = 3; const int message_timeout = 10;
const char * const message_queue_full_message = "Air space too crowded in this area."; const char * const message_queue_full_message = "Air space too crowded in this area.";
#define message_queue_size 3 #define message_queue_size 3
#define DEFAULT_LANGUAGE C #define DEFAULT_LANGUAGE C

View File

@ -1,6 +1,8 @@
#ifndef LOG_H #ifndef LOG_H
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
FILE * log_file; FILE * log_file;
@ -13,12 +15,32 @@ void log(const char * const message, const char * const color) {
} }
void log_notice(const char * const message) { void log_notice(const char * const message) {
log("", message); log("", message);
}
void logf_notice(const char * const format, ...) {
va_list args;
va_start(args, format);
char * msg;
vasprintf(&msg, format, args);
log_notice(msg);
free(msg);
} }
void log_error(const char * const message) { void log_error(const char * const message) {
log("\033[33m", message); log("\033[33m", message);
} }
void logf_error(const char * const format, ...) {
va_list args;
va_start(args, format);
char * msg;
vasprintf(&msg, format, args);
log_error(msg);
free(msg);
}
#define LOG_H #define LOG_H
#endif #endif

View File

@ -14,12 +14,11 @@ typedef enum {
ADA, ADA,
} language_t; } language_t;
language_t language = DEFAULT_LANGUAGE;
typedef void (*syntax_setter_t)(void); typedef void (*syntax_setter_t)(void);
#include "log.h" #include "log.h"
#include "syntax.h" #include "syntax.h"
#include "request.h"
#include "bot.h" #include "bot.h"
syntax_setter_t syntax_functions[] = { syntax_setter_t syntax_functions[] = {
@ -55,7 +54,7 @@ signed main(int argc, char * * argv) {
log_file = LOG_FILE; log_file = LOG_FILE;
syntax_functions[language](); syntax_functions[DEFAULT_LANGUAGE]();
connect_bot(server, port_i); connect_bot(server, port_i);
connection_loop(); connection_loop();

83
source/request.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef REQUEST_H
#define REQUEST_H
#include <stdlib.h>
#include <sys/time.h>
typedef struct {
char * user;
language_t language;
struct itimerval timer;
char * buffer[128]; // XXX: no overflow detection/avertion
unsigned int buffer_head; // is implemented on this bunch
} request_t;
request_t request_queue__[message_queue_size];
request_t * request_queue[message_queue_size];
unsigned int request_queue_head = 0;
static inline
void init_request(request_t * request) {
request->timer.it_value.tv_sec = 0;
request->timer.it_value.tv_usec = 0;
request->timer.it_interval.tv_sec = 0;
request->timer.it_interval.tv_usec = 0;
request->language = DEFAULT_LANGUAGE;
request->buffer_head = 0;
}
static inline
void reinit_request(request_t * request) {
free(request->user);
for (long i = 0; i < request->buffer_head; i++) {
free(request->buffer[i]);
}
init_request(request);
}
static inline
void touch_request_timer(request_t * const request) {
request->timer.it_value.tv_sec = message_timeout;
setitimer(ITIMER_REAL, &(request->timer), NULL);
}
request_t * take_request(const char * const user) {
for (unsigned int i = 0; i < request_queue_head; i++) {
if(!strcmp(request_queue[i]->user, user)) {
return request_queue[i];
}
}
if (request_queue_head == message_queue_size) {
return NULL;
}
request_t * request = request_queue[request_queue_head];
request->user = strdup(user);
++request_queue_head;
logf_notice("Took message: %p (%d)", (void*)request, request_queue_head);
return request;
}
void drop_request(request_t * const request) {
setitimer(ITIMER_REAL, NULL, NULL);
reinit_request(request);
if (message_queue_size > 1) {
for (unsigned int i = 0; i < request_queue_head; i++) {
request_queue[i] = request_queue[i+1];
}
request_queue[request_queue_head] = request;
}
--request_queue_head;
logf_notice("Dropped message: %p (%d)", (void*)request, request_queue_head);
}
#endif

View File

@ -210,7 +210,8 @@ void syntax_cpp (void) {
char * specials [] = { char * specials [] = {
"int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t",
"FILE", "std", "typeof", "cout", "cin", "endl", "timespec", "tm" "FILE", "std", "typeof", "cout", "cin", "endl", "timespec", "tm",
"vector", "stack", "map", "unordered_map", "queue", "deque",
/* TODO: I don't really care about this, but some people do, Anon please add what you find interesting in here... */ /* TODO: I don't really care about this, but some people do, Anon please add what you find interesting in here... */
}; };