Пример #1
0
        // Events

        private void UnloadEventHandler(object sender, EventArgs e)
        {
            // Make non-blocking call to ProcessDispatcher to ThreadPool.QueueUserWorkItem to complete
            // stopping of all start calls in this AppDomain.  For containers shared among various AppDomains,
            // this will just be a ref-count subtract.  For non-shared containers, we will close the container
            // and clean-up.
            SqlDependencyProcessDispatcher dispatcher = SqlDependency.ProcessDispatcher;

            if (null != dispatcher)
            {
                dispatcher.QueueAppDomainUnloading(SqlDependency.AppDomainKey);
            }
        }
Пример #2
0
        private void UnloadEventHandler(object sender, EventArgs e)
        {
            IntPtr ptr;

            Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependencyPerAppDomainDispatcher.UnloadEventHandler|DEP> %d#", this.ObjectID);
            try
            {
                SqlDependencyProcessDispatcher processDispatcher = SqlDependency.ProcessDispatcher;
                if (processDispatcher != null)
                {
                    processDispatcher.QueueAppDomainUnloading(SqlDependency.AppDomainKey);
                }
            }
            finally
            {
                Bid.ScopeLeave(ref ptr);
            }
        }
Пример #3
0
        // ------
        // Events
        // ------

        private void UnloadEventHandler(object sender, EventArgs e)
        {
            IntPtr hscp;

            Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependencyPerAppDomainDispatcher.UnloadEventHandler|DEP> %d#", ObjectID);
            try {
                // Make non-blocking call to ProcessDispatcher to ThreadPool.QueueUserWorkItem to complete
                // stopping of all start calls in this AppDomain.  For containers shared among various AppDomains,
                // this will just be a ref-count subtract.  For non-shared containers, we will close the container
                // and clean-up.
                SqlDependencyProcessDispatcher dispatcher = SqlDependency.ProcessDispatcher;
                if (null != dispatcher)
                {
                    dispatcher.QueueAppDomainUnloading(SqlDependency.AppDomainKey);
                }
            }
            finally {
                Bid.ScopeLeave(ref hscp);
            }
        }
        private static void ObtainProcessDispatcher()
        {
            byte[] data = SNINativeMethodWrapper.GetData();
            if (data == null)
            {
                Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> nativeStorage null, obtaining dispatcher AppDomain and creating ProcessDispatcher.\n");
                _AppDomain defaultAppDomain = SNINativeMethodWrapper.GetDefaultAppDomain();
                if (defaultAppDomain != null)
                {
                    ObjectHandle handle = CreateProcessDispatcher(defaultAppDomain);
                    if (handle != null)
                    {
                        SqlDependencyProcessDispatcher dispatcher = (SqlDependencyProcessDispatcher)handle.Unwrap();
                        if (dispatcher != null)
                        {
                            _processDispatcher = dispatcher.SingletonProcessDispatcher;
                            ObjRef          objRef     = GetObjRef(_processDispatcher);
                            BinaryFormatter formatter2 = new BinaryFormatter();
                            MemoryStream    stream     = new MemoryStream();
                            GetSerializedObject(objRef, formatter2, stream);
                            SNINativeMethodWrapper.SetData(stream.GetBuffer());
                            return;
                        }
                        Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - ObjectHandle.Unwrap returned null!\n");
                        throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyObtainProcessDispatcherFailureObjectHandle);
                    }
                    Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - AppDomain.CreateInstance returned null!\n");
                    throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyProcessDispatcherFailureCreateInstance);
                }
                Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - unable to obtain default AppDomain!\n");
                throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyProcessDispatcherFailureAppDomain);
            }
            Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> nativeStorage not null, obtaining existing dispatcher AppDomain and ProcessDispatcher.\n");
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream    stream2   = new MemoryStream(data);

            _processDispatcher = GetDeserializedObject(formatter, stream2);
            Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> processDispatcher obtained, ID: %d\n", _processDispatcher.ObjectID);
        }
 private static void ObtainProcessDispatcher()
 {
     byte[] data = SNINativeMethodWrapper.GetData();
     if (data == null)
     {
         Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> nativeStorage null, obtaining dispatcher AppDomain and creating ProcessDispatcher.\n");
         _AppDomain defaultAppDomain = SNINativeMethodWrapper.GetDefaultAppDomain();
         if (defaultAppDomain != null)
         {
             ObjectHandle handle = CreateProcessDispatcher(defaultAppDomain);
             if (handle != null)
             {
                 SqlDependencyProcessDispatcher dispatcher = (SqlDependencyProcessDispatcher) handle.Unwrap();
                 if (dispatcher != null)
                 {
                     _processDispatcher = dispatcher.SingletonProcessDispatcher;
                     ObjRef objRef = GetObjRef(_processDispatcher);
                     BinaryFormatter formatter2 = new BinaryFormatter();
                     MemoryStream stream = new MemoryStream();
                     GetSerializedObject(objRef, formatter2, stream);
                     SNINativeMethodWrapper.SetData(stream.GetBuffer());
                     return;
                 }
                 Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - ObjectHandle.Unwrap returned null!\n");
                 throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyObtainProcessDispatcherFailureObjectHandle);
             }
             Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - AppDomain.CreateInstance returned null!\n");
             throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyProcessDispatcherFailureCreateInstance);
         }
         Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - unable to obtain default AppDomain!\n");
         throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyProcessDispatcherFailureAppDomain);
     }
     Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> nativeStorage not null, obtaining existing dispatcher AppDomain and ProcessDispatcher.\n");
     BinaryFormatter formatter = new BinaryFormatter();
     MemoryStream stream2 = new MemoryStream(data);
     _processDispatcher = GetDeserializedObject(formatter, stream2);
     Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> processDispatcher obtained, ID: %d\n", _processDispatcher.ObjectID);
 }
 private static ObjRef GetObjRef(SqlDependencyProcessDispatcher _processDispatcher)
 {
     return RemotingServices.Marshal(_processDispatcher);
 }
