Exemple #1
0
 public CloseTask(CloseCallbackType callback)
 {
     _callback = callback;
 }
Exemple #2
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();
        }