File mono-19955-fix.patch of Package mono

diff -Nruw mono-6.12.0.182-orig/mcs/class/System.Transactions/System.Transactions/Transaction.cs mono-6.12.0.182/mcs/class/System.Transactions/System.Transactions/Transaction.cs
--- mono-6.12.0.182-orig/mcs/class/System.Transactions/System.Transactions/Transaction.cs	2022-06-14 22:36:01.000000000 +0200
+++ mono-6.12.0.182/mcs/class/System.Transactions/System.Transactions/Transaction.cs	2022-06-26 08:17:32.744094086 +0200
@@ -23,6 +23,8 @@
 		[ThreadStatic]
 		static Transaction ambient;
 
+		Transaction internalTransaction;
+
 		IsolationLevel level;
 		TransactionInformation info;
 
@@ -83,6 +85,8 @@
 			volatiles = other.Volatiles;
 			durables = other.Durables;
 			pspe = other.Pspe;
+			TransactionCompletedInternal = other.TransactionCompletedInternal;
+			internalTransaction = other;
 		}
 
 		[MonoTODO]
@@ -92,7 +96,26 @@
 			throw new NotImplementedException ();
 		}
 
-		public event TransactionCompletedEventHandler TransactionCompleted;
+		internal event TransactionCompletedEventHandler TransactionCompletedInternal;
+
+		public event TransactionCompletedEventHandler TransactionCompleted
+		{
+			add
+			{
+				if(this.internalTransaction != null)
+					this.internalTransaction.TransactionCompleted += value;
+
+				TransactionCompletedInternal += value;
+			}
+
+			remove
+			{
+				if(this.internalTransaction != null)
+					this.internalTransaction.TransactionCompleted -= value;
+
+				TransactionCompletedInternal -= value;
+			}
+		}
 
 		public static Transaction Current {
 			get { 
@@ -378,7 +401,7 @@
 		private void DoCommit ()
 		{
 			/* Scope becomes null in TransactionScope.Dispose */
-			if (Scope != null) {
+			if (Scope != null && (!Scope.IsComplete || !Scope.IsDisposed)) {
 				/* See test ExplicitTransaction8 */
 				Rollback (null, null);
 				CheckAborted ();
@@ -529,20 +552,21 @@
 
 		void CheckAborted ()
 		{
-			if (aborted)
+			if (aborted || (Scope != null && Scope.IsAborted))
 				throw new TransactionAbortedException ("Transaction has aborted", innerException);
 		}
 
 		void FireCompleted ()
 		{
-			if (TransactionCompleted != null)
-				TransactionCompleted (this, new TransactionEventArgs(this));
+			if (TransactionCompletedInternal != null)
+				TransactionCompletedInternal (this, new TransactionEventArgs(this));
 		}
 
 		static void EnsureIncompleteCurrentScope ()
 		{
 			if (CurrentInternal == null)
 				return;
+			
 			if (CurrentInternal.Scope != null && CurrentInternal.Scope.IsComplete)
 				throw new InvalidOperationException ("The current TransactionScope is already complete");
 		}
diff -Nruw mono-6.12.0.182-orig/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs mono-6.12.0.182/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs
--- mono-6.12.0.182-orig/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs	2022-06-14 22:36:01.000000000 +0200
+++ mono-6.12.0.182/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs	2022-06-26 09:17:38.574386820 +0200
@@ -9,7 +9,7 @@
 // (C)2006 Novell Inc,
 //
 
-
+using System.Threading;
 using DTCOption = System.Transactions.EnterpriseServicesInteropOption;
 
 namespace System.Transactions
@@ -19,6 +19,7 @@
 		static TransactionOptions defaultOptions =
 			new TransactionOptions (0, TransactionManager.DefaultTimeout);
 
+		Timer scopeTimer;		
 		Transaction transaction;
 		Transaction oldTransaction;
 		TransactionScope parentScope;
@@ -29,6 +30,7 @@
 
 		bool disposed;
 		bool completed;
+		bool aborted;
 		bool isRoot;
 
 		bool asyncFlowEnabled;
@@ -99,7 +101,7 @@
 			DTCOption interopOption)
 		{
 			Initialize (scopeOption, null, transactionOptions, interopOption,
-				TransactionManager.DefaultTimeout, TransactionScopeAsyncFlowOption.Suppress);
+				transactionOptions.Timeout, TransactionScopeAsyncFlowOption.Suppress);
 		}
 
 		public TransactionScope (Transaction transactionToUse,
@@ -143,6 +145,34 @@
 				transaction.InitScope (this);
 			if (parentScope != null)
 				parentScope.nested ++;
+
+			if(this.timeout != TimeSpan.Zero)
+				scopeTimer = new Timer(TransactionScope.TimerCallback, this, scopeTimeout, TimeSpan.Zero);
+		}
+		
+       		private static void TimerCallback(object state)
+        	{
+			TransactionScope scope = state as TransactionScope;
+			if ( null == scope )
+			{
+	                	throw new TransactionException( "TransactionScopeTimerObjectInvalid", null );
+			}
+ 
+			scope.TimeoutScope();
+	       	}
+
+		private void TimeoutScope()
+		{
+			if ( ( !this.completed ) && ( null != this.transaction ) )
+			{
+				try
+				{
+					this.transaction.Rollback();
+					this.aborted = true;
+				}
+				catch ( ObjectDisposedException ex ) { }
+				catch ( TransactionException txEx ) { }
+			}
 		}
 
 		Transaction InitTransaction (Transaction tx, TransactionScopeOption scopeOption, TransactionOptions options)
@@ -176,11 +206,21 @@
 		public void Complete ()
 		{
 			if (completed)
+			{
 				throw new InvalidOperationException ("The current TransactionScope is already complete. You should dispose the TransactionScope.");
+			}
 
 			completed = true;
 		}
 
+		internal bool IsAborted {
+			get { return aborted; }
+		}
+
+		internal bool IsDisposed {
+			get { return disposed; }
+		}
+
 		internal bool IsComplete {
 			get { return completed; }
 		}
@@ -205,6 +245,7 @@
 				throw new InvalidOperationException ("TransactionScope nested incorrectly");
 			}
 
+
 			if (Transaction.CurrentInternal != transaction && !asyncFlowEnabled) {
 				if (transaction != null)
 					transaction.Rollback ();
@@ -214,6 +255,9 @@
 				throw new InvalidOperationException ("Transaction.Current has changed inside of the TransactionScope");
 			} 
 
+			if (scopeTimer != null)
+				scopeTimer.Dispose();
+
 			if (asyncFlowEnabled) {
 				if (oldTransaction != null)
 					oldTransaction.Scope = parentScope;
@@ -226,10 +270,12 @@
 
 				variedTransaction.Scope = parentScope;
 				Transaction.CurrentInternal = oldTransaction;
-
 				transaction.Scope = null;
 
-				if (!IsComplete) {
+				if (IsAborted) {
+					throw new TransactionAbortedException("Transaction has aborted");
+	                        }
+				else if (!IsComplete) {
 					transaction.Rollback ();
 					variedTransaction.Rollback();
 					return;
@@ -251,8 +297,10 @@
 					/* scope was not in a transaction, (Suppress) */
 					return;
 
+				if (IsAborted) {
 				transaction.Scope = null;
-
+					throw new TransactionAbortedException("Transaction has aborted");
+				}
 				if (!IsComplete)
 				{
 					transaction.Rollback();
@@ -265,6 +313,7 @@
 
 				transaction.CommitInternal();
 
+				transaction.Scope = null;
 			}
 		}
 
openSUSE Build Service is sponsored by