//! \brief method for add a pipeline service public System.Boolean AddService(PipelineService ServiceItem) { if (!Available) { return(false); } if (null == ServiceItem) { return(false); } lock (((ICollection)m_WaitingServiceQueue).SyncRoot) { try { //! add service to queue m_WaitingServiceQueue.Enqueue(ServiceItem); } catch (Exception) { //System.Console.WriteLine(e.ToString()); return(false); } } //! auto star if (AutoStart) { //! auto start pipeline PipelineOpen = true; } return(true); }
//! \brief pipeline background task private void PipelineBackgroundTask() { PipelineService ServiceItem = null; Queue <PipelineService> queueFirstStageQueue = null; //! \name finit state machine A //! @{ System.Boolean FSM_GET_SERVICE_FROM_WAITING_QUEUE = true; System.Boolean FSM_INITIALIZE_NEW_SERVICE = false; //! @} System.Int32 nCurrentStageIndex = 0; //! \name finit state machine B //! @{ Boolean FSM_CHECK_CURRENT_STAGE_QUEUE = true; Boolean FSM_PEEK_SERVICE_FROM_CURRENT_STAGE_QUEUE = false; Boolean FSM_WAIT_SERVICE_RESULT = false; //! @} System.Object tObject = new object(); lock (tObject) { //! small super loop do { //! try to peek a available service if (FSM_GET_SERVICE_FROM_WAITING_QUEUE) { lock (((ICollection)m_WaitingServiceQueue).SyncRoot) { if (m_WaitingServiceQueue.Count != 0) { try { //! peek a new service ServiceItem = m_WaitingServiceQueue.Peek(); } catch (Exception) { } if (null == ServiceItem) { //! drop this service m_WaitingServiceQueue.Dequeue(); } else if (!ServiceItem.Available) { //! drop this service m_WaitingServiceQueue.Dequeue(); } else if (ServiceItem.Stage > 0) { //! drop this service m_WaitingServiceQueue.Dequeue(); //! raising event ServiceItem.OnPipelineServiceException(); } else { FSM_GET_SERVICE_FROM_WAITING_QUEUE = false; FSM_INITIALIZE_NEW_SERVICE = true; } } } } //! initialize this service item and add it to first stage queue if (FSM_INITIALIZE_NEW_SERVICE) { if (0 == m_DynamicStageList.Count) { queueFirstStageQueue = new Queue <PipelineService>(); //! create first stage m_DynamicStageList.Add(queueFirstStageQueue); } //! add this service to first stage queueFirstStageQueue.Enqueue(ServiceItem); lock (((ICollection)m_WaitingServiceQueue).SyncRoot) { //! drop this service m_WaitingServiceQueue.Dequeue(); } //! reset this stage machine FSM_INITIALIZE_NEW_SERVICE = false; FSM_GET_SERVICE_FROM_WAITING_QUEUE = true; } //! check current stage queue if (FSM_CHECK_CURRENT_STAGE_QUEUE) { if (m_RequestStop) { //! request stop m_RequestStop = false; break; } if (0 != m_DynamicStageList.Count) { if (m_DynamicStageList.Count > nCurrentStageIndex) { if (m_DynamicStageList[nCurrentStageIndex].Count > 0) { //! current stage queue is not empty FSM_CHECK_CURRENT_STAGE_QUEUE = false; FSM_PEEK_SERVICE_FROM_CURRENT_STAGE_QUEUE = true; } else { //! current stage queue is empty if (m_DynamicStageList.Count == nCurrentStageIndex + 1) { //! current stage is the top stage, release it m_DynamicStageList.Remove(m_DynamicStageList[nCurrentStageIndex]); } if (nCurrentStageIndex > 0) { nCurrentStageIndex--; } else if (m_DynamicStageList.Count > 0) { nCurrentStageIndex = m_DynamicStageList.Count - 1; } } } else if (0 != nCurrentStageIndex) { nCurrentStageIndex--; } } } //! peek service item from current stage queue if (FSM_PEEK_SERVICE_FROM_CURRENT_STAGE_QUEUE) { PipelineService tService = m_DynamicStageList[nCurrentStageIndex].Peek(); if (null == tService) { //! illegal service m_DynamicStageList[nCurrentStageIndex].Dequeue(); //! try to get next service FSM_PEEK_SERVICE_FROM_CURRENT_STAGE_QUEUE = false; FSM_CHECK_CURRENT_STAGE_QUEUE = true; } else if (!tService.Available) { //! illegal service m_DynamicStageList[nCurrentStageIndex].Dequeue(); //! try to get next service FSM_PEEK_SERVICE_FROM_CURRENT_STAGE_QUEUE = false; FSM_CHECK_CURRENT_STAGE_QUEUE = true; } else { m_StageServiceCancelled = false; //tService.InitializeCurrentStage(); tService.PipelineServiceCancelledEvent += new PipelineCoreService.PipelineServiceCancelled(PipelineServiceCancelledEvent); //! get an available service,add this service to pipelinecore if (base.AddService(tService)) { //! add service to pipeline core success FSM_PEEK_SERVICE_FROM_CURRENT_STAGE_QUEUE = false; FSM_WAIT_SERVICE_RESULT = true; tService.CompleteSignal.WaitOne(); } else { tService.PipelineServiceCancelledEvent -= new PipelineCoreService.PipelineServiceCancelled(PipelineServiceCancelledEvent); //! failed to add service m_DynamicStageList[nCurrentStageIndex].Dequeue(); tService.Cancel(); tService.OnServiceCancelled(); //! raising event ServiceItem.OnPipelineServiceException(); //! try to get next service FSM_PEEK_SERVICE_FROM_CURRENT_STAGE_QUEUE = false; FSM_CHECK_CURRENT_STAGE_QUEUE = true; } } } if (FSM_WAIT_SERVICE_RESULT) { //base.PipelineOpen = true; PipelineService tService = m_DynamicStageList[nCurrentStageIndex].Peek(); if (m_StageServiceCancelled) { //! service cancelled, drop it m_DynamicStageList[nCurrentStageIndex].Dequeue(); if (m_DynamicStageList.Count > 0) { nCurrentStageIndex = m_DynamicStageList.Count - 1; } //! reset state machine FSM_WAIT_SERVICE_RESULT = false; FSM_CHECK_CURRENT_STAGE_QUEUE = true; } else if (tService.Complete) { //! complete switch (tService.StageState) { case PIPELINE_STAGE_STATE.STATE_BLOCKED: //! blocked, try previouse stage if (nCurrentStageIndex > 0) { nCurrentStageIndex--; } else { if (m_DynamicStageList.Count > 0) { nCurrentStageIndex = m_DynamicStageList.Count - 1; } } break; case PIPELINE_STAGE_STATE.STATE_COMPLETE: //! complete, raising event m_DynamicStageList[nCurrentStageIndex].Dequeue(); if (m_DynamicStageList.Count > 0) { nCurrentStageIndex = m_DynamicStageList.Count - 1; } break; case PIPELINE_STAGE_STATE.STATE_READY: //! ready for what ? consider it as "next state" case PIPELINE_STAGE_STATE.STATE_NEXT_STATE: m_DynamicStageList[nCurrentStageIndex].Dequeue(); if (tService.Stage > nCurrentStageIndex) { nCurrentStageIndex++; if (m_DynamicStageList.Count <= nCurrentStageIndex) { m_DynamicStageList.Add(new Queue <PipelineService>()); } //! add current service to next stage m_DynamicStageList[nCurrentStageIndex].Enqueue(tService); } else if (tService.Stage == nCurrentStageIndex) { //! consider as complete if (m_DynamicStageList.Count > 0) { nCurrentStageIndex = m_DynamicStageList.Count - 1; } } else { //! exception, raising event tService.OnPipelineServiceException(); if (m_DynamicStageList.Count > 0) { nCurrentStageIndex = m_DynamicStageList.Count - 1; } } break; case PIPELINE_STAGE_STATE.STATE_WORKING: m_DynamicStageList[nCurrentStageIndex].Dequeue(); //! should not meet this situation, raising event tService.OnPipelineServiceException(); if (m_DynamicStageList.Count > 0) { nCurrentStageIndex = m_DynamicStageList.Count - 1; } break; } //! reset state machine FSM_WAIT_SERVICE_RESULT = false; FSM_CHECK_CURRENT_STAGE_QUEUE = true; } } if (0 == m_DynamicStageList.Count) { lock (((ICollection)m_WaitingServiceQueue).SyncRoot) { if (0 == m_WaitingServiceQueue.Count) { //! all service is complete break; } } } //Thread.Sleep(1); }while (true); } //! raising event OnPipelineStateReport(PIPELINE_STATE.PIPELINE_STOPPED); m_PipelineThread = null; }