unsafe int PeekLockCore(MsmqQueueHandle handle, MsmqInputMessage message, TimeSpan timeout)
        {
            int          retCode = 0;
            ITransaction internalTrans;

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            IntPtr nativePropertiesPointer = message.Pin();

            try
            {
                bool receivedMessage = false;

                while (!receivedMessage)
                {
                    retCode = UnsafeNativeMethods.MQBeginTransaction(out internalTrans);
                    if (retCode != 0)
                    {
                        return(retCode);
                    }

                    int timeoutInMilliseconds = TimeoutHelper.ToMilliseconds(timeoutHelper.RemainingTime());

                    // no timeout interval if timeout has been set to 0 otherwise a minimum of 100
                    int timeoutIntervalInMilliseconds = (timeoutInMilliseconds == 0) ? 0 : 100;

                    // receive until timeout but let go of receive lock for other contenders periodically
                    while (true)
                    {
                        lock (this.receiveLock)
                        {
                            retCode = UnsafeNativeMethods.MQReceiveMessage(handle.DangerousGetHandle(), timeoutIntervalInMilliseconds,
                                                                           UnsafeNativeMethods.MQ_ACTION_RECEIVE, nativePropertiesPointer, null, IntPtr.Zero, IntPtr.Zero, internalTrans);
                            if (retCode == UnsafeNativeMethods.MQ_ERROR_IO_TIMEOUT)
                            {
                                // keep trying until we timeout
                                timeoutInMilliseconds = TimeoutHelper.ToMilliseconds(timeoutHelper.RemainingTime());
                                if (timeoutInMilliseconds == 0)
                                {
                                    return(retCode);
                                }
                            }
                            else if (retCode != 0)
                            {
                                BOID boid = new BOID();
                                internalTrans.Abort(
                                    ref boid, // pboidReason
                                    0,        // fRetaining
                                    0         // fAsync
                                    );

                                return(retCode);
                                // we don't need to release the ITransaction as MSMQ does not increment the ref counter
                                // in MQBeginTransaction
                            }
                            else
                            {
                                // we got a message within the specified time out
                                break;
                            }
                        }
                    }

                    TransactionLookupEntry entry;

                    lock (this.internalStateLock)
                    {
                        if (!this.lockMap.TryGetValue(message.LookupId.Value, out entry))
                        {
                            this.lockMap.Add(message.LookupId.Value, new TransactionLookupEntry(message.LookupId.Value, internalTrans));
                            receivedMessage = true;
                        }
                        else
                        {
                            // this was a message that was in the process of being handed off
                            // from some app trans to some internal MSMQ transaction
                            // and we grabbed it before the Abort() could finish
                            // need to be a good citizen and finish that Abort() job for it
                            entry.MsmqInternalTransaction = internalTrans;
                        }
                    }
                }
            }
            finally
            {
                message.Unpin();
            }

            return(retCode);
        }
        unsafe int PeekLockCore(MsmqQueueHandle handle, MsmqInputMessage message, TimeSpan timeout)
        {
            int retCode = 0;
            ITransaction internalTrans;

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            IntPtr nativePropertiesPointer = message.Pin();
            try
            {
                bool receivedMessage = false;

                while (!receivedMessage)
                {
                    retCode = UnsafeNativeMethods.MQBeginTransaction(out internalTrans);
                    if (retCode != 0)
                    {
                        return retCode;
                    }

                    int timeoutInMilliseconds = TimeoutHelper.ToMilliseconds(timeoutHelper.RemainingTime());

                    // no timeout interval if timeout has been set to 0 otherwise a minimum of 100
                    int timeoutIntervalInMilliseconds = (timeoutInMilliseconds == 0) ? 0 : 100;

                    // receive until timeout but let go of receive lock for other contenders periodically
                    while (true)
                    {
                        lock (this.receiveLock)
                        {
                            retCode = UnsafeNativeMethods.MQReceiveMessage(handle.DangerousGetHandle(), timeoutIntervalInMilliseconds,
                                        UnsafeNativeMethods.MQ_ACTION_RECEIVE, nativePropertiesPointer, null, IntPtr.Zero, IntPtr.Zero, internalTrans);
                            if (retCode == UnsafeNativeMethods.MQ_ERROR_IO_TIMEOUT)
                            {
                                // keep trying until we timeout
                                timeoutInMilliseconds = TimeoutHelper.ToMilliseconds(timeoutHelper.RemainingTime());
                                if (timeoutInMilliseconds == 0)
                                {
                                    return retCode;
                                }
                            }
                            else if (retCode != 0)
                            {
                                BOID boid = new BOID();
                                internalTrans.Abort(
                                    ref boid, // pboidReason
                                    0,  // fRetaining
                                    0   // fAsync
                                    );

                                return retCode;
                                // we don't need to release the ITransaction as MSMQ does not increment the ref counter
                                // in MQBeginTransaction
                            }
                            else
                            {
                                // we got a message within the specified time out
                                break;
                            }
                        }
                    }

                    TransactionLookupEntry entry;

                    lock (this.internalStateLock)
                    {
                        if (!this.lockMap.TryGetValue(message.LookupId.Value, out entry))
                        {
                            this.lockMap.Add(message.LookupId.Value, new TransactionLookupEntry(message.LookupId.Value, internalTrans));
                            receivedMessage = true;
                        }
                        else
                        {
                            // this was a message that was in the process of being handed off
                            // from some app trans to some internal MSMQ transaction
                            // and we grabbed it before the Abort() could finish
                            // need to be a good citizen and finish that Abort() job for it
                            entry.MsmqInternalTransaction = internalTrans;
                        }
                    }
                }
            }
            finally
            {
                message.Unpin();
            }

            return retCode;
        }
