/// <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); }