From f90d21daf31f8d69e24406678be696afa8cae962 Mon Sep 17 00:00:00 2001 From: pk910 Date: Fri, 13 Jan 2012 17:48:27 +0100 Subject: [PATCH] fixes for multi thread support --- configure.ac | 2 ++ src/ClientSocket.c | 33 +++++++++++++++++++++++++++++---- src/bot_NeonHelp.c | 2 +- src/bot_NeonServ.c | 1 + src/cmd_global_addbot.c | 2 +- src/cmd_global_register.c | 4 ++-- src/cmd_neonserv_addtimeban.c | 2 +- src/cmd_neonserv_adduser.c | 2 +- src/cmd_neonserv_chanservsync.c | 4 ++-- src/cmd_neonserv_nicklist.c | 2 +- src/cmd_neonserv_uset.c | 2 +- src/event_neonserv_ctcp.c | 2 +- src/event_neonserv_notice.c | 2 +- src/event_neonspam_chanmsg.c | 2 +- src/event_neonspam_join.c | 2 +- src/main.c | 1 + src/main.h | 5 +++-- src/mysqlConn.c | 4 ++-- 18 files changed, 52 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 9dc6e4f..745ed80 100644 --- a/configure.ac +++ b/configure.ac @@ -57,6 +57,8 @@ AC_ARG_ENABLE([debug], [CFLAGS='-g -O0 -Wall -Wshadow -Werror'], [CFLAGS='-g -O2']) +CFLAGS="$CFLAGS -D_GNU_SOURCE" + # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h windows.h winsock2.h]) diff --git a/src/ClientSocket.c b/src/ClientSocket.c index 647a633..2789618 100644 --- a/src/ClientSocket.c +++ b/src/ClientSocket.c @@ -32,6 +32,7 @@ struct socket_list { #ifdef HAVE_THREADS static pthread_mutex_t synchronized; +static pthread_mutex_t synchronized_recv; #endif //the magic list :P @@ -40,6 +41,7 @@ static char buffer[BUF_SIZ]; void init_sockets() { THREAD_MUTEX_INIT(synchronized); + THREAD_MUTEX_INIT(synchronized_recv); sockets = malloc(sizeof(*sockets)); if (!sockets) @@ -370,7 +372,7 @@ int write_socket(struct ClientSocket *client, char* msg, int len) { void socket_loop(int timeout_seconds) { if(sockets == NULL) return; int is_synchronized = 1; - SYNCHRONIZE(synchronized); + SYNCHRONIZE(synchronized_recv); fd_set fds; struct timeval timeout; struct ClientSocket *sock, *next; @@ -387,7 +389,7 @@ void socket_loop(int timeout_seconds) { timeout.tv_usec = 0; ret = select(ret + 1, &fds, NULL, NULL, &timeout); if(ret == 0) { - DEDESYNCHRONIZE(synchronized); + DESYNCHRONIZE(synchronized_recv); return; } for (sock = sockets->data; sock; sock = next) { @@ -424,8 +426,28 @@ void socket_loop(int timeout_seconds) { sock->flags |= SOCKET_FLAG_QUITTED; } else { sock->traffic_in += bytes; + #ifdef HAVE_THREADS + char linesbuf[BUF_SIZ*2]; + strcpy(linesbuf, sock->buffer); + int used = 0; + for(i = 0; i < sock->bufferpos; i++) { + if(sock->buffer[i] == '\n') { + used = i+1; + } + } + if(used == sock->bufferpos + 1) { + //used all bytes so just reset the bufferpos + sock->bufferpos = 0; + } else { + for(i = 0; i < sock->bufferpos - used; i++) { + sock->buffer[i] = sock->buffer[i+used]; + } + sock->bufferpos -= used; + } is_synchronized = 0; - DESYNCHRONIZE(synchronized); + DESYNCHRONIZE(synchronized_recv); + parse_lines(sock, linesbuf, used); + #else int used = parse_lines(sock, sock->buffer, sock->bufferpos); if(used == sock->bufferpos + 1) { //used all bytes so just reset the bufferpos @@ -436,6 +458,9 @@ void socket_loop(int timeout_seconds) { } sock->bufferpos -= used; } + is_synchronized = 0; + DESYNCHRONIZE(synchronized_recv); + #endif #ifdef HAVE_THREADS FD_ZERO(&fds); //zero out all other pending sockets here (we have other threads receiving from them) #endif @@ -451,7 +476,7 @@ void socket_loop(int timeout_seconds) { } } if(is_synchronized) { - DESYNCHRONIZE(synchronized); + DESYNCHRONIZE(synchronized_recv); } } diff --git a/src/bot_NeonHelp.c b/src/bot_NeonHelp.c index ab241c1..5e0e605 100644 --- a/src/bot_NeonHelp.c +++ b/src/bot_NeonHelp.c @@ -263,7 +263,7 @@ static void neonhelp_event_privmsg_async(struct ClientSocket *client, struct Use } } printf_mysql_query("INSERT INTO `helpserv_requests` (`botid`, `host`, `hand`, `nick`, `status`, `supporter`, `time`, `text`) VALUES ('%d', '%s@%s', '%s', '%s', '0', '-1', UNIX_TIMESTAMP(), '%s')", client->clientid, escape_string(user->ident), escape_string(user->host), ((user->flags & USERFLAG_ISAUTHED) ? escape_string(user->auth) : "*"), escape_string(user->nick), escape_string(message)); - helpnode->suppid = (int) mysql_insert_id(mysql_conn); + helpnode->suppid = (int) mysql_insert_id(get_mysql_conn()); helpnode->log = NULL; helpnode->next = ((client->flags & SOCKET_HAVE_HELPNODE) ? client->botclass_helpnode : NULL); client->botclass_helpnode = helpnode; diff --git a/src/bot_NeonServ.c b/src/bot_NeonServ.c index 00b87c2..a0937b9 100644 --- a/src/bot_NeonServ.c +++ b/src/bot_NeonServ.c @@ -214,6 +214,7 @@ static const struct default_language_entry msgtab[] = { {"NS_NETINFO_USER", " User:"}, {"NS_NETINFO_CHANUSER", " Channel-User:"}, {"NS_NETINFO_OTHER", " Other:"}, + {"NS_NETINFO_THREADS", "Threads:"}, {"NS_NETINFO_VERSION", "Version:"}, {"NS_NETINFO_CODE", "Code:"}, {"NS_NETINFO_CODE_VALUE", "%s lines c code (view it at http://git.pk910.de/?p=NeonServV5.git;a=summary)"}, /* {ARGS: 20} */ diff --git a/src/cmd_global_addbot.c b/src/cmd_global_addbot.c index d30c742..1783834 100644 --- a/src/cmd_global_addbot.c +++ b/src/cmd_global_addbot.c @@ -36,7 +36,7 @@ CMD_BIND(global_cmd_addbot) { return; } printf_mysql_query("INSERT INTO `bots` (`nick`, `botclass`) VALUES ('%s', '%d')", escape_string(argv[0]), botid); - botid = (int) mysql_insert_id(mysql_conn); + botid = (int) mysql_insert_id(get_mysql_conn()); reply(getTextBot(), user, "NS_ADDBOT_DONE", argv[0], botid); logEvent(event); } diff --git a/src/cmd_global_register.c b/src/cmd_global_register.c index 45e5a75..548860d 100644 --- a/src/cmd_global_register.c +++ b/src/cmd_global_register.c @@ -210,7 +210,7 @@ static void global_cmd_register_async1(struct ClientSocket *client, struct Clien userid = atoi(row[0]); } else { printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth)); - userid = (int) mysql_insert_id(mysql_conn); + userid = (int) mysql_insert_id(get_mysql_conn()); } } if(client->botid) @@ -240,7 +240,7 @@ static void global_cmd_register_async1(struct ClientSocket *client, struct Clien printf_mysql_query("UPDATE `channels` SET `channel_registered` = UNIX_TIMESTAMP(), `channel_registrator` = '%d' WHERE `channel_id` = '%d'", adminid, chanid); } else { printf_mysql_query("INSERT INTO `channels` (`channel_name`, `channel_registered`, `channel_registrator`) VALUES ('%s', UNIX_TIMESTAMP(), '%d')", escape_string(channel), adminid); - chanid = (int) mysql_insert_id(mysql_conn); + chanid = (int) mysql_insert_id(get_mysql_conn()); } struct ClientSocket *bot; for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { diff --git a/src/cmd_neonserv_addtimeban.c b/src/cmd_neonserv_addtimeban.c index 09202f5..837812e 100644 --- a/src/cmd_neonserv_addtimeban.c +++ b/src/cmd_neonserv_addtimeban.c @@ -119,7 +119,7 @@ static void neonserv_cmd_addtimeban_async1(struct ClientSocket *client, struct C return; //add the ban printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(mask), (unsigned long) (time(0) + duration), userid, escape_string(reason)); - int banid = (int) mysql_insert_id(mysql_conn); + int banid = (int) mysql_insert_id(get_mysql_conn()); putsock(client, "MODE %s +b %s", chan->name, mask); for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { cuser = chanuser->user; diff --git a/src/cmd_neonserv_adduser.c b/src/cmd_neonserv_adduser.c index 8eccf67..0e8432b 100644 --- a/src/cmd_neonserv_adduser.c +++ b/src/cmd_neonserv_adduser.c @@ -151,7 +151,7 @@ static void neonserv_cmd_adduser_async1(struct ClientSocket *client, struct Clie } } else { printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth)); - userid = (int) mysql_insert_id(mysql_conn); + userid = (int) mysql_insert_id(get_mysql_conn()); } printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`) VALUES ('%d', '%d', '%d')", chan->channel_id, userid, caccess); reply(textclient, user, "NS_ADDUSER_DONE", nick, chan->name, caccess); diff --git a/src/cmd_neonserv_chanservsync.c b/src/cmd_neonserv_chanservsync.c index 78967d4..8581cb2 100644 --- a/src/cmd_neonserv_chanservsync.c +++ b/src/cmd_neonserv_chanservsync.c @@ -208,7 +208,7 @@ static void neonserv_cmd_chanservsync_notice_listener(struct UserNode *user, str neonserv_cmd_chanservsync_synchronize_user(neonserv_cmd_chanservsync_used->client, neonserv_cmd_chanservsync_used->textclient, neonserv_cmd_chanservsync_used->user, neonserv_cmd_chanservsync_used->chan, username, userid, caccess, seen_time, flags, 0); } else if(!stricmp(user->nick, "chanserv")) { printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(username)); - userid = (int) mysql_insert_id(mysql_conn); + userid = (int) mysql_insert_id(get_mysql_conn()); neonserv_cmd_chanservsync_synchronize_user(neonserv_cmd_chanservsync_used->client, neonserv_cmd_chanservsync_used->textclient, neonserv_cmd_chanservsync_used->user, neonserv_cmd_chanservsync_used->chan, username, userid, caccess, seen_time, flags, 1); } else { //lookup auth @@ -240,7 +240,7 @@ static AUTHLOOKUP_CALLBACK(neonserv_cmd_chanservsync_auth_lookup) { struct neonserv_cmd_chanservsync_auth_cache *cache = data; if(exists) { printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth)); - int userid = (int) mysql_insert_id(mysql_conn); + int userid = (int) mysql_insert_id(get_mysql_conn()); neonserv_cmd_chanservsync_synchronize_user(cache->client, cache->textclient, cache->user, cache->chan, auth, userid, cache->caccess, cache->seen, cache->flags, 1); } free(cache); diff --git a/src/cmd_neonserv_nicklist.c b/src/cmd_neonserv_nicklist.c index b04ccef..6178198 100644 --- a/src/cmd_neonserv_nicklist.c +++ b/src/cmd_neonserv_nicklist.c @@ -229,7 +229,7 @@ static void neonserv_cmd_nicklist_synchronize_user(struct ChanNode *chan, struct userid = atoi(row[0]); } else { printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(user->auth)); - userid = (int) mysql_insert_id(mysql_conn); + userid = (int) mysql_insert_id(get_mysql_conn()); } //check if already added printf_mysql_query("SELECT `chanuser_access`, `chanuser_id`, `chanuser_seen` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid); diff --git a/src/cmd_neonserv_uset.c b/src/cmd_neonserv_uset.c index 9e8a0c5..25a3118 100644 --- a/src/cmd_neonserv_uset.c +++ b/src/cmd_neonserv_uset.c @@ -79,7 +79,7 @@ CMD_BIND(neonserv_cmd_uset) { userid = atoi(row[0]); } else { printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(user->auth)); - userid = (int) mysql_insert_id(mysql_conn); + userid = (int) mysql_insert_id(get_mysql_conn()); } printf_mysql_query("INSERT INTO `noinvite` (`uid`, `cid`) VALUES ('%d', '%d')", userid, chan->channel_id); noinvite = 1; diff --git a/src/event_neonserv_ctcp.c b/src/event_neonserv_ctcp.c index 99ff47c..11d03e2 100644 --- a/src/event_neonserv_ctcp.c +++ b/src/event_neonserv_ctcp.c @@ -93,7 +93,7 @@ static void neonserv_event_ctcp_async1(struct ClientSocket *client, struct UserN duration = 3600; banmask = generate_banmask(user, banmaskBuf); printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason)); - int banid = (int) mysql_insert_id(mysql_conn); + int banid = (int) mysql_insert_id(get_mysql_conn()); char nameBuf[MAXLEN]; char banidBuf[20]; sprintf(nameBuf, "ban_%d", banid); diff --git a/src/event_neonserv_notice.c b/src/event_neonserv_notice.c index 11545bb..84fb51a 100644 --- a/src/event_neonserv_notice.c +++ b/src/event_neonserv_notice.c @@ -88,7 +88,7 @@ static void neonserv_event_notice_async1(struct ClientSocket *client, struct Use duration = 3600; banmask = generate_banmask(user, banmaskBuf); printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason)); - int banid = (int) mysql_insert_id(mysql_conn); + int banid = (int) mysql_insert_id(get_mysql_conn()); char nameBuf[MAXLEN]; char banidBuf[20]; sprintf(nameBuf, "ban_%d", banid); diff --git a/src/event_neonspam_chanmsg.c b/src/event_neonspam_chanmsg.c index c5bc02f..163315d 100644 --- a/src/event_neonspam_chanmsg.c +++ b/src/event_neonspam_chanmsg.c @@ -243,7 +243,7 @@ static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct Ch banmask = generate_banmask(chanuser->user, banmaskBuf); printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (punish_time ? (time(0) + punish_time) : 0), 0, escape_string(reason)); if(punish_time) { - int banid = (int) mysql_insert_id(mysql_conn); + int banid = (int) mysql_insert_id(get_mysql_conn()); char nameBuf[MAXLEN]; char banidBuf[20]; sprintf(nameBuf, "ban_%d", banid); diff --git a/src/event_neonspam_join.c b/src/event_neonspam_join.c index 3b31b92..5a169f2 100644 --- a/src/event_neonspam_join.c +++ b/src/event_neonspam_join.c @@ -97,7 +97,7 @@ static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanU banmask = generate_banmask(chanuser->user, banmaskBuf); printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (duration ? (time(0) + duration) : 0), 0, escape_string(reason)); if(duration) { - int banid = (int) mysql_insert_id(mysql_conn); + int banid = (int) mysql_insert_id(get_mysql_conn()); char nameBuf[MAXLEN]; char banidBuf[20]; sprintf(nameBuf, "ban_%d", banid); diff --git a/src/main.c b/src/main.c index a1b7161..4ad2d0d 100644 --- a/src/main.c +++ b/src/main.c @@ -136,6 +136,7 @@ main: statistics_enabled = get_int_field("statistics.enable"); queue_init(); + init_sockets(); init_timeq(); init_lang(); ssl_init(); diff --git a/src/main.h b/src/main.h index d3a5ec2..5002bcd 100644 --- a/src/main.h +++ b/src/main.h @@ -21,6 +21,7 @@ #define NEONSERV_VERSION "5.3" #define VERSION_PATCHLEVEL 543 +#include #include #include #include @@ -48,8 +49,8 @@ #define THREAD_MUTEX_INIT(var) { \ pthread_mutexattr_t mutex_attr; \ pthread_mutexattr_init(&mutex_attr);\ - pthread_mutexattr_setkind_np(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP);\ - pthread_mutex_init(&var, mutex_attr); \ + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP);\ + pthread_mutex_init(&var, &mutex_attr); \ } #define SYNCHRONIZE(var) pthread_mutex_lock(&var) #define DESYNCHRONIZE(var) pthread_mutex_unlock(&var) diff --git a/src/mysqlConn.c b/src/mysqlConn.c index ea3c2b8..3c3a5a8 100644 --- a/src/mysqlConn.c +++ b/src/mysqlConn.c @@ -20,7 +20,7 @@ struct mysql_conn_struct { unsigned long tid; - MYSQL *mysql_conn = NULL; + MYSQL *mysql_conn; struct used_result *used_results; struct escaped_string *escaped_strings; struct mysql_conn_struct *next; @@ -271,7 +271,7 @@ struct mysql_conn_struct *get_mysql_conn_struct() { return mysql_conn; } } - mysql_conn = malloc(*mysql_conn); + mysql_conn = malloc(sizeof(*mysql_conn)); mysql_conn->mysql_conn = mysql_init(NULL); mysql_conn->tid = tid; mysql_conn->used_results = NULL; -- 2.20.1