Example #3
0
        private int PeekLockCore(MsmqQueueHandle handle, MsmqInputMessage message, TimeSpan timeout)
        {
            int           num        = 0;
            TimeoutHelper helper     = new TimeoutHelper(timeout);
            IntPtr        properties = message.Pin();

            try
            {
                bool flag = false;
                while (!flag)
                {
                    ITransaction transaction;
                    bool         flag2;
                    object       obj2;
                    num = UnsafeNativeMethods.MQBeginTransaction(out transaction);
                    if (num != 0)
                    {
                        return(num);
                    }
                    int num3 = (TimeoutHelper.ToMilliseconds(helper.RemainingTime()) == 0) ? 0 : 100;
Label_0045:
                    flag2 = false;
                    try
                    {
                        Monitor.Enter(obj2 = this.receiveLock, ref flag2);
                        num = UnsafeNativeMethods.MQReceiveMessage(handle.DangerousGetHandle(), num3, 0, properties, null, IntPtr.Zero, IntPtr.Zero, transaction);
                        if (num == -1072824293)
                        {
                            if (TimeoutHelper.ToMilliseconds(helper.RemainingTime()) == 0)
                            {
                                return(num);
                            }
                            goto Label_0045;
                        }
                        if (num != 0)
                        {
                            BOID pboidReason = new BOID();
                            transaction.Abort(ref pboidReason, 0, 0);
                            return(num);
                        }
                    }
                    finally
                    {
                        if (flag2)
                        {
                            Monitor.Exit(obj2);
                        }
                    }
                    lock (this.internalStateLock)
                    {
                        TransactionLookupEntry entry;
                        if (!this.lockMap.TryGetValue(message.LookupId.Value, out entry))
                        {
                            this.lockMap.Add(message.LookupId.Value, new TransactionLookupEntry(message.LookupId.Value, transaction));
                            flag = true;
                        }
                        else
                        {
                            entry.MsmqInternalTransaction = transaction;
                        }
                        continue;
                    }
                }
            }
            finally
            {
                message.Unpin();
            }
            return(num);
        }
 private int PeekLockCore(MsmqQueueHandle handle, MsmqInputMessage message, TimeSpan timeout)
 {
     int num = 0;
     TimeoutHelper helper = new TimeoutHelper(timeout);
     IntPtr properties = message.Pin();
     try
     {
         bool flag = false;
         while (!flag)
         {
             ITransaction transaction;
             bool flag2;
             object obj2;
             num = UnsafeNativeMethods.MQBeginTransaction(out transaction);
             if (num != 0)
             {
                 return num;
             }
             int num3 = (TimeoutHelper.ToMilliseconds(helper.RemainingTime()) == 0) ? 0 : 100;
         Label_0045:
             flag2 = false;
             try
             {
                 Monitor.Enter(obj2 = this.receiveLock, ref flag2);
                 num = UnsafeNativeMethods.MQReceiveMessage(handle.DangerousGetHandle(), num3, 0, properties, null, IntPtr.Zero, IntPtr.Zero, transaction);
                 if (num == -1072824293)
                 {
                     if (TimeoutHelper.ToMilliseconds(helper.RemainingTime()) == 0)
                     {
                         return num;
                     }
                     goto Label_0045;
                 }
                 if (num != 0)
                 {
                     BOID pboidReason = new BOID();
                     transaction.Abort(ref pboidReason, 0, 0);
                     return num;
                 }
             }
             finally
             {
                 if (flag2)
                 {
                     Monitor.Exit(obj2);
                 }
             }
             lock (this.internalStateLock)
             {
                 TransactionLookupEntry entry;
                 if (!this.lockMap.TryGetValue(message.LookupId.Value, out entry))
                 {
                     this.lockMap.Add(message.LookupId.Value, new TransactionLookupEntry(message.LookupId.Value, transaction));
                     flag = true;
                 }
                 else
                 {
                     entry.MsmqInternalTransaction = transaction;
                 }
                 continue;
             }
         }
     }
     finally
     {
         message.Unpin();
     }
     return num;
 }