Пример #7
0
        internal static bool Start(string connectionString, string queue, bool useDefaults)
        {
            if (string.IsNullOrEmpty(connectionString))
            {
                if (null == connectionString)
                {
                    throw ADP.ArgumentNull(nameof(connectionString));
                }
                else
                {
                    throw ADP.Argument(nameof(connectionString));
                }
            }

            if (!useDefaults && string.IsNullOrEmpty(queue))
            {                       // If specified but null or empty, use defaults.
                useDefaults = true;
                queue       = null; // Force to null - for proper hashtable comparison for default case.
            }

            // End duplicate Start/Stop logic.

            bool errorOccurred = false;
            bool result        = false;

            lock (s_startStopLock)
            {
                try
                {
                    if (null == s_processDispatcher)
                    { // Ensure _processDispatcher reference is present - inside lock.
                        s_processDispatcher = SqlDependencyProcessDispatcher.SingletonProcessDispatcher;
                    }

                    if (useDefaults)
                    { // Default listener.
                        string server = null;
                        DbConnectionPoolIdentity identity = null;
                        string user           = null;
                        string database       = null;
                        string service        = null;
                        bool   appDomainStart = false;

                        RuntimeHelpers.PrepareConstrainedRegions();
                        try
                        { // CER to ensure that if Start succeeds we add to hash completing setup.
                            // Start using process wide default service/queue & database from connection string.
                            result = s_processDispatcher.StartWithDefault(
                                connectionString,
                                out server,
                                out identity,
                                out user,
                                out database,
                                ref service,
                                s_appDomainKey,
                                SqlDependencyPerAppDomainDispatcher.SingletonInstance,
                                out errorOccurred,
                                out appDomainStart);
                        }
                        finally
                        {
                            if (appDomainStart && !errorOccurred)
                            { // If success, add to hashtable.
                                IdentityUserNamePair identityUser    = new IdentityUserNamePair(identity, user);
                                DatabaseServicePair  databaseService = new DatabaseServicePair(database, service);
                                if (!AddToServerUserHash(server, identityUser, databaseService))
                                {
                                    try
                                    {
                                        Stop(connectionString, queue, useDefaults, true);
                                    }
                                    catch (Exception e)
                                    { // Discard stop failure!
                                        if (!ADP.IsCatchableExceptionType(e))
                                        {
                                            throw;
                                        }

                                        ADP.TraceExceptionWithoutRethrow(e); // Discard failure, but trace for now.
                                    }
                                    throw SQL.SqlDependencyDuplicateStart();
                                }
                            }
                        }
                    }
                    else
                    { // Start with specified service/queue & database.
                        result = s_processDispatcher.Start(
                            connectionString,
                            queue,
                            s_appDomainKey,
                            SqlDependencyPerAppDomainDispatcher.SingletonInstance);
                        // No need to call AddToServerDatabaseHash since if not using default queue user is required
                        // to provide options themselves.
                    }
                }
                catch (Exception e)
                {
                    if (!ADP.IsCatchableExceptionType(e))
                    {
                        throw;
                    }

                    ADP.TraceExceptionWithoutRethrow(e); // Discard failure, but trace for now.

                    throw;
                }
            }

            return(result);
        }
