FutureIsReady() public static method

public static FutureIsReady ( FutureHandle futureHandle ) : bool
futureHandle FutureHandle
return bool
コード例 #1
0
        internal FdbFutureArray(FutureHandle[] handles, Func <FutureHandle, T> selector, CancellationToken ct)
        {
            Contract.Requires(handles != null && selector != null);

            m_handles        = handles;
            m_resultSelector = selector;

            bool abortAllHandles = false;

            try
            {
                if (ct.IsCancellationRequested)
                {                 // already cancelled, we must abort everything
                    SetFlag(FdbFuture.Flags.COMPLETED);
                    abortAllHandles  = true;
                    m_resultSelector = null;
                    this.TrySetCanceled();
                    return;
                }

                // add this instance to the list of pending futures
                var prm = RegisterCallback(this);

                foreach (var handle in handles)
                {
                    if (FdbNative.FutureIsReady(handle))
                    {                     // this handle is already done
                        continue;
                    }

                    Interlocked.Increment(ref m_pending);

                    // register the callback handler
                    var err = FdbNative.FutureSetCallback(handle, CallbackHandler, prm);
                    if (Fdb.Failed(err))
                    {                     // uhoh
                        Debug.WriteLine("Failed to set callback for Future<" + typeof(T).Name + "> 0x" + handle.Handle.ToString("x") + " !!!");
                        throw Fdb.MapToException(err) !;
                    }
                }

                // allow the callbacks to handle completion
                TrySetFlag(FdbFuture.Flags.READY);

                if (Volatile.Read(ref m_pending) == 0)
                {                 // all callbacks have already fired (or all handles were already completed)
                    UnregisterCallback(this);
                    HandleCompletion();
                    m_resultSelector = null;
                    abortAllHandles  = true;
                    SetFlag(FdbFuture.Flags.COMPLETED);
                }
                else if (ct.CanBeCanceled)
                {                 // register for cancellation (if needed)
                    RegisterForCancellation(ct);
                }
            }
            catch
            {
                // this is bad news, since we are in the constructor, we need to clear everything
                SetFlag(FdbFuture.Flags.DISPOSED);

                UnregisterCancellationRegistration();

                UnregisterCallback(this);

                abortAllHandles = true;

                // this is technically not needed, but just to be safe...
                this.TrySetCanceled();

                throw;
            }
            finally
            {
                if (abortAllHandles)
                {
                    CloseHandles(handles);
                }
            }
            GC.KeepAlive(this);
        }
コード例 #2
0
        internal FdbFutureSingle([NotNull] FutureHandle handle, [NotNull] Func <FutureHandle, T> selector, CancellationToken ct)
        {
            Contract.NotNull(handle, nameof(handle));
            Contract.NotNull(selector, nameof(selector));

            m_handle         = handle;
            m_resultSelector = selector;

            try
            {
                if (handle.IsInvalid)
                {                 // it's dead, Jim !
                    SetFlag(FdbFuture.Flags.COMPLETED);
                    m_resultSelector = null;
                    return;
                }

                if (FdbNative.FutureIsReady(handle))
                {                 // either got a value or an error
#if DEBUG_FUTURES
                    Debug.WriteLine("Future<" + typeof(T).Name + "> 0x" + handle.Handle.ToString("x") + " was already ready");
#endif
                    HandleCompletion(fromCallback: false);
#if DEBUG_FUTURES
                    Debug.WriteLine("Future<" + typeof(T).Name + "> 0x" + handle.Handle.ToString("x") + " completed inline");
#endif
                    return;
                }

                // register for cancellation (if needed)
                if (ct.CanBeCanceled)
                {
                    if (ct.IsCancellationRequested)
                    {                     // we have already been cancelled
#if DEBUG_FUTURES
                        Debug.WriteLine("Future<" + typeof(T).Name + "> 0x" + handle.Handle.ToString("x") + " will complete later");
#endif

                        // Abort the future and simulate a Canceled task
                        SetFlag(FdbFuture.Flags.COMPLETED);
                        // note: we don't need to call fdb_future_cancel because fdb_future_destroy will take care of everything
                        handle.Dispose();
                        // also, don't keep a reference on the callback because it won't be needed
                        m_resultSelector = null;
                        this.TrySetCanceled();
                        return;
                    }

                    // token still active
                    RegisterForCancellation(ct);
                }

#if DEBUG_FUTURES
                Debug.WriteLine("Future<" + typeof(T).Name + "> 0x" + handle.Handle.ToString("x") + " will complete later");
#endif

                TrySetFlag(FdbFuture.Flags.READY);

                // add this instance to the list of pending futures
                var prm = RegisterCallback(this);

                // register the callback handler
                var err = FdbNative.FutureSetCallback(handle, CallbackHandler, prm);
                if (Fdb.Failed(err))
                {                 // uhoh
#if DEBUG_FUTURES
                    Debug.WriteLine("Failed to set callback for Future<" + typeof(T).Name + "> 0x" + handle.Handle.ToString("x") + " !!!");
#endif
                    throw Fdb.MapToException(err);
                }
            }
            catch
            {
                // this is bad news, since we are in the constructor, we need to clear everything
                SetFlag(FdbFuture.Flags.DISPOSED);
                UnregisterCancellationRegistration();
                UnregisterCallback(this);

                // kill the future handle
                m_handle.Dispose();

                // this is technically not needed, but just to be safe...
                this.TrySetCanceled();

                throw;
            }
            GC.KeepAlive(this);
        }