Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
            }
        }