static private EnsureNotOnNetworkThread ( [ callerMethod = null ) : void | ||
callerMethod | [ | |
return | void |
/// <summary>Set an option on this cluster that does not take any parameter</summary> /// <param name="option">Option to set</param> public void SetOption(FdbClusterOption option) { ThrowIfDisposed(); Fdb.EnsureNotOnNetworkThread(); if (Logging.On && Logging.IsVerbose) { Logging.Verbose(this, "SetOption", $"Setting cluster option {option.ToString()}"); } m_handler.SetOption(option, Slice.Nil); }
/// <summary>Set an option on this cluster that takes an integer value</summary> /// <param name="option">Option to set</param> /// <param name="value">Value of the parameter</param> public void SetOption(FdbClusterOption option, long value) { ThrowIfDisposed(); Fdb.EnsureNotOnNetworkThread(); if (Logging.On && Logging.IsVerbose) { Logging.Verbose(this, "SetOption", $"Setting cluster option {option.ToString()} to {value}"); } var data = Slice.FromFixed64(value); m_handler.SetOption(option, data); }
/// <summary>Set an option on this cluster that takes a string value</summary> /// <param name="option">Option to set</param> /// <param name="value">Value of the parameter (can be null)</param> public void SetOption(FdbClusterOption option, string value) { ThrowIfDisposed(); Fdb.EnsureNotOnNetworkThread(); if (Logging.On && Logging.IsVerbose) { Logging.Verbose(this, "SetOption", $"Setting cluster option {option.ToString()} to '{value ?? "<null>"}'"); } var data = FdbNative.ToNativeString(value, nullTerminated: true); m_handler.SetOption(option, data); }
/// <summary>Throws if the transaction is not in a valid state (for reading/writing) and that we can proceed with a read or write operation</summary> /// <param name="allowFromNetworkThread">If true, this operation is allowed to run from a callback on the network thread and should NEVER block.</param> /// <param name="allowFailedState">If true, this operation can run even if the transaction is in a failed state.</param> /// <exception cref="System.ObjectDisposedException">If Dispose as already been called on the transaction</exception> /// <exception cref="System.InvalidOperationException">If CommitAsync() or Rollback() have already been called on the transaction, or if the database has been closed</exception> internal void EnsureStilValid(bool allowFromNetworkThread = false, bool allowFailedState = false) { // We must not be disposed if (allowFailedState ? this.State == STATE_DISPOSED : this.State != STATE_READY) { ThrowOnInvalidState(this); } // The cancellation token should not be signaled m_cancellation.ThrowIfCancellationRequested(); // We cannot be called from the network thread (or else we will deadlock) if (!allowFromNetworkThread) { Fdb.EnsureNotOnNetworkThread(); } // Ensure that the DB is still opened and that this transaction is still registered with it this.Database.EnsureTransactionIsValid(this); // we are ready to go ! }
/// <summary>Stops the thread running the FDB event loop</summary> private static void StopEventLoop() { if (s_eventLoopStarted) { // We cannot be called from the network thread itself, or else we will dead lock ! Fdb.EnsureNotOnNetworkThread(); if (Logging.On) { Logging.Verbose(typeof(Fdb), "StopEventLoop", "Stopping network thread..."); } s_eventLoopStopRequested = true; var err = FdbNative.StopNetwork(); if (err != FdbError.Success) { if (Logging.On) { Logging.Warning(typeof(Fdb), "StopEventLoop", $"Failed to stop event loop: {err.ToString()}"); } } s_eventLoopStarted = false; var thread = s_eventLoop; if (thread != null && thread.IsAlive) { // BUGBUG: specs says that we need to wait for the network thread to stop gracefuly, or else data integrity may not be guaranteed... // We should wait for a bit, and only attempt to Abort() the thread after a timeout (30sec ? more ?) // keep track of how much time it took to stop... var duration = Stopwatch.StartNew(); try { //TODO: replace with a ManualResetEvent that would get signaled at the end of the event loop ? while (thread.IsAlive && duration.Elapsed.TotalSeconds < 5) { // wait a bit... Thread.Sleep(250); } if (thread.IsAlive) { if (Logging.On) { Logging.Warning(typeof(Fdb), "StopEventLoop", $"The fdb network thread has not stopped after {duration.Elapsed.TotalSeconds:N0} seconds. Forcing shutdown..."); } // Force a shutdown thread.Abort(); bool stopped = thread.Join(TimeSpan.FromSeconds(30)); //REVIEW: is this even usefull? If the thread is stuck in a native P/Invoke call, it won't get notified until it returns to managed code ... // => in that case, we have a zombie thread on our hands... if (!stopped) { if (Logging.On) { Logging.Warning(typeof(Fdb), "StopEventLoop", $"The fdb network thread failed to stop after more than {duration.Elapsed.TotalSeconds:N0} seconds. Transaction integrity may not be guaranteed."); } } } } catch (ThreadAbortException) { // Should not happen, unless we are called from a thread that is itself being stopped ? } finally { s_eventLoop = null; duration.Stop(); if (duration.Elapsed.TotalSeconds >= 20) { if (Logging.On) { Logging.Warning(typeof(Fdb), "StopEventLoop", $"The fdb network thread took a long time to stop ({duration.Elapsed.TotalSeconds:N0} seconds)."); } } } } } }