From: pk910 Date: Sat, 14 Jan 2012 22:02:27 +0000 (+0100) Subject: fixed UserNode.c & IRCParser.c multi thread compatibility X-Git-Tag: v5.3~51 X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=commitdiff_plain;h=c361012eac11cfc2dc1c7426f7ad1146cebd594f fixed UserNode.c & IRCParser.c multi thread compatibility --- diff --git a/src/IRCParser.c b/src/IRCParser.c index ab1c69c..97e851a 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -173,10 +173,17 @@ static int is_onlyBotSeeUser(struct ClientSocket *client, struct UserNode *user) static IRC_CMD(raw_join) { if(from == NULL || argc < 1) return 0; + SYNCHRONIZE(cache_sync); struct UserNode *user = getUserByMask(from); struct ChanNode *chan = getChanByName(argv[0]); - if(!chan && (!user || !(user->flags & USERFLAG_ISBOT))) return 0; - if(chan && (((!user || !isBot(user)) && chan->chanbot != client->user) || ((user && isBot(user)) && client->user != user))) return 1; //we ignore it - but it's not a parse error + if(!chan && (!user || !(user->flags & USERFLAG_ISBOT))) { + DESYNCHRONIZE(cache_sync); + return 0; + } + if(chan && (((!user || !isBot(user)) && chan->chanbot != client->user) || ((user && isBot(user)) && client->user != user))) { + DESYNCHRONIZE(cache_sync); + return 1; //we ignore it - but it's not a parse error + } //let Bots always add themselves! (maybe they join invisible) if(user == NULL) { user = addUserMask(from); @@ -237,6 +244,7 @@ static IRC_CMD(raw_join) { chanuser->flags &= ~CHANUSERFLAG_VOICED; chanuser->flags |= CHANUSERFLAG_OPPED; } + DESYNCHRONIZE(cache_sync); return 1; } @@ -275,11 +283,21 @@ static void check_full_rejoin(struct ChanNode *chan) { static IRC_CMD(raw_part) { if(from == NULL || argc < 1) return 0; + SYNCHRONIZE(cache_sync); struct UserNode *user = getUserByMask(from); - if(user == NULL) return 0; + if(user == NULL) { + DESYNCHRONIZE(cache_sync); + return 0; + } struct ChanNode *chan = getChanByName(argv[0]); - if(chan == NULL) return 0; - if((!isBot(user) && chan->chanbot != client->user) || (isBot(user) && client->user != user)) return 1; //we ignore it - but it's not a parse error + if(chan == NULL) { + DESYNCHRONIZE(cache_sync); + return 0; + } + if((!isBot(user) && chan->chanbot != client->user) || (isBot(user) && client->user != user)) { + DESYNCHRONIZE(cache_sync); + return 1; //we ignore it - but it's not a parse error + } int keep_channel = 1; if(chan->chanbot == user && (chan->flags & CHANFLAG_REJOINING)) { struct ClientSocket **clients = chan->rejoin_array; @@ -289,6 +307,7 @@ static IRC_CMD(raw_part) { } free(chan->rejoin_array); chan->flags &= ~CHANFLAG_REJOINING; + DESYNCHRONIZE(cache_sync); return 0; } else if(isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { struct ChanUser *chanuser = getChanUser(user, chan); @@ -312,16 +331,27 @@ static IRC_CMD(raw_part) { putsock(client, "PART %s :magic hop", chan->name); putsock(client, "JOIN %s", chan->name); } + DESYNCHRONIZE(cache_sync); return 1; } static IRC_CMD(raw_quit) { if(from == NULL || argc < 1) return 0; + SYNCHRONIZE(cache_sync); struct UserNode *user = getUserByMask(from); - if(user == NULL) return 0; - if(!is_firstBotSeeUser(client, user)) return 1; //we ignore it - but it's not a parse error + if(user == NULL) { + DESYNCHRONIZE(cache_sync); + return 0; + } + if(!is_firstBotSeeUser(client, user)) { + DESYNCHRONIZE(cache_sync); + return 1; //we ignore it - but it's not a parse error + } int registering = !stricmp(argv[0], "Registered"); - if((registering && (user->flags & USERFLAG_ISBOT))) return 1; //bot is registering - just ignore it + if((registering && (user->flags & USERFLAG_ISBOT))) { + DESYNCHRONIZE(cache_sync); + return 1; //bot is registering - just ignore it + } delUser(user, 0); //a little bit crazy, but we want to delete the user on the channel's userlists - but not the users channel list event_quit(user, argv[0]); if(user->flags & USERFLAG_ISBOT) { @@ -356,6 +386,7 @@ static IRC_CMD(raw_quit) { registering_users = user; } else delUser(user, 1); //now we fully free the user + DESYNCHRONIZE(cache_sync); return 1; } @@ -391,16 +422,26 @@ void bot_disconnect(struct ClientSocket *client) { static IRC_CMD(raw_kick) { if(from == NULL || argc < 3) return 0; + SYNCHRONIZE(cache_sync); struct UserNode *user = getUserByMask(from); struct UserNode *target = getUserByNick(argv[1]); struct ChanNode *chan = getChanByName(argv[0]); - if(chan == NULL || target == NULL) return 0; - if(((!isBot(target) && chan->chanbot != client->user) || (isBot(target) && client->user != target))) return 1; //we ignore it - but it's not a parse error + if(chan == NULL || target == NULL) { + DESYNCHRONIZE(cache_sync); + return 0; + } + if(((!isBot(target) && chan->chanbot != client->user) || (isBot(target) && client->user != target))) { + DESYNCHRONIZE(cache_sync); + return 1; //we ignore it - but it's not a parse error + } int keep_channel = 1; if(isUserOnChan(target, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { if(user == NULL) { user = createTempUserMask(from); - if(!user) return 0; + if(!user) { + DESYNCHRONIZE(cache_sync); + return 0; + } user->flags |= USERFLAG_ISTMPUSER; } struct ChanUser *chanuser = getChanUser(target, chan); @@ -419,6 +460,7 @@ static IRC_CMD(raw_kick) { if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) { check_full_rejoin(chan); } + DESYNCHRONIZE(cache_sync); return 1; } diff --git a/src/UserNode.c b/src/UserNode.c index f90e72f..5f75aa2 100644 --- a/src/UserNode.c +++ b/src/UserNode.c @@ -69,15 +69,20 @@ struct UserNode* getUserByNick(const char *nick) { //case sensitive int userListIndex = get_nicklist_entry(*nick); if(userListIndex == -1 || userList[userListIndex] == NULL) return NULL; + SYNCHRONIZE(cache_sync); struct UserNode *user; for(user = userList[userListIndex]; user; user = user->next) { - if(!stricmp(nick, user->nick)) + if(!stricmp(nick, user->nick)) { + DESYNCHRONIZE(cache_sync); return user; + } } + DESYNCHRONIZE(cache_sync); return NULL; } struct UserNode* getUserByMask(const char *mask) { //case sensitive + SYNCHRONIZE(cache_sync); char cmask[strlen(mask)+1]; strcpy(cmask, mask); int i; @@ -86,12 +91,15 @@ struct UserNode* getUserByMask(const char *mask) { //case sensitive if(cmask[i] == '!') { cmask[i] = 0; user = getUserByNick(&cmask[0]); + DESYNCHRONIZE(cache_sync); return user; } else if(cmask[i] == '.') { //it's a server + DESYNCHRONIZE(cache_sync); return NULL; } } + DESYNCHRONIZE(cache_sync); return NULL; } @@ -99,6 +107,7 @@ struct UserNode* searchUserByNick(const char *nick) { //case insensitive if(!isalpha(*nick)) return getUserByNick(nick); + SYNCHRONIZE(cache_sync); int userListIndex; struct UserNode *user; @@ -106,22 +115,28 @@ struct UserNode* searchUserByNick(const char *nick) { //case insensitive userListIndex = get_nicklist_entry(tolower(*nick)); if(userListIndex != -1 && userList[userListIndex] != NULL) { for(user = userList[userListIndex]; user; user = user->next) { - if(!stricmp(nick, user->nick)) + if(!stricmp(nick, user->nick)) { + DESYNCHRONIZE(cache_sync); return user; + } } } //search in the upper case "section" userListIndex = get_nicklist_entry(toupper(*nick)); if(userListIndex != -1 && userList[userListIndex] != NULL) { for(user = userList[userListIndex]; user; user = user->next) { - if(!stricmp(nick, user->nick)) + if(!stricmp(nick, user->nick)) { + DESYNCHRONIZE(cache_sync); return user; + } } } + DESYNCHRONIZE(cache_sync); return NULL; } int countUsersWithHost(char *host) { + SYNCHRONIZE(cache_sync); int i, count = 0; struct UserNode *user; for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) { @@ -131,23 +146,28 @@ int countUsersWithHost(char *host) { } } } + DESYNCHRONIZE(cache_sync); return count; } char *getAuthFakehost(char *auth) { + SYNCHRONIZE(cache_sync); int i; struct UserNode *user; for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) { for(user = userList[i]; user; user = user->next) { if((user->flags & USERFLAG_ISAUTHED) && !strcmp(user->auth, auth) && isFakeHost(user->host)) { + DESYNCHRONIZE(cache_sync); return user->host; } } } + DESYNCHRONIZE(cache_sync); return NULL; } struct UserNode* getAllUsers(struct UserNode *last) { + SYNCHRONIZE(cache_sync); if(last == NULL || last->next == NULL) { int cindex; if(last == NULL) @@ -156,27 +176,35 @@ struct UserNode* getAllUsers(struct UserNode *last) { cindex = get_nicklist_entry(last->nick[0]) + 1; while(userList[cindex] == NULL && cindex < VALID_NICK_CHARS_FIRST_LEN) cindex++; - if(cindex > VALID_NICK_CHARS_FIRST_LEN) return NULL; + DESYNCHRONIZE(cache_sync); + if(cindex >= VALID_NICK_CHARS_FIRST_LEN) return NULL; return userList[cindex]; - } else + } else { + DESYNCHRONIZE(cache_sync); return last->next; + } } struct UserNode* getUsersWithAuth(const char *auth, struct UserNode *last) { + SYNCHRONIZE(cache_sync); int cindex = (last ? get_nicklist_entry(last->nick[0]) : 0); struct UserNode *cuser = last; while(cindex <= VALID_NICK_CHARS_FIRST_LEN) { for(cuser = (cuser ? cuser->next : userList[cindex]); cuser; cuser = cuser->next) { - if((cuser->flags & USERFLAG_ISAUTHED) && !strcmp(cuser->auth, auth)) + if((cuser->flags & USERFLAG_ISAUTHED) && !strcmp(cuser->auth, auth)) { + DESYNCHRONIZE(cache_sync); return cuser; + } } cindex++; cuser = NULL; } + DESYNCHRONIZE(cache_sync); return NULL; } int getUserCount() { + SYNCHRONIZE(cache_sync); int i, count = 0; struct UserNode *user; for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) { @@ -184,6 +212,7 @@ int getUserCount() { count++; } } + DESYNCHRONIZE(cache_sync); return count; }