/// <summary>
        /// Called by the appender that just appended a transaction to the log.
        /// </summary>
        /// <param name="logForceEvents"> A trace event for the given log append operation. </param>
        /// <returns> {@code true} if we got lucky and were the ones forcing the log. </returns>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: protected boolean forceAfterAppend(org.neo4j.kernel.impl.transaction.tracing.LogForceEvents logForceEvents) throws java.io.IOException
        protected internal virtual bool ForceAfterAppend(LogForceEvents logForceEvents)
        {
            // There's a benign race here, where we add our link before we update our next pointer.
            // This is okay, however, because unparkAll() spins when it sees a null next pointer.
            ThreadLink threadLink = new ThreadLink(Thread.CurrentThread);

            threadLink.Next = _threadLinkHead.getAndSet(threadLink);
            bool attemptedForce = false;

            using (LogForceWaitEvent logForceWaitEvent = logForceEvents.BeginLogForceWait())
            {
                do
                {
                    if (_forceLock.tryLock())
                    {
                        attemptedForce = true;
                        try
                        {
                            ForceLog(logForceEvents);
                            // In the event of any failure a database panic will be raised and thrown here
                        }
                        finally
                        {
                            _forceLock.unlock();

                            // We've released the lock, so unpark anyone who might have decided park while we were working.
                            // The most recently parked thread is the one most likely to still have warm caches, so that's
                            // the one we would prefer to unpark. Luckily, the stack nature of the ThreadLinks makes it easy
                            // to get to.
                            ThreadLink nextWaiter = _threadLinkHead.get();
                            nextWaiter.Unpark();
                        }
                    }
                    else
                    {
                        WaitForLogForce();
                    }
                } while (!threadLink.Done);

                // If there were many threads committing simultaneously and I wasn't the lucky one
                // actually doing the forcing (where failure would throw panic exception) I need to
                // explicitly check if everything is OK before considering this transaction committed.
                if (!attemptedForce)
                {
                    _databaseHealth.assertHealthy(typeof(IOException));
                }
            }
            return(attemptedForce);
        }
 private void UnparkAll(ThreadLink links)
 {
     do
     {
         links.Done = true;
         links.Unpark();
         ThreadLink tmp;
         do
         {
             // Spin because of the race:y update when consing.
             tmp = links.Next;
         } while (tmp == null);
         links = tmp;
     } while (links != ThreadLink.End);
 }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private void forceLog(org.neo4j.kernel.impl.transaction.tracing.LogForceEvents logForceEvents) throws java.io.IOException
        private void ForceLog(LogForceEvents logForceEvents)
        {
            ThreadLink links = _threadLinkHead.getAndSet(ThreadLink.End);

            try
            {
                using (LogForceEvent logForceEvent = logForceEvents.BeginLogForce())
                {
                    Force();
                }
            }
//JAVA TO C# CONVERTER WARNING: 'final' catch parameters are not available in C#:
//ORIGINAL LINE: catch (final Throwable panic)
            catch (Exception panic)
            {
                _databaseHealth.panic(panic);
                throw panic;
            }
            finally
            {
                UnparkAll(links);
            }
        }