Fix downloads being cut off early

This commit is contained in:
anthony 2022-02-01 09:54:28 +00:00
parent d035db7f0c
commit 315af41624
3 changed files with 49 additions and 11 deletions

View File

@ -14,6 +14,8 @@ struct download_context;
BOOL completed; BOOL completed;
BOOL cancelled; BOOL cancelled;
NSUInteger size; NSUInteger size;
NSUInteger confirmedSize, sizeUntilNow;
NSLock *confirmedSizeLock;
NSUInteger written; NSUInteger written;
NSInteger index; NSInteger index;
NSDate *startDate; NSDate *startDate;

View File

@ -3,6 +3,11 @@
#import "desktop/download.h" #import "desktop/download.h"
#import "Preferences.h" #import "Preferences.h"
@interface DownloadItem(Private)
-(void) completeAndNotifyManager;
-(void) notifyManager;
@end
@implementation DownloadItem @implementation DownloadItem
-(id)initWithManager: (DownloadManager*)aManager destination: (NSURL*)aDestination size: (NSInteger)aSize index: (NSUInteger)anIndex ctx: (struct download_context*)aCtx { -(id)initWithManager: (DownloadManager*)aManager destination: (NSURL*)aDestination size: (NSInteger)aSize index: (NSUInteger)anIndex ctx: (struct download_context*)aCtx {
@ -10,6 +15,8 @@
error = nil; error = nil;
index = anIndex; index = anIndex;
written = 0; written = 0;
confirmedSize = 0;
confirmedSizeLock = [[NSLock alloc] init];
completed = NO; completed = NO;
size = aSize; size = aSize;
startDate = [[NSDate date] retain]; startDate = [[NSDate date] retain];
@ -29,12 +36,15 @@
return self; return self;
} }
// TODO: - Why isn't this releasing?
-(void)dealloc { -(void)dealloc {
NSLog(@"DownloadItem dealloc!!");
runThread = NO; runThread = NO;
[destination release]; [destination release];
[outputStream close]; [outputStream close];
[outputStream release]; [outputStream release];
[startDate release]; [startDate release];
[confirmedSizeLock release];
if (error) { if (error) {
[error release]; [error release];
} }
@ -56,11 +66,11 @@
} }
-(BOOL)appendToDownload: (NSData*)data { -(BOOL)appendToDownload: (NSData*)data {
sizeUntilNow += [data length];
if (downloadThread == nil) { if (downloadThread == nil) {
NSLog(@"Error: expected download thread to be initialized"); NSLog(@"Error: expected download thread to be initialized");
return NO; return NO;
} }
[data retain];
[self performSelector: @selector(reallyWriteData:) onThread: downloadThread [self performSelector: @selector(reallyWriteData:) onThread: downloadThread
withObject: data waitUntilDone: NO modes: [NSArray arrayWithObject: withObject: data waitUntilDone: NO modes: [NSArray arrayWithObject:
NSDefaultRunLoopMode]]; NSDefaultRunLoopMode]];
@ -68,9 +78,15 @@
} }
-(void)reallyWriteData: (NSData*)data { -(void)reallyWriteData: (NSData*)data {
NSUInteger len = [data length]; NSUInteger toWrite = [data length];
NSUInteger writtenNow = [outputStream write: [data bytes] maxLength: len]; NSInteger thisWrite;
written += writtenNow; const uint8_t *start = [data bytes];
while (toWrite > 0) {
thisWrite = [outputStream write: start maxLength: toWrite];
start += thisWrite;
toWrite -= thisWrite;
}
written += [data length];
// Unless im misunderstanding download_context_get_total_length appears to return // Unless im misunderstanding download_context_get_total_length appears to return
// a too-small non-zero value for download size when called so... // a too-small non-zero value for download size when called so...
size = MAX(written, size); size = MAX(written, size);
@ -81,6 +97,25 @@
waitUntilDone: NO]; waitUntilDone: NO];
} }
lastWrite = time; lastWrite = time;
// Check if we're complete.
BOOL done;
[confirmedSizeLock lock];
done = confirmedSize > 0 && written >= confirmedSize;
[confirmedSizeLock unlock];
if (done) {
[self performSelectorOnMainThread: @selector(completeAndNotifyManager)
withObject: nil waitUntilDone: NO];
}
}
-(void)completeAndNotifyManager {
completed = YES;
runThread = NO;
[outputStream close];
[[manager delegate] downloadManager: manager didUpdateItem: self];
if ([[Preferences defaultPreferences] removeDownloadsOnComplete]) {
[manager removeDownloadsAtIndexes: [NSIndexSet indexSetWithIndex: index]];
}
} }
-(void)notifyManager { -(void)notifyManager {
[[manager delegate] downloadManager: manager didUpdateItem: self]; [[manager delegate] downloadManager: manager didUpdateItem: self];
@ -104,12 +139,14 @@
} }
-(void)complete { -(void)complete {
[outputStream close]; NSLog(@"Complete called...");
completed = YES; // Having set this non-0, our download thread will know to complete.
[[manager delegate] downloadManager: manager didUpdateItem: self]; [confirmedSizeLock lock];
if ([[Preferences defaultPreferences] removeDownloadsOnComplete]) { confirmedSize = sizeUntilNow;
[manager removeDownloadsAtIndexes: [NSIndexSet indexSetWithIndex: index]]; [confirmedSizeLock unlock];
} // Trigger a write just to trigger the completion check if there's no data
// pending write.
[self appendToDownload: [NSData data]];
} }
-(BOOL)isComplete { -(BOOL)isComplete {

View File

@ -110,7 +110,6 @@ static struct gui_download_window *gnustep_download_create(struct download_conte
// ?? // ??
static nserror gnustep_download_data(struct gui_download_window *dw, const char *data, unsigned int size) { static nserror gnustep_download_data(struct gui_download_window *dw, const char *data, unsigned int size) {
NSLog(@"gnustep_download_data");
BOOL success = [(id)dw appendToDownload: [NSData dataWithBytesNoCopy: (void*)data BOOL success = [(id)dw appendToDownload: [NSData dataWithBytesNoCopy: (void*)data
length: size freeWhenDone: NO]]; length: size freeWhenDone: NO]];
if (success) { if (success) {