00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <Cntm/Synchro/MainSynchroSpace.h>
00015 #include <Cntm/Synchro/LoopInNoMainThreadException.h>
00016 #include <Cntm/Synchro/NoReentrantModeException.h>
00017
00018
00019
00020 Cntm::MainSynchroSpace::Implement::Implement():
00021 instance(NULL), stopping(false), runned(false)
00022 {
00023 if (!SynchroSpace::SetMainSynchroSpaceFactory(this))
00024 throw IllegalStateException("Cntm::MainSynchroSpace::Begin", "Попытка повторного создания главного синхропространства");
00025 holdInstance = SynchroSpace::Main();
00026 }
00027
00028 Cntm::SynchroSpace::Ptr Cntm::MainSynchroSpace::Implement::QueryMainInstance()
00029 {
00030
00031 SynchroSpace::Ptr res = holdInstance;
00032 if (res) return res;
00033
00034
00035
00036 boost::recursive_mutex::scoped_lock lock(instanceMutex);
00037 res.SetPointer(instance);
00038 if (!res)
00039 {
00040 res = new MainSynchroSpace();
00041 instance = res.Pointer();
00042 }
00043 return res;
00044 }
00045
00046 void Cntm::MainSynchroSpace::Implement::Start()
00047 {
00048 DoEnter();
00049 }
00050
00051 void Cntm::MainSynchroSpace::Implement::Run()
00052 {
00053
00054 if (!MainSynchroSpace::IsMainThread())
00055 throw LoopInNoMainThreadException("Cntm::MainSynchroSpace::Run", "Метод Cntm::MainSynchroSpace::Run должен вызываться из главного потока");
00056
00057 if (runned)
00058 throw NoReentrantModeException("Cntm::MainSynchroSpace::Run", "Cntm::MainSynchroSpace не допускает реентерабельный вход");
00059
00060 DoLeave();
00061
00062 runned = true;
00063
00064
00065 do
00066 {
00067 ProcessQueue();
00068 }
00069 while (!stopping);
00070
00071 stopping = false;
00072 runned = false;
00073
00074 DoEnter();
00075 }
00076
00077 void Cntm::MainSynchroSpace::Implement::Finish()
00078 {
00079
00080 if (!MainSynchroSpace::IsMainThread())
00081 throw LoopInNoMainThreadException("Cntm::MainSynchroSpace::End", "Метод Cntm::MainSynchroSpace::End должен вызываться из главного потока");
00082
00083 DoLeave();
00084
00085 holdInstance.SetNull();
00086
00087
00088 while (instance)
00089 ProcessQueue();
00090 }
00091
00092 void Cntm::MainSynchroSpace::Implement::Stop()
00093 {
00094 stopping = true;
00095 signalFlag.Set();
00096 }
00097
00098 void Cntm::MainSynchroSpace::Implement::MainInstanceDeleted(MainSynchroSpace* Inst)
00099 {
00100
00101
00102
00103 boost::recursive_mutex::scoped_lock lock(instanceMutex);
00104 if (instance == Inst)
00105 {
00106 instance = NULL;
00107 signalFlag.Set();
00108 }
00109 }
00110
00111 void Cntm::MainSynchroSpace::Implement::ProcessQueue()
00112 {
00113 signalFlag.Wait(true, 0);
00114 DoEnter();
00115 taskQueue.Exec();
00116 DoLeave();
00117 }
00118
00119
00120
00121
00122 Cntm::MainSynchroSpace::Implement* Cntm::MainSynchroSpace::implement;
00123
00124 void Cntm::MainSynchroSpace::Begin()
00125 {
00126 implement = new Implement;
00127 implement->Start();
00128 }