Exemplo n.º 1
0
        private async Task DoJob()
        {
            long         now = SystemClock.UptimeMillis;
            EncodedImage input;
            bool         isLast;

            lock (_gate)
            {
                input         = _encodedImage;
                isLast        = _isLast;
                _encodedImage = null;
                _isLast       = false;
                _jobState     = JobState.RUNNING;
                _jobStartTime = now;
            }

            try
            {
                // we need to do a check in case the job got cleared in the meantime
                if (ShouldProcess(input, isLast))
                {
                    await _jobRunnable.Invoke(input, isLast).ConfigureAwait(false);
                }
            }
            finally
            {
                EncodedImage.CloseSafely(input);
                OnJobFinished();
            }
        }
        public void TestCloseSafely()
        {
            EncodedImage encodedImage = new EncodedImage(_byteBufferRef);

            EncodedImage.CloseSafely(encodedImage);
            Assert.AreEqual(1, _byteBufferRef.GetUnderlyingReferenceTestOnly().GetRefCountTestOnly());
        }
            /// <summary>
            /// Performs the decode synchronously.
            /// </summary>
            private async Task DoDecode(EncodedImage encodedImage, bool isLast)
            {
                if (IsFinished() || !EncodedImage.IsValid(encodedImage))
                {
                    return;
                }

                try
                {
                    long queueTime = _jobScheduler.GetQueuedTime();
                    int  length    = isLast ?
                                     encodedImage.Size : GetIntermediateImageEndOffset(encodedImage);

                    if (length == 0)
                    {
                        return;
                    }

                    IQualityInfo quality = isLast ? ImmutableQualityInfo.FULL_QUALITY : GetQualityInfo();

                    _producerListener.OnProducerStart(_producerContext.Id, PRODUCER_NAME);
                    CloseableImage image = null;

                    try
                    {
                        image = await _parent._imageDecoder
                                .DecodeImageAsync(encodedImage, length, quality, _imageDecodeOptions)
                                .ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        _producerListener.OnProducerFinishWithFailure(
                            _producerContext.Id,
                            PRODUCER_NAME,
                            e,
                            GetExtraMap(image, queueTime, quality, isLast));

                        HandleError(e);
                        return;
                    }

                    _producerListener.OnProducerFinishWithSuccess(
                        _producerContext.Id,
                        PRODUCER_NAME,
                        GetExtraMap(image, queueTime, quality, isLast));

                    HandleResult(image, isLast);
                }
                finally
                {
                    EncodedImage.CloseSafely(encodedImage);
                }
            }
