Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

HistoryView: don't load in commit information in a separate thread an…

…ymore

I've seen this hang or crash a few times, so I hope this works better.
Instead of running a task in a separate thread, we just let it go through
the run loop and catch it when the task is done.

This ruins the second subview in the history view, but I don't think
anybody ever used that, so I'm going to remove it.
  • Loading branch information...
commit 0363eea494602e3002f45f1790eaff3435151949 1 parent 2cdf2b6
@pieter authored
View
14 PBGitCommit.m
@@ -66,20 +66,10 @@ - (NSString *)realSha
return str;
}
-// NOTE: This method should remain threadsafe, as we load it in async
-// from the web view.
+// FIXME: Remove this method once it's unused.
- (NSString*) details
{
- if (details != nil)
- return details;
-
- NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", [self realSha], nil];
- if (![PBGitDefaults showWhitespaceDifferences])
- [arguments insertObject:@"-w" atIndex:1];
-
- details = [self.repository outputForArguments:arguments];
-
- return details;
+ return @"";
}
- (NSString *) patch
View
32 PBWebHistoryController.m
@@ -7,6 +7,7 @@
//
#import "PBWebHistoryController.h"
+#import "PBGitDefaults.h"
@implementation PBWebHistoryController
@@ -49,6 +50,37 @@ - (void) changeContentTo: (PBGitCommit *) content
NSArray *arguments = [NSArray arrayWithObjects:content, [[[historyController repository] headRef] simpleRef], nil];
[[self script] callWebScriptMethod:@"loadCommit" withArguments: arguments];
+
+ // Now we load the extended details. We used to do this in a separate thread,
+ // but this caused some funny behaviour because NSTask's and NSThread's don't really
+ // like each other. Instead, just do it async.
+
+ NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", currentSha, nil];
+ if (![PBGitDefaults showWhitespaceDifferences])
+ [taskArguments insertObject:@"-w" atIndex:1];
+
+ NSFileHandle *handle = [repository handleForArguments:taskArguments];
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ // Remove notification, in case we have another one running
+ [nc removeObserver:self];
+ [nc addObserver:self selector:@selector(commitDetailsLoaded:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle];
+ [handle readToEndOfFileInBackgroundAndNotify];
+}
+
+- (void)commitDetailsLoaded:(NSNotification *)notification
+{
+ NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
+ if (!data)
+ return;
+
+ NSString *details = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ if (!details)
+ details = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
+
+ if (!details)
+ return;
+
+ [[view windowScriptObject] callWebScriptMethod:@"loadCommitDetails" withArguments:[NSArray arrayWithObject:details]];
}
- (void) selectCommit: (NSString*) sha
View
22 html/views/history/history.js
@@ -1,4 +1,7 @@
var commit;
+
+// Create a new Commit object
+// obj: PBGitCommit object
var Commit = function(obj) {
this.object = obj;
@@ -11,8 +14,9 @@ var Commit = function(obj) {
// TODO:
// this.author_date instant
- // This all needs to be async
- this.loadedRaw = function(details) {
+ // This can be called later with the output of
+ // 'git show' to fill in missing commit details (such as a diff)
+ this.parseDetails = function(details) {
this.raw = details;
var diffStart = this.raw.indexOf("\ndiff ");
@@ -138,6 +142,7 @@ var selectCommit = function(a) {
Controller.selectCommit_(a);
}
+// Relead only refs
var reload = function() {
$("notification").style.display = "none";
commit.reloadRefs();
@@ -159,10 +164,11 @@ var showRefs = function() {
var loadCommit = function(commitObject, currentRef) {
// These are only the things we can do instantly.
- // Other information will be loaded later by loadExtendedCommit
+ // Other information will be loaded later by loadCommitDetails,
+ // Which will be called from the controller once
+ // the commit details are in.
+
commit = new Commit(commitObject);
- Controller.callSelector_onObject_callBack_("details", commitObject,
- function(data) { commit.loadedRaw(data); loadExtendedCommit(commit); });
commit.currentRef = currentRef;
notify("Loading commit…", 0);
@@ -199,6 +205,8 @@ var loadCommit = function(commitObject, currentRef) {
}
var showDiff = function() {
+
+ // Callback for the diff highlighter. Used to generate a filelist
var newfile = function(name1, name2, id, mode_change, old_mode, new_mode) {
var button = document.createElement("div");
var p = document.createElement("p");
@@ -270,8 +278,10 @@ var enableFeatures = function()
enableFeature("gravatar", $("gravatar"))
}
-var loadExtendedCommit = function(commit)
+var loadCommitDetails = function(data)
{
+ commit.parseDetails(data);
+
var formatEmail = function(name, email) {
return email ? name + " &lt;<a href='mailto:" + email + "'>" + email + "</a>&gt;" : name;
}
Please sign in to comment.
Something went wrong with that request. Please try again.