Пример #1
0
        // 実行するセッションとタスクは型の整合が取れている必要があるので、派生クラスで型を限定したインターフェースを公開する
        protected IEnumerator Execute(Gs2SessionTask gs2SessionTask)
        {
            var isNowClosed = false;

            using (var scopedLock = new NonreentrantLock.ScopedLock(_lock))
            {
                if (_state == State.Available)
                {
                    gs2SessionTask.Gs2SessionTaskId = _gs2SessionTaskIdGenerator.Issue();
                    _gs2SessionTaskList.Add(gs2SessionTask);

                    var current = gs2SessionTask.Execute(this);

                    using (var unlockScope = new NonreentrantLock.ScopedUnlock(_lock))
                    {
                        yield return(current);
                    }

                    while (!gs2SessionTask.IsCompleted)
                    {
                        using (var unlockScope = new NonreentrantLock.ScopedUnlock(_lock))
                        {
                            yield return(null);
                        }
                    }

                    _gs2SessionTaskList.Remove(gs2SessionTask);

                    if (_gs2SessionTaskList.Count == 0 && _state == State.Closed)
                    {
                        _state = State.Idle;

                        isNowClosed = true;

                        CompleteCloseTasks();
                    }
                    ;
                }
                else
                {
                    gs2SessionTask.Complete(new Gs2Response(new SessionNotOpenException("The session is not opened.")));
                }
            }

            gs2SessionTask.InvokeCallback();

            if (isNowClosed)
            {
                OnClose?.Invoke();
            }
        }
Пример #2
0
        /// <summary>
        ///  セッションのオープン操作をおこなうコルーチンを返却します。<br />
        ///  <br />
        ///  コルーチンの完了時にはコールバックが返っていることが保証されます。<br />
        ///  ただし、オープン状態のセッションは外部要因によって予期せずクローズされることがあるため、オープン操作成功のコールバックが返った時点でも、セッションが確実にオープン状態であることは保証されません。<br />
        ///  <br />
        ///  セッションのオープン操作は、オープン途中やすでにオープン状態のセッションに対しても重ねておこなうことができます。<br />
        /// </summary>
        ///
        /// <returns>IEnumerator</returns>
        /// <param name="callback">コールバックハンドラ</param>
        public IEnumerator Open(OpenCallbackType callback)
        {
            var openTask = new OpenTask(callback);

            using (var scopedLock = new NonreentrantLock.ScopedLock(_lock))
            {
                if (_state == State.Available)
                {
                    openTask.Complete(new AsyncResult <OpenResult>(new OpenResult(), null));
                }
                else
                {
                    _openTaskList.Add(openTask);

                    while (true)
                    {
                        if (openTask.IsCompleted)
                        {
                            break;
                        }

                        IEnumerator current = null;

                        if (_state == State.Idle)
                        {
                            _state = State.Opening;
                            if (Credential is BasicGs2Credential)
                            {
                                current = OpenImpl();
                            }
                            else if (Credential is ProjectTokenGs2Credential)
                            {
                                using (var scopedUnlock = new NonreentrantLock.ScopedUnlock(_lock))
                                {
                                    OpenCallback(Credential.ProjectToken, null);
                                }
                            }
                        }

                        using (var scopedUnlock = new NonreentrantLock.ScopedUnlock(_lock))
                        {
                            yield return(current);
                        }
                    }
                }
            }

            openTask.InvokeCallback();
        }
Пример #3
0
        /// <summary>
        ///  セッションのクローズ操作をおこなうコルーチンを返却します。<br />
        ///  <br />
        ///  コルーチンの完了時にはコールバックが返っていることが保証されます。<br />
        ///  また、セッションのクローズ操作は必ず成功し、コールバックが返った時点でセッションがクローズド状態であり、そのセッションを利用していたすべての API の実行が完了していることが保証されます。<br />
        ///  ただし、複数のクローズ操作を同時に実行し、そのコールバックでオープン操作を開始した場合はその限りではありません。<br />
        ///  <br />
        ///  セッションに対して複数回のオープン操作をおこなっていた場合であっても、1回のクローズ操作でクローズド状態へ移行します。<br />
        /// </summary>
        ///
        /// <returns>IEnumerator</returns>
        /// <param name="callback">コールバックハンドラ</param>
        public IEnumerator Close(CloseCallbackType callback)
        {
            var closeTask = new CloseTask(callback);

            var isNowClosed = false;

            using (var scopedLock = new NonreentrantLock.ScopedLock(_lock))
            {
                if (_state == State.Idle)
                {
                    closeTask.Complete();
                }
                else
                {
                    _closeTaskList.Add(closeTask);

                    while (true)
                    {
                        if (closeTask.IsCompleted)
                        {
                            break;
                        }

                        IEnumerator current = null;

                        switch (_state)
                        {
                        case State.Opening:
                            _state  = State.CancellingOpen;
                            current = CancelOpenImpl();
                            break;

                        case State.Available:
                            ProjectToken = null;
                            if (_gs2SessionTaskList.Count == 0)
                            {
                                _state  = State.Closing;
                                current = CloseImpl();
                            }
                            else
                            {
                                _state = State.CancellingTasks;
                                foreach (var gs2SessionTask in _gs2SessionTaskList)
                                {
                                    gs2SessionTask.Cancel();
                                }
                            }
                            break;

                        case State.CancellingTasks:
                            if (_gs2SessionTaskList.Count == 0)
                            {
                                _state  = State.Closing;
                                current = CloseImpl();
                            }
                            break;

                        case State.Closed:
                            if (_gs2SessionTaskList.Count == 0)
                            {
                                _state = State.Idle;

                                isNowClosed = true;

                                CompleteCloseTasks();

                                continue;
                            }
                            break;

                        case State.Idle:
                        case State.CancellingOpen:
                        case State.Closing:
                            break;
                        }

                        using (var unlockScope = new NonreentrantLock.ScopedUnlock(_lock))
                        {
                            yield return(current);
                        }
                    }
                }
            }

            if (isNowClosed)
            {
                OnClose?.Invoke();
            }

            closeTask.InvokeCallback();
        }