protected virtual void PostNode(Node *node) { // Set the write flag for this node (the node is reserved so no need for locks) node->DoneWrite = 1; // Move the write pointer as far forward as we can // always starting from WriteEnd to make all contiguous // completed nodes available for reading. for (; ;) { int blockIndex = _nodeHeader->WriteEnd; node = this[blockIndex]; #pragma warning disable 0420 // ignore ref to volatile warning - Interlocked API if (Interlocked.CompareExchange(ref node->DoneWrite, 0, 1) != 1) { // If we get here then another thread either another thread // has already moved the write index or we have moved forward // as far as we can return; } // Move the pointer one forward Interlocked.CompareExchange(ref _nodeHeader->WriteEnd, node->Next, blockIndex); #pragma warning restore 0420 // Signal the "data exists" event if read threads are waiting if (blockIndex == _nodeHeader->ReadStart) { DataExists.Set(); } } }
/// <summary> /// Makes a node available for reading after writing is complete /// </summary> /// <param name="node">An unsafe pointer to the node to return</param> protected virtual void PostNode(Node *node) { //set pointer oft last written Node Interlocked.Exchange(ref _nodeHeader->WriteLastIndex, node->Index); //set pointer oft last written Node Interlocked.Exchange(ref _nodeHeader->WriteLastCounter, node->ContinueCounter); // Move the pointer one forward Interlocked.Exchange(ref _nodeHeader->WriteEnd, node->Next); DiagInfo.PostedNode = *node; // free node node->FreeNodeWrite(); // Signal the "data exists" event for read threads DataExists.Set(); }