Changeset 3703
- Timestamp:
- 07/08/07 02:32:00 (1 year ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Plug-Ins/Web Interface/JVWebInterfacePlugin.m
r3701 r3703 24 24 static NSString *JVWebInterfaceOverrideStyle = @"overrideStyle"; 25 25 26 #define ActivityQueueFull 1 27 #define ActivityQueueEmpty 2 28 26 29 static void processCommand( http_req_t *req, http_resp_t *resp, http_server_t *server ) { 27 30 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; … … 225 228 226 229 [pool release]; 230 } 231 232 static int socketStatus( int sock, int timeoutSecs, int timeoutMsecs ) { 233 int selectResult = 0; 234 fd_set checkSet; 235 struct timeval timeout; 236 237 FD_ZERO( &checkSet ); 238 FD_SET( sock, &checkSet ); 239 240 timeout.tv_sec = timeoutSecs; 241 timeout.tv_usec = timeoutMsecs; 242 243 if( ( selectResult = select( sock + 1, &checkSet, 0, 0, &timeout ) ) < 0 ) 244 return -1; 245 if( ! selectResult ) 246 return 0; 247 return 1; 227 248 } 228 249 … … 481 502 NSXMLDocument *doc = [NSXMLDocument documentWithRootElement:[NSXMLElement elementWithName:@"queue"]]; 482 503 [info setObject:doc forKey:@"activityQueue"]; 483 504 505 NSConditionLock *activityLock = [[NSConditionLock alloc] initWithCondition:ActivityQueueEmpty]; 506 [info setObject:activityLock forKey:@"activityLock"]; 507 [activityLock release]; 508 484 509 NSMutableDictionary *styles = [NSMutableDictionary dictionary]; 485 510 [info setObject:styles forKey:@"styles"]; … … 654 679 } 655 680 681 BOOL wait = ( [arguments objectForKey:@"wait"] ? YES : NO ); 682 683 NSConditionLock *activityLock = nil; 684 NSXMLDocument *activityQueue = nil; 685 656 686 @synchronized( _clients ) { 657 687 NSDictionary *info = [_clients objectForKey:client]; … … 662 692 } 663 693 664 NSXMLDocument *doc = [info objectForKey:@"activityQueue"]; 665 if( ! doc ) return; 666 667 if( [[doc rootElement] childCount] ) { 668 NSData *xml = [doc XMLData]; 694 activityLock = [info objectForKey:@"activityLock"]; 695 activityQueue = [info objectForKey:@"activityQueue"]; 696 697 if( ! activityLock || ! activityQueue ) { 698 resp -> status_code = 500; 699 resp -> reason_phrase = "Internal Error"; 700 } 701 } 702 703 if( wait && ! [activityLock lockWhenCondition:ActivityQueueFull beforeDate:[NSDate dateWithTimeIntervalSinceNow:60.]] ) { 704 resp -> status_code = 204; 705 resp -> reason_phrase = "No Content"; 706 return; 707 } 708 709 BOOL success = NO; 710 711 @synchronized( activityQueue ) { 712 if( [[activityQueue rootElement] childCount] ) { 713 NSData *xml = [activityQueue XMLData]; 714 669 715 resp -> content_type = "text/xml"; 670 resp -> write( resp, (char *)[xml bytes], [xml length] ); 671 [[doc rootElement] setChildren:nil]; // clear the queue 672 } 716 success = ( (unsigned) resp -> write( resp, (char *)[xml bytes], [xml length] ) == [xml length] ); 717 718 if( success && socketStatus( resp -> sock, 0, 1) ) 719 success = NO; 720 721 if( success ) [[activityQueue rootElement] setChildren:nil]; // clear the queue 722 } else { 723 resp -> status_code = 204; 724 resp -> reason_phrase = "No Content"; 725 } 726 } 727 728 if( wait ) { 729 [activityLock unlockWithCondition:( success ? ActivityQueueEmpty : ActivityQueueFull )]; 730 } else { 731 if( success && [activityLock tryLockWhenCondition:ActivityQueueFull] ) 732 [activityLock unlockWithCondition:ActivityQueueEmpty]; 673 733 } 674 734 } … … 684 744 685 745 while( ( info = [enumerator nextObject] ) ) { 686 NSXMLDocument *doc = [info objectForKey:@"activityQueue"]; 687 if( ! doc ) continue; 688 689 NSXMLElement *copy = [element copyWithZone:[self zone]]; 690 [[doc rootElement] addChild:copy]; 691 [copy release]; 746 NSXMLDocument *activityQueue = [info objectForKey:@"activityQueue"]; 747 NSConditionLock *activityLock = [info objectForKey:@"activityLock"]; 748 if( ! activityQueue || ! activityLock ) continue; 749 750 @synchronized( activityQueue ) { 751 NSXMLElement *copy = [element copyWithZone:[self zone]]; 752 [[activityQueue rootElement] addChild:copy]; 753 [copy release]; 754 } 755 756 if( [activityLock tryLockWhenCondition:ActivityQueueEmpty] ) 757 [activityLock unlockWithCondition:ActivityQueueFull]; 692 758 } 693 759 } … … 755 821 [body release]; 756 822 757 NSXMLDocument *doc = [info objectForKey:@"activityQueue"]; 758 [[doc rootElement] addChild:element]; 823 NSXMLDocument *activityQueue = [info objectForKey:@"activityQueue"]; 824 NSConditionLock *activityLock = [info objectForKey:@"activityLock"]; 825 if( ! activityQueue || ! activityLock ) continue; 826 827 NSLog(@"append %d", [activityLock condition]); 828 829 @synchronized( activityQueue ) { 830 [[activityQueue rootElement] addChild:element]; 831 } 832 833 if( [activityLock tryLockWhenCondition:ActivityQueueEmpty] ) 834 [activityLock unlockWithCondition:ActivityQueueFull]; 759 835 } 760 836 … … 802 878 [body release]; 803 879 804 NSXMLDocument *doc = [info objectForKey:@"activityQueue"]; 805 [[doc rootElement] addChild:element]; 880 NSXMLDocument *activityQueue = [info objectForKey:@"activityQueue"]; 881 NSConditionLock *activityLock = [info objectForKey:@"activityLock"]; 882 if( ! activityQueue || ! activityLock ) continue; 883 884 @synchronized( activityQueue ) { 885 [[activityQueue rootElement] addChild:element]; 886 } 887 888 if( [activityLock tryLockWhenCondition:ActivityQueueEmpty] ) 889 [activityLock unlockWithCondition:ActivityQueueFull]; 806 890 } 807 891 trunk/Plug-Ins/Web Interface/Resources/iphone/iphone.js
r3701 r3703 59 59 ChatController.checkActivity(); 60 60 61 if(activityCheckInterval) clearInterval(activityCheckInterval); 62 activityCheckInterval = setInterval(ChatController.checkActivity, currentActivityCheckInterval); 61 if( ! UserDefaults.longPollActivityChecking ) { 62 if(activityCheckInterval) clearInterval(activityCheckInterval); 63 activityCheckInterval = setInterval(ChatController.checkActivity, currentActivityCheckInterval); 64 } 63 65 }; 64 66 … … 254 256 maximumActivityCheckInterval: 10000, 255 257 activityCheckIntervalIncrement: 200, 256 scrollBackMessageLimit: 200 258 scrollBackMessageLimit: 200, 259 longPollActivityChecking: true 257 260 }; 258 261 … … 292 295 293 296 if(request.status < 200 || request.status >= 300) { 294 if(activityCheckInterval) clearInterval(activityCheckInterval); 295 activityCheckInterval = setInterval(ChatController.checkActivity, UserDefaults.minimumActivityCheckInterval); 297 if( UserDefaults.longPollActivityChecking ) { 298 setTimeout(ChatController.checkActivity, 1000); // check in a bit, not right away 299 } else { 300 if(activityCheckInterval) clearInterval(activityCheckInterval); 301 activityCheckInterval = setInterval(ChatController.checkActivity, UserDefaults.minimumActivityCheckInterval); 302 } 296 303 return; 297 304 } 305 306 if( UserDefaults.longPollActivityChecking ) 307 setTimeout(ChatController.checkActivity, 0); // check again right away 298 308 299 309 var updateIntervalDelta = 0; … … 336 346 } 337 347 338 if(! updateIntervalDelta) updateIntervalDelta = UserDefaults.activityCheckIntervalIncrement; 339 340 var newActivityCheckInterval = Math.min((currentActivityCheckInterval + updateIntervalDelta), UserDefaults.maximumActivityCheckInterval); 341 newActivityCheckInterval = Math.max(newActivityCheckInterval, UserDefaults.minimumActivityCheckInterval); 342 343 if(newActivityCheckInterval != currentActivityCheckInterval) { 344 currentActivityCheckInterval = newActivityCheckInterval; 345 346 if(activityCheckInterval) clearInterval(activityCheckInterval); 347 activityCheckInterval = setInterval(ChatController.checkActivity, currentActivityCheckInterval); 348 if( ! UserDefaults.longPollActivityChecking ) { 349 if(! updateIntervalDelta) updateIntervalDelta = UserDefaults.activityCheckIntervalIncrement; 350 351 var newActivityCheckInterval = Math.min((currentActivityCheckInterval + updateIntervalDelta), UserDefaults.maximumActivityCheckInterval); 352 newActivityCheckInterval = Math.max(newActivityCheckInterval, UserDefaults.minimumActivityCheckInterval); 353 354 if(newActivityCheckInterval != currentActivityCheckInterval) { 355 currentActivityCheckInterval = newActivityCheckInterval; 356 357 if(activityCheckInterval) clearInterval(activityCheckInterval); 358 activityCheckInterval = setInterval(ChatController.checkActivity, currentActivityCheckInterval); 359 } 348 360 } 349 361 }; 350 362 351 request.open("get", "/command/checkActivity?order=" + Colloquy.nextOrderIdentifier++ + "&uinque=" + Math.round(Math.random() * 1000000), true);363 request.open("get", "/command/checkActivity?order=" + Colloquy.nextOrderIdentifier++ + "&uinque=" + (Math.round(Math.random() * 1000000) + ( UserDefaults.longPollActivityChecking ? "&wait" : "" ) ), true); 352 364 request.send(); 353 365 }; … … 550 562 } 551 563 552 if(activityCheckInterval) clearInterval(activityCheckInterval); 553 activityCheckInterval = setInterval(ChatController.checkActivity, 250); 564 if( ! UserDefaults.longPollActivityChecking ) { 565 if(activityCheckInterval) clearInterval(activityCheckInterval); 566 activityCheckInterval = setInterval(ChatController.checkActivity, 250); 567 } 554 568 }; 555 569