Пример #8
0
        private static void ObtainProcessDispatcher() {
            byte[] nativeStorage = SNINativeMethodWrapper.GetData();

            if (nativeStorage == null) {
                Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> nativeStorage null, obtaining dispatcher AppDomain and creating ProcessDispatcher.\n");
#if DEBUG       // Possibly expensive, limit to debug.
                Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> AppDomain.CurrentDomain.FriendlyName: %ls\n", AppDomain.CurrentDomain.FriendlyName);
#endif
                _AppDomain masterDomain = SNINativeMethodWrapper.GetDefaultAppDomain();

                if (null != masterDomain) {
                    ObjectHandle handle = CreateProcessDispatcher(masterDomain);

                    if (null != handle) {
                        SqlDependencyProcessDispatcher dependency = (SqlDependencyProcessDispatcher) handle.Unwrap();

                        if (null != dependency) {
                            _processDispatcher = dependency.SingletonProcessDispatcher; // Set to static instance.

                            // Serialize and set in native.
                            ObjRef objRef = GetObjRef(_processDispatcher);
                            BinaryFormatter formatter = new BinaryFormatter();
                            MemoryStream    stream    = new MemoryStream();
                            GetSerializedObject(objRef, formatter, stream);
                            SNINativeMethodWrapper.SetData(stream.GetBuffer()); // Native will be forced to synchronize and not overwrite.
                        }
                        else {
                            Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - ObjectHandle.Unwrap returned null!\n");
                            throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyObtainProcessDispatcherFailureObjectHandle);
                        }
                    }
                    else {
                        Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - AppDomain.CreateInstance returned null!\n");
                        throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyProcessDispatcherFailureCreateInstance);
                    }
                }
                else {
                    Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP|ERR> ERROR - unable to obtain default AppDomain!\n");
                    throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyProcessDispatcherFailureAppDomain);
                }
            }
            else {
                Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> nativeStorage not null, obtaining existing dispatcher AppDomain and ProcessDispatcher.\n");
#if DEBUG       // Possibly expensive, limit to debug.
                Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> AppDomain.CurrentDomain.FriendlyName: %ls\n", AppDomain.CurrentDomain.FriendlyName);
#endif
                BinaryFormatter formatter = new BinaryFormatter();
                MemoryStream    stream    = new MemoryStream(nativeStorage);
                _processDispatcher = GetDeserializedObject(formatter, stream); // Deserialize and set for appdomain.
                Bid.NotificationsTrace("<sc.SqlDependency.ObtainProcessDispatcher|DEP> processDispatcher obtained, ID: %d\n", _processDispatcher.ObjectID);
            }
        }
 private static ObjRef GetObjRef(SqlDependencyProcessDispatcher _processDispatcher)
 {
     return(RemotingServices.Marshal(_processDispatcher));
 }
 internal SqlConnectionContainer(SqlDependencyProcessDispatcher.SqlConnectionContainerHashHelper hashHelper, string appDomainKey, bool useDefaults)
 {
     IntPtr ptr;
     this._defaultWaitforTimeout = 0xea60;
     this._objectID = Interlocked.Increment(ref _objectTypeCount);
     Bid.NotificationsScopeEnter(out ptr, "<sc.SqlConnectionContainer|DEP> %d#, queue: '%ls'", this.ObjectID, hashHelper.Queue);
     bool flag = false;
     try
     {
         this._hashHelper = hashHelper;
         string str = null;
         if (useDefaults)
         {
             str = Guid.NewGuid().ToString();
             this._queue = "SqlQueryNotificationService-" + str;
             this._hashHelper.ConnectionStringBuilder.ApplicationName = this._queue;
         }
         else
         {
             this._queue = this._hashHelper.Queue;
         }
         this._con = new SqlConnection(this._hashHelper.ConnectionStringBuilder.ConnectionString);
         ((SqlConnectionString) this._con.ConnectionOptions).CreatePermissionSet().Assert();
         this._con.Open();
         this._cachedServer = this._con.DataSource;
         if (!this._con.IsYukonOrNewer)
         {
             throw SQL.NotificationsRequireYukon();
         }
         if (hashHelper.Identity != null)
         {
             this._windowsIdentity = DbConnectionPoolIdentity.GetCurrentWindowsIdentity();
         }
         this._escapedQueueName = SqlConnection.FixupDatabaseTransactionName(this._queue);
         this._appDomainKeyHash = new Dictionary<string, int>();
         this._com = new SqlCommand();
         this._com.Connection = this._con;
         this._com.CommandText = "select is_broker_enabled from sys.databases where database_id=db_id()";
         if (!((bool) this._com.ExecuteScalar()))
         {
             throw SQL.SqlDependencyDatabaseBrokerDisabled();
         }
         this._conversationGuidParam = new SqlParameter("@p1", SqlDbType.UniqueIdentifier);
         this._timeoutParam = new SqlParameter("@p2", SqlDbType.Int);
         this._timeoutParam.Value = 0;
         this._com.Parameters.Add(this._timeoutParam);
         flag = true;
         this._receiveQuery = "WAITFOR(RECEIVE TOP (1) message_type_name, conversation_handle, cast(message_body AS XML) as message_body from " + this._escapedQueueName + "), TIMEOUT @p2;";
         if (useDefaults)
         {
             this._sprocName = SqlConnection.FixupDatabaseTransactionName("SqlQueryNotificationStoredProcedure-" + str);
             this.CreateQueueAndService(false);
         }
         else
         {
             this._com.CommandText = this._receiveQuery;
             this._endConversationQuery = "END CONVERSATION @p1; ";
             this._concatQuery = this._endConversationQuery + this._receiveQuery;
         }
         bool appDomainStart = false;
         this.IncrementStartCount(appDomainKey, out appDomainStart);
         this.SynchronouslyQueryServiceBrokerQueue();
         this._timeoutParam.Value = this._defaultWaitforTimeout;
         this.AsynchronouslyQueryServiceBrokerQueue();
     }
     catch (Exception exception)
     {
         if (!ADP.IsCatchableExceptionType(exception))
         {
             throw;
         }
         ADP.TraceExceptionWithoutRethrow(exception);
         if (flag)
         {
             this.TearDownAndDispose();
         }
         else
         {
             if (this._com != null)
             {
                 this._com.Dispose();
                 this._com = null;
             }
             if (this._con != null)
             {
                 this._con.Dispose();
                 this._con = null;
             }
         }
         throw;
     }
     finally
     {
         Bid.ScopeLeave(ref ptr);
     }
 }