MainSynchroSpace.cpp

См. документацию.
00001 /*
00002  * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события
00003  * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru
00004  * _______________________________________________________________________________
00005  * Разрешено свободное использование, копирование, распространение, изменение
00006  * (изменение сведений об авторских правах запрещено). Запрещена продажа и
00007  * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об
00008  * авторских правах на программу (или сведениях о программе, об авторах,
00009  * использованных средствах разработки и т.д.) должна быть указана информация
00010  * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е.
00011  * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора.
00012  */
00013 
00014 #include <Cntm/Synchro/MainSynchroSpace.h>
00015 #include <Cntm/Synchro/LoopInNoMainThreadException.h>
00016 #include <Cntm/Synchro/NoReentrantModeException.h>
00017 
00018 // Implement //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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(); // Перед запуском цикла выходим из синхропространства (вошли в Begin'е).
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(); // Перед запуском цикла выходим из синхропространства (вошли в Run'е).
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 // QTMainSynchroSpace /////////////////////////////////////////////////////////////////////////////////////////////////////////
00121 
00122 Cntm::MainSynchroSpace::Implement* Cntm::MainSynchroSpace::implement;
00123 
00124 void Cntm::MainSynchroSpace::Begin()
00125 {
00126         implement = new Implement;
00127         implement->Start();
00128 }

SourceForge.net Logo
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой  doxygen 1.5.3