File: Msmq.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (140 lines) | stat: -rw-r--r-- 4,881 bytes parent folder | download
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Channels
{
    using System.Threading;
    using System.Net.Security;

    internal static class Msmq
    {
        static Version longhornVersion = new Version(4, 0);
        static Version version;
        static bool activeDirectoryEnabled;
        static object xpSendLock = null;
        static UriPrefixTable<ITransportManagerRegistration> transportManagerTable = new UriPrefixTable<ITransportManagerRegistration>();
        static object staticLock = new object();

        // Double-checked locking pattern requires volatile for read/write synchronization
        static volatile SafeLibraryHandle errorStrings = null;

        static Msmq()
        {
            MsmqQueue.GetMsmqInformation(ref version, ref activeDirectoryEnabled);
            MsmqDiagnostics.MsmqDetected(version);
            Version osVersion = System.Environment.OSVersion.Version;
            if (osVersion.Major == 5 && osVersion.Minor == 1)
                xpSendLock = new object();
        }

        internal static bool ActiveDirectoryEnabled
        {
            get { return activeDirectoryEnabled; }
        }

        internal static Version Version
        {
            get { return version; }
        }

        internal static bool IsPerAppDeadLetterQueueSupported
        {
            get { return Msmq.Version >= longhornVersion; }
        }

        internal static bool IsAdvancedPoisonHandlingSupported
        {
            get { return Msmq.Version >= longhornVersion; }
        }

        internal static bool IsRejectMessageSupported
        {
            get { return Msmq.Version >= longhornVersion; }
        }

        internal static bool IsRemoteReceiveContextSupported
        {
            get { return Msmq.Version >= longhornVersion; }
        }

        internal static UriPrefixTable<ITransportManagerRegistration> StaticTransportManagerTable
        {
            get { return transportManagerTable; }
        }

        internal static IPoisonHandlingStrategy CreatePoisonHandler(MsmqReceiveHelper receiver)
        {
            if (receiver.Transactional)
            {
                if (Msmq.Version < longhornVersion)
                {
                    return new Msmq3PoisonHandler(receiver);
                }
                else
                {
                    if (receiver.ListenUri.AbsoluteUri.Contains(";"))
                        return new Msmq4SubqueuePoisonHandler(receiver);
                    else
                        return new Msmq4PoisonHandler(receiver);
                }
            }
            else
            {
                return new MsmqNonTransactedPoisonHandler(receiver);
            }
        }

        internal static MsmqQueue CreateMsmqQueue(MsmqReceiveHelper receiver)
        {
            if (receiver.MsmqReceiveParameters.ReceiveContextSettings.Enabled)
            {
                if (Msmq.Version < longhornVersion)
                {
                    return new MsmqDefaultLockingQueue(receiver.MsmqReceiveParameters.AddressTranslator.UriToFormatName(receiver.ListenUri), UnsafeNativeMethods.MQ_RECEIVE_ACCESS);
                }
                else
                {
                    return new MsmqSubqueueLockingQueue(receiver.MsmqReceiveParameters.AddressTranslator.UriToFormatName(receiver.ListenUri), receiver.ListenUri.Host, UnsafeNativeMethods.MQ_RECEIVE_ACCESS);
                }
            }
            else
            {
                return new MsmqQueue(receiver.MsmqReceiveParameters.AddressTranslator.UriToFormatName(receiver.ListenUri), UnsafeNativeMethods.MQ_RECEIVE_ACCESS);
            }
        }

        internal static SafeLibraryHandle ErrorStrings
        {
            get
            {
                if (null == errorStrings)
                {
                    lock (staticLock)
                    {
                        if (null == errorStrings)
                        {
#pragma warning suppress 56523 // Callers (there is only one) handle an invalid handle returned from here.
                            errorStrings = UnsafeNativeMethods.LoadLibrary("MQUTIL.DLL");
                        }
                    }
                }
                return errorStrings;
            }
        }

        internal static void EnterXPSendLock(out bool lockHeld, ProtectionLevel protectionLevel)
        {
            lockHeld = false;
            if (null != xpSendLock && (ProtectionLevel.None != protectionLevel))
            {
                Monitor.Enter(xpSendLock, ref lockHeld);
            }
        }

        internal static void LeaveXPSendLock()
        {
            Monitor.Exit(xpSendLock);
        }
    }
}