Skip to content

Commit 0363eea

Browse files
committed
HistoryView: don't load in commit information in a separate thread anymore
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.
1 parent 2cdf2b6 commit 0363eea

File tree

3 files changed

+50
-18
lines changed

3 files changed

+50
-18
lines changed

PBGitCommit.m

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,10 @@ - (NSString *)realSha
6666
return str;
6767
}
6868

69-
// NOTE: This method should remain threadsafe, as we load it in async
70-
// from the web view.
69+
// FIXME: Remove this method once it's unused.
7170
- (NSString*) details
7271
{
73-
if (details != nil)
74-
return details;
75-
76-
NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", [self realSha], nil];
77-
if (![PBGitDefaults showWhitespaceDifferences])
78-
[arguments insertObject:@"-w" atIndex:1];
79-
80-
details = [self.repository outputForArguments:arguments];
81-
82-
return details;
72+
return @"";
8373
}
8474

8575
- (NSString *) patch

PBWebHistoryController.m

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "PBWebHistoryController.h"
10+
#import "PBGitDefaults.h"
1011

1112
@implementation PBWebHistoryController
1213

@@ -49,6 +50,37 @@ - (void) changeContentTo: (PBGitCommit *) content
4950

5051
NSArray *arguments = [NSArray arrayWithObjects:content, [[[historyController repository] headRef] simpleRef], nil];
5152
[[self script] callWebScriptMethod:@"loadCommit" withArguments: arguments];
53+
54+
// Now we load the extended details. We used to do this in a separate thread,
55+
// but this caused some funny behaviour because NSTask's and NSThread's don't really
56+
// like each other. Instead, just do it async.
57+
58+
NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", currentSha, nil];
59+
if (![PBGitDefaults showWhitespaceDifferences])
60+
[taskArguments insertObject:@"-w" atIndex:1];
61+
62+
NSFileHandle *handle = [repository handleForArguments:taskArguments];
63+
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
64+
// Remove notification, in case we have another one running
65+
[nc removeObserver:self];
66+
[nc addObserver:self selector:@selector(commitDetailsLoaded:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle];
67+
[handle readToEndOfFileInBackgroundAndNotify];
68+
}
69+
70+
- (void)commitDetailsLoaded:(NSNotification *)notification
71+
{
72+
NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
73+
if (!data)
74+
return;
75+
76+
NSString *details = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
77+
if (!details)
78+
details = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
79+
80+
if (!details)
81+
return;
82+
83+
[[view windowScriptObject] callWebScriptMethod:@"loadCommitDetails" withArguments:[NSArray arrayWithObject:details]];
5284
}
5385

5486
- (void) selectCommit: (NSString*) sha

html/views/history/history.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
var commit;
2+
3+
// Create a new Commit object
4+
// obj: PBGitCommit object
25
var Commit = function(obj) {
36
this.object = obj;
47

@@ -11,8 +14,9 @@ var Commit = function(obj) {
1114
// TODO:
1215
// this.author_date instant
1316

14-
// This all needs to be async
15-
this.loadedRaw = function(details) {
17+
// This can be called later with the output of
18+
// 'git show' to fill in missing commit details (such as a diff)
19+
this.parseDetails = function(details) {
1620
this.raw = details;
1721

1822
var diffStart = this.raw.indexOf("\ndiff ");
@@ -138,6 +142,7 @@ var selectCommit = function(a) {
138142
Controller.selectCommit_(a);
139143
}
140144

145+
// Relead only refs
141146
var reload = function() {
142147
$("notification").style.display = "none";
143148
commit.reloadRefs();
@@ -159,10 +164,11 @@ var showRefs = function() {
159164

160165
var loadCommit = function(commitObject, currentRef) {
161166
// These are only the things we can do instantly.
162-
// Other information will be loaded later by loadExtendedCommit
167+
// Other information will be loaded later by loadCommitDetails,
168+
// Which will be called from the controller once
169+
// the commit details are in.
170+
163171
commit = new Commit(commitObject);
164-
Controller.callSelector_onObject_callBack_("details", commitObject,
165-
function(data) { commit.loadedRaw(data); loadExtendedCommit(commit); });
166172
commit.currentRef = currentRef;
167173

168174
notify("Loading commit…", 0);
@@ -199,6 +205,8 @@ var loadCommit = function(commitObject, currentRef) {
199205
}
200206

201207
var showDiff = function() {
208+
209+
// Callback for the diff highlighter. Used to generate a filelist
202210
var newfile = function(name1, name2, id, mode_change, old_mode, new_mode) {
203211
var button = document.createElement("div");
204212
var p = document.createElement("p");
@@ -270,8 +278,10 @@ var enableFeatures = function()
270278
enableFeature("gravatar", $("gravatar"))
271279
}
272280

273-
var loadExtendedCommit = function(commit)
281+
var loadCommitDetails = function(data)
274282
{
283+
commit.parseDetails(data);
284+
275285
var formatEmail = function(name, email) {
276286
return email ? name + " &lt;<a href='mailto:" + email + "'>" + email + "</a>&gt;" : name;
277287
}

0 commit comments

Comments
 (0)