Skip to content

Prevent the git_trace callback from being garbage collected #917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions LibGit2Sharp/Core/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2959,6 +2959,18 @@ public static GitObjectType git_tag_target_type(GitObjectSafeHandle tag)

#region git_trace_

/// <summary>
/// Install/Enable logging inside of LibGit2 to send messages back to LibGit2Sharp.
///
/// Since the given callback will be passed into and retained by C code,
/// it is very important that you pass an actual delegate here (and don't
/// let the compiler create/cast a temporary one for you). Furthermore, you
/// must hold a reference to this delegate until you turn off logging.
///
/// This callback is unlike other callbacks because logging persists in the
/// process until disabled; in contrast, most callbacks are only defined for
/// the duration of the down-call.
/// </summary>
public static void git_trace_set(LogLevel level, NativeMethods.git_trace_cb callback)
{
using (ThreadAffinity())
Expand Down
2 changes: 1 addition & 1 deletion LibGit2Sharp/GlobalSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public static LogConfiguration LogConfiguration
}
else
{
Proxy.git_trace_set(value.Level, value.GitTraceHandler);
Proxy.git_trace_set(value.Level, value.GitTraceCallback);

Log.Write(LogLevel.Info, "Logging enabled at level {0}", value.Level);
}
Expand Down
11 changes: 10 additions & 1 deletion LibGit2Sharp/LogConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public LogConfiguration(LogLevel level, LogHandler handler)

Level = level;
Handler = handler;

// Explicitly create (and hold a reference to) a callback-delegate to wrap GitTraceHandler().
GitTraceCallback = GitTraceHandler;
}

private LogConfiguration()
Expand All @@ -35,8 +38,14 @@ private LogConfiguration()

internal LogLevel Level { get; private set; }
internal LogHandler Handler { get; private set; }
internal NativeMethods.git_trace_cb GitTraceCallback { get; private set; }

internal void GitTraceHandler(LogLevel level, IntPtr msg)
/// <summary>
/// This private method will be called from LibGit2 (from C code via
/// the GitTraceCallback delegate) to route LibGit2 log messages to
/// the same LogHandler as LibGit2Sharp messages.
/// </summary>
private void GitTraceHandler(LogLevel level, IntPtr msg)
{
string message = LaxUtf8Marshaler.FromNative(msg);
Handler(level, message);
Expand Down