Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Conversation

@shiena
Copy link
Contributor

@shiena shiena commented Jul 13, 2017

fixes #124
fixes #35

Depends on:

I replaced the reading of standard output from asynchronous to synchronous to eliminate garbled characters.

image

Synchronous reading of both standard output and standard error may cause deadlock. So I replaced standard output only.
Reference: https://stackoverflow.com/questions/7160187/standardoutput-readtoend-hangs

Also, I'm worried about whether performance will be bad.

@shiena
Copy link
Contributor Author

shiena commented Jul 18, 2017

@StanleyGoldman
The appveyor build failed with an error occurred in nuget restore GitHub.Unity.sln.
Can you build it again?

@shiena
Copy link
Contributor Author

shiena commented Jul 22, 2017

@StanleyGoldman
A pull request has been completed. I will summarize the changes.

  • Using Process::StandardOutput::BaseStream::BeginRead instead of Process::BeginOutputReadLine
  • Also change StandardError
  • However, since .NET 4.6 has no problem in character encoding, use the original code
  • Add options to git command according to Git for Windows Unicode support

@StanleyGoldman
Copy link
Contributor

Hey @shiena sorry I've been MIA, @shana and I have been on vacation.
We will take a look at this soon.

@StanleyGoldman
Copy link
Contributor

Hey @shiena, sorry it's taken so long to get to this.

Processes are executed in a separate thread, so because of the bug in Unity we can definitely go with synchronous calls here. Also until Unity removes support for their .net 3.5 profile we will not compile this library in .net 4.6.

So when you get the chance remove all the #if/#endif and keep the .net 3.5 side. I think there are a few more changes to make so after that I will review again.

@StanleyGoldman StanleyGoldman self-requested a review August 2, 2017 16:40
Copy link
Contributor

@StanleyGoldman StanleyGoldman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove all the #if/#endif with NET_4_6

@shiena
Copy link
Contributor Author

shiena commented Aug 2, 2017

@StanleyGoldman Thank you for review.
I kept the .net 3.5 side according to the compilation policy.

@StanleyGoldman
Copy link
Contributor

💨... Thanks for the quick changes ...
I'm testing your changes against the https://github.com/unity3d-jp/piranhan repo now.

{
var encoded = outputEncoding.GetString(outputBuffer, 0, bytesRead);
outputContents.Append(encoded);
Process.StandardOutput.BaseStream.BeginRead(outputBuffer, 0, outputBuffer.Length, outputCallback, Process.StandardOutput);
Copy link
Contributor

@StanleyGoldman StanleyGoldman Aug 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this line of code should not be here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems I am mistaken

{
var encoded = errorEncoding.GetString(errorBuffer, 0, bytesRead);
errorContents.Append(encoded);
Process.StandardError.BaseStream.BeginRead(errorBuffer, 0, errorBuffer.Length, errorCallback, Process.StandardError);
Copy link
Contributor

@StanleyGoldman StanleyGoldman Aug 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the same goes for this line.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mistaken here too

@StanleyGoldman
Copy link
Contributor

I understand why you've done what you've done... 🤔... I'm thinking about it

Copy link
Contributor

@StanleyGoldman StanleyGoldman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand what happened now, you worked real hard to keep both async and sync methods possible. Since we are going to go sync, you can rewrite the way the output is being handled to be simpler & easier to follow.

Process.BeginOutputReadLine();
{
outputReset.Reset();
Process.StandardOutput.BaseStream.BeginRead(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a loop here to read the bytes and encode the string with the correct encoding. After that you can read the lines and call the appropriate output method. This way we won't need the complicated AsyncCallback that has a reference to itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you read the standard output using a loop there, it blocks processing.
Because RunCredentialHelper writes to the standard input of git-credential-wincred command when signing in to GitHub.

Logger.Trace("RunCredentialHelper helper:\"{0}\" action:\"{1}\"", credHelper, action);
SimpleProcessTask task;
if (credHelper.StartsWith('!'))
{
// it's a separate app, run it as such
task = new SimpleProcessTask(taskManager.Token, credHelper.Substring(1).ToNPath(), action);
}
else
{
var args = $"credential-{credHelper} {action}";
task = new SimpleProcessTask(taskManager.Token, args);
}
task.Configure(processManager, true);
task.OnStartProcess += proc =>
{
foreach (var line in lines)
{
proc.StandardInput.WriteLine(line);
}
proc.StandardInput.Close();
};
return task;

For that reason, I think that we need an asynchronous BeginRead.
Please tell me if there is a better way.

Process.BeginErrorReadLine();
{
errorReset.Reset();
Process.StandardError.BaseStream.BeginRead(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the same thing here.

if (Process.StartInfo.RedirectStandardOutput)
outputReset.WaitOne();
if (Process.StartInfo.RedirectStandardError)
errorReset.WaitOne();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That way we no longer need these ManualResetEvent objects.

@StanleyGoldman
Copy link
Contributor

@shiena there is another branch based off this, could you test it out for me.

https://github.com/github-for-unity/Unity/tree/fixes/returning-lines-sooner

@StanleyGoldman
Copy link
Contributor

LFS Verification checks are preventing me from pushing to your repo

@shiena
Copy link
Contributor Author

shiena commented Aug 11, 2017

@StanleyGoldman Japanese also displayed correctly for that branch.

@StanleyGoldman
Copy link
Contributor

Edited the pull request description to show what this PR depends on

@shiena
Copy link
Contributor Author

shiena commented Aug 11, 2017

@StanleyGoldman I think that #35 has also been fixed.

@StanleyGoldman
Copy link
Contributor

You may be right, let's see

@StanleyGoldman
Copy link
Contributor

You are correct.

StanleyGoldman
StanleyGoldman previously approved these changes Aug 11, 2017
if (token.IsCancellationRequested)
var outputStream = Process.StandardOutput.BaseStream;
var outputBuffer = new byte[bufferSize];
var outputEncoding = Process.StartInfo.StandardOutputEncoding ?? Console.Out.Encoding;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can Process.StartInfo.StandardOutputEncoding ever be null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could not be null by tracing the call hierarchy. So delete the null check.

}
var errorStream = Process.StandardError.BaseStream;
var errorBuffer = new byte[bufferSize];
var errorEncoding = Process.StartInfo.StandardErrorEncoding ?? Console.Error.Encoding;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question about Process.StartInfo.StandardErrorEncoding ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also delete null check.

@shiena
Copy link
Contributor Author

shiena commented Aug 22, 2017

@StanleyGoldman @shana
A process encoding bug has been avoided as #181 has been merged. (Process.StandardOutput.ReadLine correctly encodes)
However, if the user sets encoding options other than utf8 in git config, the history view garbled.
Therefore, I recommend setting -C logoutputencoding=utf8 etc for git command line option.

Even if you need the git command line option, this pull request is redundant, so I would like to create another pull request.

@shana
Copy link
Member

shana commented Aug 22, 2017

@shiena Yup, we were literally just discussing that 10 minutes ago and came to the same conclusion 😄 👍

@StanleyGoldman
Copy link
Contributor

Hey @shiena we were about to say the same thing to you...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

3 participants