1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
// ****************************************************************************
// Copyright (C) 2000-2001 Microsoft Corporation. All rights reserved.
//
// CONTENTS
// Workflow Base exception class
//
// DESCRIPTION
// Base class for WINOE Runtime engine exception
//
// REVISIONS
// Date Ver By Remarks
// ~~~~~~~~~~ ~~~ ~~~~~~~~ ~~~~~~~~~~~~~~
// 03/08/01 1.0 Microsoft Created.
// ****************************************************************************
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Workflow;
using System.Workflow.Runtime;
using System.Workflow.ComponentModel;
namespace System.Workflow.Runtime
{
/*
* The Unload() method has been changed so that
* any Unload requests made while in the middle of an atomic
* transaction wait for the atomic transaction to complete.
* This makes use of an ManualResetEvent. Unload() waits on the event:
* theEvent.WaitOne()
* But waiting with the executor and scheduler locks held
* will block everything else.
*
* The solution is to have a custom internal exception class that has the
* ManualResetEvent as an internal property. If Unload() finds itself in the middle
* of an atomic transaction, it throws the Exception. The Exception is propogated upwards
* until we reach the method that was the first to grab the executor lock.
*
* We then drop that lock and wait on the event handle. As soon as the handle is
* Set() by DisposeTransaction(), we grab the executor lock and do everything all over.
*/
internal class ExecutorLocksHeldException : Exception
{
private ManualResetEvent handle;
public ExecutorLocksHeldException(ManualResetEvent handle)
{
this.handle = handle;
}
internal ManualResetEvent Handle
{
get
{
return handle;
}
}
}
}
|