Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ public static partial class TransactionInterop
}
public static partial class TransactionManager
{
public static System.TimeSpan DefaultTimeout { get { throw null; } }
public static System.TimeSpan DefaultTimeout { get { throw null; } set { } }
[System.Diagnostics.CodeAnalysis.DisallowNullAttribute]
public static System.Transactions.HostCurrentTransactionCallback? HostCurrentCallback { get { throw null; } set { } }
public static System.TimeSpan MaximumTimeout { get { throw null; } }
public static System.TimeSpan MaximumTimeout { get { throw null; } set { } }
public static event System.Transactions.TransactionStartedEventHandler? DistributedTransactionStarted { add { } remove { } }
public static void RecoveryComplete(System.Guid resourceManagerIdentifier) { }
public static System.Transactions.Enlistment Reenlist(System.Guid resourceManagerIdentifier, byte[] recoveryInformation, System.Transactions.IEnlistmentNotification enlistmentNotification) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ internal static IsolationLevel DefaultIsolationLevel
private static MachineSettingsSection MachineSettings => s_machineSettings ??= MachineSettingsSection.GetSection();

private static bool s_defaultTimeoutValidated;
private static TimeSpan s_defaultTimeout;
private static long s_defaultTimeoutTicks;
public static TimeSpan DefaultTimeout
{
get
Expand All @@ -292,23 +292,45 @@ public static TimeSpan DefaultTimeout

if (!s_defaultTimeoutValidated)
{
s_defaultTimeout = ValidateTimeout(DefaultSettingsSection.Timeout);
// If the timeout value got adjusted, it must have been greater than MaximumTimeout.
if (s_defaultTimeout != DefaultSettingsSection.Timeout)
LazyInitializer.EnsureInitialized(ref s_defaultTimeoutTicks, ref s_defaultTimeoutValidated, ref s_classSyncObject, () => ValidateTimeout(DefaultSettingsSection.Timeout).Ticks);
if (Interlocked.Read(ref s_defaultTimeoutTicks) != DefaultSettingsSection.Timeout.Ticks)
{
if (etwLog.IsEnabled())
{
etwLog.ConfiguredDefaultTimeoutAdjusted();
}
}
s_defaultTimeoutValidated = true;
}

if (etwLog.IsEnabled())
{
etwLog.MethodExit(TraceSourceType.TraceSourceBase, "TransactionManager.get_DefaultTimeout");
}
return s_defaultTimeout;
return new TimeSpan(Interlocked.Read(ref s_defaultTimeoutTicks));
}
set
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
{
etwLog.MethodEnter(TraceSourceType.TraceSourceBase, "TransactionManager.set_DefaultTimeout");
}

Interlocked.Exchange(ref s_defaultTimeoutTicks, ValidateTimeout(value).Ticks);
if (Interlocked.Read(ref s_defaultTimeoutTicks) != value.Ticks)
{
if (etwLog.IsEnabled())
{
etwLog.ConfiguredDefaultTimeoutAdjusted();
}
}

s_defaultTimeoutValidated = true;

if (etwLog.IsEnabled())
{
etwLog.MethodExit(TraceSourceType.TraceSourceBase, "TransactionManager.set_DefaultTimeout");
}
}
}

Expand All @@ -325,7 +347,7 @@ public static TimeSpan MaximumTimeout
etwLog.MethodEnter(TraceSourceType.TraceSourceBase, "TransactionManager.get_DefaultMaximumTimeout");
}

LazyInitializer.EnsureInitialized(ref s_maximumTimeout, ref s_cachedMaxTimeout, ref s_classSyncObject, () => DefaultSettingsSection.Timeout);
LazyInitializer.EnsureInitialized(ref s_maximumTimeout, ref s_cachedMaxTimeout, ref s_classSyncObject, () => MachineSettingsSection.MaxTimeout);

if (etwLog.IsEnabled())
{
Expand All @@ -334,6 +356,39 @@ public static TimeSpan MaximumTimeout

return s_maximumTimeout;
}
set
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
{
etwLog.MethodEnter(TraceSourceType.TraceSourceBase, "TransactionManager.set_DefaultMaximumTimeout");
}

if (value < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(value));
}

s_cachedMaxTimeout = true;
s_maximumTimeout = value;
LazyInitializer.EnsureInitialized(ref s_defaultTimeoutTicks, ref s_defaultTimeoutValidated, ref s_classSyncObject, () => DefaultSettingsSection.Timeout.Ticks);

long defaultTimeoutTicks = 0;
defaultTimeoutTicks = Interlocked.Read(ref s_defaultTimeoutTicks);
Interlocked.Exchange(ref s_defaultTimeoutTicks, ValidateTimeout(new TimeSpan(Interlocked.Read(ref s_defaultTimeoutTicks))).Ticks);
if (Interlocked.Read(ref s_defaultTimeoutTicks) != defaultTimeoutTicks)
{
if (etwLog.IsEnabled())
{
etwLog.ConfiguredDefaultTimeoutAdjusted();
}
}

if (etwLog.IsEnabled())
{
etwLog.MethodExit(TraceSourceType.TraceSourceBase, "TransactionManager.set_DefaultMaximumTimeout");
}
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<Compile Include="NonMsdtcPromoterTests.cs" />
<Compile Include="AsyncTransactionScopeTests.cs" />
<Compile Include="IntResourceManager.cs" />
<Compile Include="TransactionManagerTest.cs" />
<Compile Include="TransactionScopeTest.cs" />
<Compile Include="AsyncTest.cs" />
<Compile Include="EnlistTest.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit;

namespace System.Transactions.Tests
{
public class TransactionManagerTest
{
[Fact]
public void DefaultTimeout_MaxTimeout_Set_Get()
{
TimeSpan tsDefault = TimeSpan.Parse("00:02:00");
TransactionManager.DefaultTimeout = tsDefault;
Assert.Equal(tsDefault, TransactionManager.DefaultTimeout);

TimeSpan tsMax = TimeSpan.Parse("00:30:00");
TransactionManager.MaximumTimeout = tsMax;
Assert.Equal(tsMax, TransactionManager.MaximumTimeout);

TimeSpan ts = TransactionManager.MaximumTimeout.Add(TimeSpan.FromMinutes(10));
TransactionManager.DefaultTimeout = ts;
Assert.Equal(tsMax, TransactionManager.MaximumTimeout);
Assert.Equal(TransactionManager.DefaultTimeout, TransactionManager.MaximumTimeout);

ts = TimeSpan.Parse("-00:01:00");
Assert.Throws<ArgumentOutOfRangeException>(() => TransactionManager.DefaultTimeout = ts);
Assert.Throws<ArgumentOutOfRangeException>(() => TransactionManager.MaximumTimeout = ts);
}
}
}