public static object CreateInMTA(Type type)
 {
     if (IsNoContextMTA())
     {
         return Activator.CreateInstance(type);
     }
     MTARequest request = new MTARequest(type);
     lock (critSec)
     {
         if (!workerThreadInitialized)
         {
             InitWorkerThread();
             workerThreadInitialized = true;
         }
         int index = reqList.Add(request);
         if (!evtGo.Set())
         {
             reqList.RemoveAt(index);
             throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
         }
     }
     request.evtDone.WaitOne();
     if (request.exception != null)
     {
         throw request.exception;
     }
     return request.createdObject;
 }
Beispiel #2
0
        public static object CreateInMTA(Type type)
        {
            if (IsNoContextMTA())
            {
                return(Activator.CreateInstance(type));
            }
            MTARequest request = new MTARequest(type);

            lock (critSec)
            {
                if (!workerThreadInitialized)
                {
                    InitWorkerThread();
                    workerThreadInitialized = true;
                }
                int index = reqList.Add(request);
                if (!evtGo.Set())
                {
                    reqList.RemoveAt(index);
                    throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
                }
            }
            request.evtDone.WaitOne();
            if (request.exception != null)
            {
                throw request.exception;
            }
            return(request.createdObject);
        }
Beispiel #3
0
        /*
         * [DllImport("kernel32")] static extern IntPtr CreateEvent(IntPtr pSecurity, int manual, int initial, IntPtr name);
         * [SuppressUnmanagedCodeSecurity, DllImport("kernel32")] static extern int SetEvent(IntPtr handle);
         * [SuppressUnmanagedCodeSecurity, DllImport("kernel32")] static extern int WaitForSingleObject(IntPtr handle, int timeout);
         * IntPtr hDoIndicate = CreateEvent(IntPtr.Zero, 0, 0, IntPtr.Zero);
         * IntPtr hDoneIndicate = CreateEvent(IntPtr.Zero, 0, 0, IntPtr.Zero);
         */

        // Worker thread for each EventSource



        //
        // Ensure we are able to trap exceptions from worker thread.
        // Called from IndicateEvents which in turn is protected from
        // concurrent access.
        //


        public void MTAWorkerThread2()
        {
            while (true)
            {
                doIndicate.WaitOne(); //WaitForSingleObject(hDoIndicate, -1);
                if (alive == false)
                {
                    break;
                }
                // get requests from the request queue. Since two Set within short time on evtGo can wake this thread only once
                // workerthread should check until we empty all the results. Even if we consume the request that is not set,
                // workerthread will wake up one more time unnecessarily and do nothing
                while (true)
                {
                    MTARequest reqToProcess = null;
                    lock (critSec)
                    {
                        if (reqList.Count > 0)
                        {
                            reqToProcess = (MTARequest)reqList[0];
                            reqList.RemoveAt(0);
                        }
                        else
                        {
                            break;  // break the inner while true
                        }
                    }
                    try
                    {
                        if (pSinkMTA != null)
                        {
                            int hresult = pSinkMTA.Indicate_(reqToProcess.lengthFromSTA, reqToProcess.objectsFromSTA);
                            if (hresult < 0)
                            {
                                if ((hresult & 0xfffff000) == 0x80041000)
                                {
                                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult);
                                }
                                else
                                {
                                    Marshal.ThrowExceptionForHR(hresult);
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        reqToProcess.exception = e;
                    }
                    finally
                    {
                        reqToProcess.doneIndicate.Set(); //SetEvent(hDoneIndicate);
                        GC.KeepAlive(this);
                    }
                }
            }
        }
Beispiel #4
0
 public void IndicateEvents(int length, IntPtr[] objects)
 {
     if (pSinkMTA == null)
     {
         return;
     }
     //
     // Checking for MTA is not enough.  We need to make sure we are not in a COM+ Context
     //
     if (MTAHelper.IsNoContextMTA())
     {
         // Sink lives in MTA
         int hresult = pSinkMTA.Indicate_(length, objects);
         if (hresult < 0)
         {
             if ((hresult & 0xfffff000) == 0x80041000)
             {
                 ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult);
             }
             else
             {
                 Marshal.ThrowExceptionForHR(hresult);
             }
         }
     }
     else
     {
         MTARequest myReq = new MTARequest(length, objects);
         int        ndx;
         lock (critSec)
         {
             // Do it from worker thread
             if (workerThreadInitialized == false)
             {
                 // We've never created worker thread
                 Thread thread = new Thread(new ThreadStart(MTAWorkerThread2));
                 thread.IsBackground = true;
                 thread.SetApartmentState(ApartmentState.MTA);
                 thread.Start();
                 workerThreadInitialized = true;
             }
             ndx = reqList.Add(myReq);
             if (doIndicate.Set() == false)  //SetEvent(hDoIndicate);
             {
                 reqList.RemoveAt(ndx);
                 throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
             }
         }
         myReq.doneIndicate.WaitOne(); //WaitForSingleObject(hDoneIndicate, -1);
         if (myReq.exception != null)
         {
             throw myReq.exception;
         }
     }
     GC.KeepAlive(this);
 }
Beispiel #5
0
 public void IndicateEvents(int length, IntPtr[] objects)
 {
     if (this.pSinkMTA != null)
     {
         if (MTAHelper.IsNoContextMTA())
         {
             int errorCode = this.pSinkMTA.Indicate_(length, objects);
             if (errorCode < 0)
             {
                 if ((errorCode & 0xfffff000L) == 0x80041000L)
                 {
                     ManagementException.ThrowWithExtendedInfo((ManagementStatus)errorCode);
                 }
                 else
                 {
                     Marshal.ThrowExceptionForHR(errorCode);
                 }
             }
         }
         else
         {
             MTARequest request = new MTARequest(length, objects);
             lock (this.critSec)
             {
                 if (!this.workerThreadInitialized)
                 {
                     Thread thread = new Thread(new ThreadStart(this.MTAWorkerThread2))
                     {
                         IsBackground = true
                     };
                     thread.SetApartmentState(ApartmentState.MTA);
                     thread.Start();
                     this.workerThreadInitialized = true;
                 }
                 int index = this.reqList.Add(request);
                 if (!this.doIndicate.Set())
                 {
                     this.reqList.RemoveAt(index);
                     throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
                 }
             }
             request.doneIndicate.WaitOne();
             if (request.exception != null)
             {
                 throw request.exception;
             }
         }
         GC.KeepAlive(this);
     }
 }
        // This method will create an instance of the requeted type in the MTA
        public static object CreateInMTA(Type type)
        {
            // If we are currently in the MTA, we can directly create the object
            if(IsNoContextMTA())  // Bug#110141 - Checking for MTA is not enough.  We need to make sure we are not in a COM+ Context
                return Activator.CreateInstance(type);

            // We need to create the object in the MTA by using a worker thread
            // that lives in the MTA.  Make sure only one person uses this worker
            // thread at a time
            MTARequest myReq = new MTARequest(type);
            int ndx;

            lock(critSec)
            {
                // Make sure worker thread is initialized
        	    if(workerThreadInitialized == false)
                {
	                InitWorkerThread();
        	        workerThreadInitialized = true;
                }

                ndx = reqList.Add(myReq);

                if( evtGo.Set() == false )
                {
                    reqList.RemoveAt(ndx);
                    throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
                }
            }

            // release the lock so that worker thread can work on the request
            myReq.evtDone.WaitOne();

            if (myReq.exception != null)
            {
                throw myReq.exception;
            }

            return myReq.createdObject;
        }
 public void IndicateEvents(int length, IntPtr[] objects)
 {
     if (pSinkMTA == null)
         return;
     //
     // Checking for MTA is not enough.  We need to make sure we are not in a COM+ Context
     //
     if (MTAHelper.IsNoContextMTA())
     {
         // Sink lives in MTA
         int hresult = pSinkMTA.Indicate_(length, objects);
         if (hresult < 0)
         {
             if ((hresult & 0xfffff000) == 0x80041000)
                 ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult);
             else
                 Marshal.ThrowExceptionForHR(hresult);
         }
     }
     else
     {
         MTARequest myReq = new MTARequest(length,objects);
         int ndx;
         lock(critSec)
         {
             // Do it from worker thread
             if (workerThreadInitialized == false)
             {
                 // We've never created worker thread
                 Thread thread = new Thread(new ThreadStart(MTAWorkerThread2));
                 thread.IsBackground = true;
                 thread.SetApartmentState(ApartmentState.MTA);
                 thread.Start();
                 workerThreadInitialized = true;
             }
             ndx = reqList.Add(myReq);
             if( doIndicate.Set() == false ) //SetEvent(hDoIndicate);
             {
                 reqList.RemoveAt(ndx);
                 throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
             }
         }
         myReq.doneIndicate.WaitOne(); //WaitForSingleObject(hDoneIndicate, -1);
         if (myReq.exception != null)
         {
             throw myReq.exception;
         }
     }
     GC.KeepAlive(this); 
 }
 public void IndicateEvents(int length, IntPtr[] objects)
 {
     if (this.pSinkMTA != null)
     {
         if (MTAHelper.IsNoContextMTA())
         {
             int errorCode = this.pSinkMTA.Indicate_(length, objects);
             if (errorCode < 0)
             {
                 if ((errorCode & 0xfffff000L) == 0x80041000L)
                 {
                     ManagementException.ThrowWithExtendedInfo((ManagementStatus) errorCode);
                 }
                 else
                 {
                     Marshal.ThrowExceptionForHR(errorCode);
                 }
             }
         }
         else
         {
             MTARequest request = new MTARequest(length, objects);
             lock (this.critSec)
             {
                 if (!this.workerThreadInitialized)
                 {
                     Thread thread = new Thread(new ThreadStart(this.MTAWorkerThread2)) {
                         IsBackground = true
                     };
                     thread.SetApartmentState(ApartmentState.MTA);
                     thread.Start();
                     this.workerThreadInitialized = true;
                 }
                 int index = this.reqList.Add(request);
                 if (!this.doIndicate.Set())
                 {
                     this.reqList.RemoveAt(index);
                     throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED"));
                 }
             }
             request.doneIndicate.WaitOne();
             if (request.exception != null)
             {
                 throw request.exception;
             }
         }
         GC.KeepAlive(this);
     }
 }