Exemplo n.º 4
0
        /// <summary>
        /// Clears the currently set job.
        ///
        /// <para /> In case the currently set job has been scheduled but
        /// not started yet, the job won't be executed.
        /// </summary>
        public void ClearJob()
        {
            EncodedImage oldEncodedImage;

            lock (_gate)
            {
                oldEncodedImage = _encodedImage;
                _encodedImage   = null;
                _isLast         = false;
            }

            EncodedImage.CloseSafely(oldEncodedImage);
        }
        /// <summary>
        /// Associates encodedImage with given key in disk cache.
        /// Disk write is performed on background thread, so the
        /// caller of this method is not blocked.
        /// </summary>
        public Task Put(ICacheKey key, EncodedImage encodedImage)
        {
            Preconditions.CheckNotNull(key);
            Preconditions.CheckArgument(EncodedImage.IsValid(encodedImage));

            // Store encodedImage in staging area
            _stagingArea.Put(key, encodedImage);

            // Write to disk cache. This will be executed on background thread,
            // so increment the ref count. When this write completes
            // (with success/failure), then we will bump down the ref count again.
            EncodedImage finalEncodedImage = EncodedImage.CloneOrNull(encodedImage);

            try
            {
                Task writeTask = _writeExecutor.Execute(() =>
                {
                    try
                    {
                        WriteToDiskCache(key, finalEncodedImage);
                    }
                    finally
                    {
                        _stagingArea.Remove(key, finalEncodedImage);
                        EncodedImage.CloseSafely(finalEncodedImage);

                        // Removes write task after it's completed.
                        Task writeTaskCompleted = default(Task);
                        _writeToDiskCacheTasks.TryRemove(key, out writeTaskCompleted);
                    }
                });

                _writeToDiskCacheTasks.TryAdd(key, writeTask);
                return(writeTask);
            }
            catch (Exception)
            {
                // We failed to enqueue cache write. Log failure and decrement ref count
                // TODO: 3697790
                Debug.WriteLine($"Failed to schedule disk-cache write for { key.ToString() }");
                _stagingArea.Remove(key, encodedImage);
                EncodedImage.CloseSafely(finalEncodedImage);

                // Removes write task due to error.
                Task writeTaskCompleted = default(Task);
                _writeToDiskCacheTasks.TryRemove(key, out writeTaskCompleted);
                throw;
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Updates the job.
        ///
        /// <para />This just updates the job, but it doesn't schedule it.
        /// In order to be executed, the job has to be scheduled after
        /// being set. In case there was a previous job scheduled that has
        /// not yet started, this new job will be executed instead.
        /// </summary>
        /// <returns>
        /// Whether the job was successfully updated.
        /// </returns>
        public bool UpdateJob(EncodedImage encodedImage, bool isLast)
        {
            if (!ShouldProcess(encodedImage, isLast))
            {
                return(false);
            }

            EncodedImage oldEncodedImage;

            lock (_gate)
            {
                oldEncodedImage = _encodedImage;
                _encodedImage   = EncodedImage.CloneOrNull(encodedImage);
                _isLast         = isLast;
            }

            EncodedImage.CloseSafely(oldEncodedImage);
            return(true);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Removes key-value from the StagingArea. Both key and value must match.
        /// </summary>
        /// <param name="key">The cache key.</param>
        /// <param name="encodedImage">Value corresponding to key.</param>
        /// <returns>true if item was removed.</returns>
        public bool Remove(ICacheKey key, EncodedImage encodedImage)
        {
            lock (_mapGate)
            {
                Preconditions.CheckNotNull(key);
                Preconditions.CheckNotNull(encodedImage);
                Preconditions.CheckArgument(EncodedImage.IsValid(encodedImage));

                EncodedImage oldValue = default(EncodedImage);
                if (!_map.TryGetValue(key, out oldValue))
                {
                    return(false);
                }

                CloseableReference <IPooledByteBuffer> oldReference = oldValue.GetByteBufferRef();
                CloseableReference <IPooledByteBuffer> reference    = encodedImage.GetByteBufferRef();

                try
                {
                    if (oldReference == null || reference == null || oldReference.Get() != reference.Get())
                    {
                        return(false);
                    }

                    _map.Remove(key);
                }
                finally
                {
                    CloseableReference <IPooledByteBuffer> .CloseSafely(reference);

                    CloseableReference <IPooledByteBuffer> .CloseSafely(oldReference);

                    EncodedImage.CloseSafely(oldValue);
                }

#if DEBUG_STAGING_AREA
                LogStats();
#endif // DEBUG_STAGING_AREA
                return(true);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Stores key-value in this StagingArea.
        /// </summary>
        /// <param name="key">The cache key.</param>
        /// <param name="encodedImage">
        /// EncodedImage to be associated with key.
        /// </param>
        public void Put(ICacheKey key, EncodedImage encodedImage)
        {
            lock (_mapGate)
            {
                Preconditions.CheckNotNull(key);
                Preconditions.CheckArgument(EncodedImage.IsValid(encodedImage));

                // We're making a 'copy' of this reference - so duplicate it
                EncodedImage oldEntry = default(EncodedImage);
                if (_map.TryGetValue(key, out oldEntry))
                {
                    _map.Remove(key);
                }

                _map.Add(key, EncodedImage.CloneOrNull(encodedImage));
                EncodedImage.CloseSafely(oldEntry);
#if DEBUG_STAGING_AREA
                LogStats();
#endif // DEBUG_STAGING_AREA
            }
        }