Changeset 3532

Show
Ignore:
Timestamp:
01/04/07 02:57:39 (2 years ago)
Author:
timothy
Message:

Adding some asserts to help catch code running on the wrong thread.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Additions/MVUtilities.h

    r3531 r3532  
    2828        return [[var retain] autorelease]; 
    2929} 
     30 
     31#define MVAssertMainThreadRequired() \ 
     32        NSAssert1( [NSThread isMainThread], @"Method needs to run on the main thread, not %@.", [NSThread currentThread] ) 
     33 
     34#define MVAssertCorrectThreadRequired(thread) \ 
     35        NSAssert2( [NSThread currentThread] == (thread), @"Method needs to run on %@, not %@.", (thread), [NSThread currentThread] ) 
  • trunk/Additions/NSNotificationAdditions.m

    r3420 r3532  
    11#import "NSNotificationAdditions.h" 
    2 #import <pthread.h> 
    32 
    43@implementation NSNotificationCenter (NSNotificationCenterAdditions) 
    54- (void) postNotificationOnMainThread:(NSNotification *) notification { 
    6         if( pthread_main_np() ) return [self postNotification:notification]; 
     5        if( [NSThread isMainThread] ) return [self postNotification:notification]; 
    76        [self postNotificationOnMainThread:notification waitUntilDone:NO]; 
    87} 
    98 
    109- (void) postNotificationOnMainThread:(NSNotification *) notification waitUntilDone:(BOOL) wait { 
    11         if( pthread_main_np() ) return [self postNotification:notification]; 
     10        if( [NSThread isMainThread] ) return [self postNotification:notification]; 
    1211        [[self class] performSelectorOnMainThread:@selector( _postNotification: ) withObject:notification waitUntilDone:wait]; 
    1312} 
     
    1817 
    1918- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object { 
    20         if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:nil]; 
     19        if( [NSThread isMainThread] ) return [self postNotificationName:name object:object userInfo:nil]; 
    2120        [self postNotificationOnMainThreadWithName:name object:object userInfo:nil waitUntilDone:NO]; 
    2221} 
    2322 
    2423- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo { 
    25         if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:userInfo]; 
     24        if( [NSThread isMainThread] ) return [self postNotificationName:name object:object userInfo:userInfo]; 
    2625        [self postNotificationOnMainThreadWithName:name object:object userInfo:userInfo waitUntilDone:NO]; 
    2726} 
    2827 
    2928- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo waitUntilDone:(BOOL) wait { 
    30         if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:userInfo]; 
     29        if( [NSThread isMainThread] ) return [self postNotificationName:name object:object userInfo:userInfo]; 
    3130 
    3231        NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:3]; 
     
    3635 
    3736        [[self class] performSelectorOnMainThread:@selector( _postNotificationName: ) withObject:info waitUntilDone:wait]; 
    38         [info release]; 
    3937} 
    4038 
     
    4543 
    4644        [[self defaultCenter] postNotificationName:name object:object userInfo:userInfo]; 
     45 
     46        [info release]; 
    4747} 
    4848@end 
     
    5050@implementation NSNotificationQueue (NSNotificationQueueAdditions) 
    5151- (void) enqueueNotificationOnMainThread:(NSNotification *) notification postingStyle:(NSPostingStyle) postingStyle { 
    52         if( pthread_main_np() ) return [self enqueueNotification:notification postingStyle:postingStyle coalesceMask:( NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender ) forModes:nil]; 
     52        if( [NSThread isMainThread] ) return [self enqueueNotification:notification postingStyle:postingStyle coalesceMask:( NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender ) forModes:nil]; 
    5353        [self enqueueNotificationOnMainThread:notification postingStyle:postingStyle coalesceMask:( NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender ) forModes:nil]; 
    5454} 
    5555 
    5656- (void) enqueueNotificationOnMainThread:(NSNotification *) notification postingStyle:(NSPostingStyle) postingStyle coalesceMask:(unsigned) coalesceMask forModes:(NSArray *) modes { 
    57         if( pthread_main_np() ) return [self enqueueNotification:notification postingStyle:postingStyle coalesceMask:coalesceMask forModes:modes]; 
     57        if( [NSThread isMainThread] ) return [self enqueueNotification:notification postingStyle:postingStyle coalesceMask:coalesceMask forModes:modes]; 
    5858 
    5959        NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:4]; 
     
    6464 
    6565        [[self class] performSelectorOnMainThread:@selector( _enqueueNotification: ) withObject:info waitUntilDone:NO]; 
    66         [info release]; 
    6766} 
    6867 
     
    7473 
    7574        [[self defaultQueue] enqueueNotification:notification postingStyle:postingStyle coalesceMask:coalesceMask forModes:modes]; 
     75 
     76        [info release]; 
    7677} 
    7778@end 
  • trunk/Chat Core/MVIRCChatConnection.m

    r3530 r3532  
    208208        MVSafeRetainAssign( &_queueWait, [NSDate dateWithTimeIntervalSinceNow:JVQueueWaitBeforeConnected] ); 
    209209 
    210         [self _resetSendQueueInterval]; 
    211210        [self _resetSupportedFeatures]; 
    212211 
     
    223222 
    224223- (void) disconnectWithReason:(NSAttributedString *) reason { 
    225         [self cancelPendingReconnectAttempts]; 
     224        [self performSelector:@selector( cancelPendingReconnectAttempts ) withObject:nil inThread:[NSThread mainThread]]; 
     225 
    226226        if( _sendQueueProcessing && _connectionThread ) 
    227227                [self performSelector:@selector( _stopSendQueue ) withObject:nil inThread:_connectionThread]; 
     
    494494 
    495495- (void) setAwayStatusMessage:(NSAttributedString *) message { 
    496         [_awayMessage release]; 
    497         _awayMessage = nil; 
    498  
    499496        if( [[message string] length] ) { 
    500497                [[self localUser] _setStatus:MVChatUserAwayStatus]; 
    501498 
    502                 _awayMessage = [message copyWithZone:nil]
     499                MVSafeCopyAssign( &_awayMessage, message )
    503500 
    504501                NSData *msg = [[self class] _flattenedIRCDataForMessage:message withEncoding:[self encoding] andChatFormat:[self outgoingChatFormat]]; 
    505502                [self sendRawMessageImmediatelyWithComponents:@"AWAY :", msg, nil]; 
    506503        } else { 
     504                MVSafeAssign( &_awayMessage, nil ); 
    507505                [[self localUser] _setStatus:MVChatUserAvailableStatus]; 
    508506                [self sendRawMessage:@"AWAY" immediately:YES]; 
     
    519517 
    520518- (void) _connect { 
     519        MVAssertCorrectThreadRequired( _connectionThread ); 
     520 
    521521        id old = _chatConnection; 
    522522        _chatConnection = [[AsyncSocket allocWithZone:nil] initWithDelegate:self]; 
     
    527527        if( ! [_chatConnection connectToHost:[self server] onPort:[self serverPort] error:NULL] ) 
    528528                [self _didNotConnect]; 
     529        else [self _resetSendQueueInterval]; 
    529530} 
    530531 
     
    574575 
    575576- (void) _didDisconnect { 
     577        MVAssertMainThreadRequired(); 
     578 
    576579        if( _status == MVChatConnectionServerDisconnectedStatus ) { 
    577580                if( ABS( [_lastConnectAttempt timeIntervalSinceNow] ) > 300. ) 
     
    586589 
    587590- (BOOL) socketWillConnect:(AsyncSocket *) sock { 
     591        MVAssertCorrectThreadRequired( _connectionThread ); 
     592 
    588593        if( [[self proxyServer] length] && [self proxyServerPort] ) { 
    589594                if( _proxy == MVChatConnectionHTTPSProxy || _proxy == MVChatConnectionHTTPProxy ) { 
     
    635640 
    636641- (void) socket:(AsyncSocket *) sock willDisconnectWithError:(NSError *) error { 
     642        MVAssertCorrectThreadRequired( _connectionThread ); 
    637643        NSLog(@"connection error: %@", error ); 
    638644        MVSafeRetainAssign( &_lastError, error ); 
     
    640646 
    641647- (void) socketDidDisconnect:(AsyncSocket *) sock { 
     648        MVAssertCorrectThreadRequired( _connectionThread ); 
     649 
    642650        if( sock != _chatConnection ) return; 
    643651 
     
    691699 
    692700- (void) socket:(AsyncSocket *) sock didConnectToHost:(NSString *) host port:(UInt16) port { 
     701        MVAssertCorrectThreadRequired( _connectionThread ); 
     702 
    693703        [self setNickname:[self preferredNickname]]; 
    694704 
     
    706716 
    707717- (void) socket:(AsyncSocket *) sock didReadData:(NSData *) data withTag:(long) tag { 
     718        MVAssertCorrectThreadRequired( _connectionThread ); 
     719 
    708720        NSString *rawString = [self _newStringWithBytes:[data bytes] length:[data length]]; 
    709721 
     
    847859 
    848860- (void) _writeDataToServer:(id) raw { 
     861        MVAssertCorrectThreadRequired( _connectionThread ); 
     862 
    849863        NSMutableData *data = nil; 
    850864        NSString *string = nil; 
     
    879893 
    880894- (void) _readNextMessageFromServer { 
     895        MVAssertCorrectThreadRequired( _connectionThread ); 
     896 
    881897        static NSData *delimiter = nil; 
    882898        // IRC messages end in \x0D\x0A, but some non-compliant servers only use \x0A during the connecting phase 
     
    972988 
    973989- (void) _periodicEvents { 
     990        MVAssertCorrectThreadRequired( _connectionThread ); 
     991 
    974992        @synchronized( _knownUsers ) { 
    975993                NSMutableArray *removeList = [[NSMutableArray allocWithZone:nil] initWithCapacity:[_knownUsers count]]; 
     
    9981016 
    9991017- (void) _pingServer { 
     1018        MVAssertCorrectThreadRequired( _connectionThread ); 
    10001019        [self sendRawMessageImmediatelyWithFormat:@"PING %@", [self server]]; 
    10011020        [self performSelector:@selector( _pingServer ) withObject:nil afterDelay:JVPingServerInterval]; 
     
    10031022 
    10041023- (void) _startSendQueue { 
     1024        MVAssertCorrectThreadRequired( _connectionThread ); 
     1025 
    10051026        if( _sendQueueProcessing ) return; 
    10061027        _sendQueueProcessing = YES; 
     1028 
    10071029        if( _queueWait && [_queueWait timeIntervalSinceNow] > 0. ) 
    10081030                [self performSelector:@selector( _sendQueue ) withObject:nil afterDelay:[_queueWait timeIntervalSinceNow]]; 
     
    10111033 
    10121034- (void) _stopSendQueue { 
     1035        MVAssertCorrectThreadRequired( _connectionThread ); 
     1036        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector( _sendQueue ) object:nil]; 
    10131037        _sendQueueProcessing = NO; 
    1014         [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector( _sendQueue ) object:nil]; 
    10151038} 
    10161039 
    10171040- (void) _resetSendQueueInterval { 
     1041        MVAssertCorrectThreadRequired( _connectionThread ); 
     1042 
    10181043        [self _stopSendQueue]; 
    10191044        @synchronized( _sendQueue ) { 
     
    10241049 
    10251050- (void) _sendQueue { 
     1051        MVAssertCorrectThreadRequired( _connectionThread ); 
     1052 
    10261053        @synchronized( _sendQueue ) { 
    10271054                if( ! [_sendQueue count] ) { 
     
    10811108 
    10821109- (void) _scheduleWhoisForUser:(MVChatUser *) user { 
     1110        MVAssertCorrectThreadRequired( _connectionThread ); 
     1111 
    10831112        if( ! _pendingWhoisUsers ) 
    10841113                _pendingWhoisUsers = [[NSMutableSet allocWithZone:nil] initWithCapacity:50]; 
     
    10891118 
    10901119- (void) _whoisNextScheduledUser { 
     1120        MVAssertCorrectThreadRequired( _connectionThread ); 
     1121 
    10911122        if( [_pendingWhoisUsers count] ) { 
    10921123                MVChatUser *user = [_pendingWhoisUsers anyObject]; 
     
    10961127 
    10971128- (void) _whoisWatchedUsers { 
     1129        MVAssertCorrectThreadRequired( _connectionThread ); 
     1130 
    10981131        [self performSelector:@selector( _whoisWatchedUsers ) withObject:nil afterDelay:JVWatchedUserWHOISDelay]; 
    10991132 
     
    11151148 
    11161149- (void) _checkWatchedUsers { 
     1150        MVAssertCorrectThreadRequired( _connectionThread ); 
     1151 
    11171152        if( _watchCommandSupported ) return; // we don't need to call this anymore, return before we reschedule 
    11181153 
     
    12311266 
    12321267- (void) _handle001WithParameters:(NSArray *) parameters fromSender:(id) sender { 
     1268        MVAssertCorrectThreadRequired( _connectionThread ); 
     1269 
    12331270        MVSafeRetainAssign( &_queueWait, [NSDate dateWithTimeIntervalSinceNow:0.5] ); 
    12341271 
     
    12551292 
    12561293- (void) _handle005WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_ISUPPORT 
     1294        MVAssertCorrectThreadRequired( _connectionThread ); 
     1295 
    12571296        if( ! _serverInformation ) 
    12581297                _serverInformation = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:5]; 
     
    13791418 
    13801419- (void) _handle433WithParameters:(NSArray *) parameters fromSender:(id) sender { // ERR_NICKNAMEINUSE 
     1420        MVAssertCorrectThreadRequired( _connectionThread ); 
     1421 
    13811422        if( ! [self isConnected] ) { 
    13821423                NSString *nick = [self nextAlternateNickname]; 
     
    13901431 
    13911432- (void) _handlePrivmsgWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     1433        MVAssertCorrectThreadRequired( _connectionThread ); 
     1434 
    13921435        // if the sender is a server lets make a user for the server name 
    13931436        // this is not ideal but the notifications need user objects 
     
    14281471 
    14291472- (void) _handleNoticeWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     1473        MVAssertCorrectThreadRequired( _connectionThread ); 
     1474 
    14301475        // if the sender is a server lets make a user for the server name 
    14311476        // this is not ideal but the notifications need user objects 
     
    14801525 
    14811526- (void) _handleCTCP:(NSDictionary *) ctcpInfo { 
     1527        MVAssertMainThreadRequired(); 
     1528 
    14821529        BOOL request = [[ctcpInfo objectForKey:@"request"] boolValue]; 
    14831530        NSData *data = [ctcpInfo objectForKey:@"data"]; 
     
    17731820 
    17741821- (void) _handleCTCP:(NSMutableData *) data asRequest:(BOOL) request fromSender:(MVChatUser *) sender forRoom:(MVChatRoom *) room { 
     1822        MVAssertCorrectThreadRequired( _connectionThread ); 
     1823 
    17751824        NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:4]; 
    17761825        if( data ) [info setObject:data forKey:@"data"]; 
     
    17861835 
    17871836- (void) _handleJoinWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     1837        MVAssertCorrectThreadRequired( _connectionThread ); 
     1838 
    17881839        if( [parameters count] && [sender isKindOfClass:[MVChatUser class]] ) { 
    17891840                NSString *name = [self _stringFromPossibleData:[parameters objectAtIndex:0]]; 
     
    18101861 
    18111862- (void) _handlePartWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     1863        MVAssertCorrectThreadRequired( _connectionThread ); 
     1864 
    18121865        if( [parameters count] >= 1 && [sender isKindOfClass:[MVChatUser class]] ) { 
    18131866                NSString *roomName = [self _stringFromPossibleData:[parameters objectAtIndex:0]]; 
     
    18271880 
    18281881- (void) _handleQuitWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     1882        MVAssertCorrectThreadRequired( _connectionThread ); 
     1883 
    18291884        if( [parameters count] && [sender isKindOfClass:[MVChatUser class]] ) { 
    18301885                if( [sender isLocalUser] ) return; 
     
    18501905 
    18511906- (void) _handleKickWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     1907        MVAssertCorrectThreadRequired( _connectionThread ); 
     1908 
    18521909        // if the sender is a server lets make a user for the server name 
    18531910        // this is not ideal but the notifications need user objects 
     
    18731930 
    18741931- (void) _handleTopicWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     1932        MVAssertCorrectThreadRequired( _connectionThread ); 
     1933 
    18751934        // if the sender is a server lets make a user for the server name 
    18761935        // this is not ideal but the notifications need user objects 
     
    20172076 
    20182077- (void) _handleModeWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     2078        MVAssertCorrectThreadRequired( _connectionThread ); 
     2079 
    20192080        // if the sender is a server lets make a user for the server name 
    20202081        // this is not ideal but the notifications need user objects 
     
    20342095 
    20352096- (void) _handle324WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_CHANNELMODEIS 
     2097        MVAssertCorrectThreadRequired( _connectionThread ); 
     2098 
    20362099        if( [parameters count] >= 3 ) { 
    20372100                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:1]]; 
     
    20442107 
    20452108- (void) _handlePingWithParameters:(NSArray *) parameters fromSender:(id) sender { 
     2109        MVAssertCorrectThreadRequired( _connectionThread ); 
     2110 
    20462111        if( [parameters count] >= 1 ) { 
    20472112                if( [parameters count] == 1 ) 
     
    20552120 
    20562121- (void) _handleInviteWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     2122        MVAssertCorrectThreadRequired( _connectionThread ); 
     2123 
    20572124        // if the sender is a server lets make a user for the server name 
    20582125        // this is not ideal but the notifications need user objects 
     
    20682135 
    20692136- (void) _handleNickWithParameters:(NSArray *) parameters fromSender:(MVChatUser *) sender { 
     2137        MVAssertCorrectThreadRequired( _connectionThread ); 
     2138 
    20702139        if( [parameters count] == 1 && [sender isKindOfClass:[MVChatUser class]] ) { 
    20712140                NSString *nick = [self _stringFromPossibleData:[parameters objectAtIndex:0]]; 
     
    21032172 
    21042173- (void) _handle303WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_ISON 
     2174        MVAssertCorrectThreadRequired( _connectionThread ); 
     2175 
    21052176        if( [parameters count] == 2 && _isonSentCount > 0 ) { 
    21062177                _isonSentCount--; 
     
    21572228 
    21582229- (void) _handle301WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_AWAY 
     2230        MVAssertCorrectThreadRequired( _connectionThread ); 
     2231 
    21592232        if( [parameters count] == 3 ) { 
    21602233                MVChatUser *user = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:1]]; 
     
    21682241 
    21692242- (void) _handle305WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_UNAWAY 
     2243        MVAssertCorrectThreadRequired( _connectionThread ); 
    21702244        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionSelfAwayStatusChangedNotification object:self userInfo:nil]; 
    21712245} 
    21722246 
    21732247- (void) _handle306WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_NOWAWAY 
     2248        MVAssertCorrectThreadRequired( _connectionThread ); 
    21742249        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:MVChatConnectionSelfAwayStatusChangedNotification object:self userInfo:nil]; 
    21752250} 
     
    21792254 
    21802255- (void) _handle353WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_NAMREPLY 
     2256        MVAssertCorrectThreadRequired( _connectionThread ); 
     2257 
    21812258        if( [parameters count] == 4 ) { 
    21822259                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:2]]; 
     
    22232300 
    22242301- (void) _handle366WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_ENDOFNAMES 
     2302        MVAssertCorrectThreadRequired( _connectionThread ); 
     2303 
    22252304        if( [parameters count] >= 2 ) { 
    22262305                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:1]]; 
     
    22432322 
    22442323- (void) _handle352WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_WHOREPLY 
     2324        MVAssertCorrectThreadRequired( _connectionThread ); 
     2325 
    22452326        if( [parameters count] >= 7 ) { 
    22462327                MVChatUser *member = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:5]]; 
     
    22742355 
    22752356- (void) _handle315WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_ENDOFWHO 
     2357        MVAssertCorrectThreadRequired( _connectionThread ); 
     2358 
    22762359        if( [parameters count] >= 2 ) { 
    22772360                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:1]]; 
     
    22842367 
    22852368- (void) _handle322WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_LIST 
     2369        MVAssertCorrectThreadRequired( _connectionThread ); 
     2370 
    22862371        if( [parameters count] == 4 ) { 
    22872372                NSString *room = [parameters objectAtIndex:1]; 
     
    23002385 
    23012386- (void) _handle367WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_BANLIST 
     2387        MVAssertCorrectThreadRequired( _connectionThread ); 
     2388 
    23022389        if( [parameters count] >= 3 ) { 
    23032390                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:1]]; 
     
    23202407 
    23212408- (void) _handle368WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_ENDOFBANLIST 
     2409        MVAssertCorrectThreadRequired( _connectionThread ); 
     2410 
    23222411        if( [parameters count] >= 2 ) { 
    23232412                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:1]]; 
     
    23312420 
    23322421- (void) _handle332WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_TOPIC 
     2422        MVAssertCorrectThreadRequired( _connectionThread ); 
     2423 
    23332424        if( [parameters count] == 3 ) { 
    23342425                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:1]]; 
     
    23382429 
    23392430- (void) _handle333WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_TOPICWHOTIME_IRCU 
     2431        MVAssertCorrectThreadRequired( _connectionThread ); 
     2432 
    23402433        if( [parameters count] >= 4 ) { 
    23412434                MVChatRoom *room = [self joinedChatRoomWithName:[parameters objectAtIndex:1]]; 
     
    23522445 
    23532446- (void) _handle311WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_WHOISUSER 
     2447        MVAssertCorrectThreadRequired( _connectionThread ); 
     2448 
    23542449        if( [parameters count] == 6 ) { 
    23552450                NSString *nick = [parameters objectAtIndex:1]; 
     
    23692464 
    23702465- (void) _handle312WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_WHOISSERVER 
     2466        MVAssertCorrectThreadRequired( _connectionThread ); 
     2467 
    23712468        if( [parameters count] >= 3 ) { 
    23722469                MVChatUser *user = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:1]]; 
     
    23762473 
    23772474- (void) _handle313WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_WHOISOPERATOR 
     2475        MVAssertCorrectThreadRequired( _connectionThread ); 
     2476 
    23782477        if( [parameters count] >= 2 ) { 
    23792478                MVChatUser *user = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:1]]; 
     
    23832482 
    23842483- (void) _handle317WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_WHOISIDLE 
     2484        MVAssertCorrectThreadRequired( _connectionThread ); 
     2485 
    23852486        if( [parameters count] >= 3 ) { 
    23862487                MVChatUser *user = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:1]]; 
     
    23992500 
    24002501- (void) _handle318WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_ENDOFWHOIS 
     2502        MVAssertCorrectThreadRequired( _connectionThread ); 
     2503 
    24012504        if( [parameters count] >= 2 ) { 
    24022505                MVChatUser *user = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:1]]; 
     
    24132516 
    24142517- (void) _handle319WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_WHOISCHANNELS 
     2518        MVAssertCorrectThreadRequired( _connectionThread ); 
     2519 
    24152520        if( [parameters count] == 3 ) { 
    24162521                NSString *rooms = [self _stringFromPossibleData:[parameters objectAtIndex:2]]; 
     
    24432548 
    24442549- (void) _handle320WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_WHOISIDENTIFIED 
     2550        MVAssertCorrectThreadRequired( _connectionThread ); 
     2551 
    24452552        if( [parameters count] == 3 ) { 
    24462553                NSString *comment = [self _stringFromPossibleData:[parameters objectAtIndex:2]]; 
     
    24562563 
    24572564- (void) _handle401WithParameters:(NSArray *) parameters fromSender:(id) sender { // ERR_NOSUCHNICK 
     2565        MVAssertCorrectThreadRequired( _connectionThread ); 
     2566 
    24582567        if( [parameters count] >= 2 ) { 
    24592568                MVChatUser *user = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:1]]; 
     
    24672576 
    24682577- (void) _handle402WithParameters:(NSArray *) parameters fromSender:(id) sender { // ERR_NOSUCHSERVER 
     2578        MVAssertCorrectThreadRequired( _connectionThread ); 
     2579 
    24692580        // some servers send back 402 (No such server) when we send our double nickname WHOIS requests, treat as a user 
    24702581        if( [parameters count] >= 2 ) { 
     
    24792590 
    24802591- (void) _handle421WithParameters:(NSArray *) parameters fromSender:(id) sender { // ERR_UNKNOWNCOMMAND 
     2592        MVAssertCorrectThreadRequired( _connectionThread ); 
     2593 
    24812594        if( [parameters count] >= 2 ) { 
    24822595                NSString *command = [parameters objectAtIndex:1]; 
     
    24942607 
    24952608- (void) _handle604WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_NOWON_BAHAMUT_UNREAL 
     2609        MVAssertCorrectThreadRequired( _connectionThread ); 
     2610 
    24962611        if( [parameters count] >= 5 ) { 
    24972612                MVChatUser *user = [self chatUserWithUniqueIdentifier:[parameters objectAtIndex:1]]; 
     
    25072622 
    25082623- (void) _handle600WithParameters:(NSArray *) parameters fromSender:(id) sender { // RPL_LOGON_BAHAMUT_UNREAL 
    2509         if( [parameters count] >= 5 ) { 
     2624        MVAssertCorrectThreadRequired( _connectionThread ); 
     2625 
     2626        if( [parameters count] >= 5 ) 
    25102627                [self _handle604WithParameters:parameters fromSender:sender]; // do everything we do above 
    2511         } 
    25122628} 
    25132629@end