/// <summary> /// Internal flush routine. /// </summary> /// <param name="curBatch"></param> /// <param name="wait">Whether to wait for flush to complete.</param> /// <param name="plc">Whether this is the last batch.</param> /// <returns>Whether this call was able to CAS previous batch</returns> private bool Flush0(DataStreamerBatch <TK, TV> curBatch, bool wait, int plc) { // 1. Try setting new current batch to help further adders. bool res = Interlocked.CompareExchange(ref _batch, (plc == PlcContinue || plc == PlcFlush) ? new DataStreamerBatch <TK, TV>(curBatch) : null, curBatch) == curBatch; // 2. Perform actual send. curBatch.Send(this, plc); if (wait) { // 3. Wait for all futures to finish. curBatch.AwaitCompletion(); } return(res); }
/// <summary> /// Internal send routine. /// </summary> /// <param name="ldr">streamer.</param> /// <param name="plc">Policy.</param> public void Send(DataStreamerImpl <TK, TV> ldr, int plc) { // 1. Delegate to the previous batch first. DataStreamerBatch <TK, TV> prev0 = _prev; if (prev0 != null) { prev0.Send(ldr, DataStreamerImpl <TK, TV> .PlcContinue); } // 2. Set guard. _rwLock.EnterWriteLock(); try { if (_sndGuard) { return; } else { _sndGuard = true; } } finally { _rwLock.ExitWriteLock(); } var handleRegistry = ldr.Marshaller.Ignite.HandleRegistry; long futHnd = 0; // 3. Actual send. try { ldr.Update(writer => { writer.WriteInt(plc); if (plc != DataStreamerImpl <TK, TV> .PlcCancelClose) { futHnd = handleRegistry.Allocate(_fut); writer.WriteLong(futHnd); WriteTo(writer); } }); } catch (Exception) { if (futHnd != 0) { handleRegistry.Release(futHnd); } throw; } if (plc == DataStreamerImpl <TK, TV> .PlcCancelClose || _size == 0) { ThreadPool.QueueUserWorkItem(_ => _fut.OnNullResult()); handleRegistry.Release(futHnd); } }