AsyncProc.h

См. документацию.
00001 /*
00002  * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события
00003  * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru
00004  * _______________________________________________________________________________
00005  * Разрешено свободное использование, копирование, распространение, изменение
00006  * (изменение сведений об авторских правах запрещено). Запрещена продажа и 
00007  * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об
00008  * авторских правах на программу (или сведениях о программе, об авторах, 
00009  * использованных средствах разработки и т.д.) должна быть указана информация
00010  * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е.
00011  * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора.
00012  */ 
00013 
00014 #ifndef CNTM_ASYNCPROC_H
00015 #define CNTM_ASYNCPROC_H
00016 #include <Cntm/Concurrency/ExecutionUnit.h>
00017 #include <Cntm/Synchro/SynchroSpace.h>
00018 #include <Cntm/Synchro/SynchroObject.h>
00019 #include <Cntm/AsyncProc/Internal/ThreadProcFunctor.h>
00020 #include <Cntm/AsyncProc/Internal/DeferProcFunctor.h>
00021 #include <Cntm/AsyncProc/Internal/DirectProcFunctor.h>
00022 #include <Cntm/AsyncProc/AsyncProcTerminatingSignal.h>
00023 #include <Cntm/AsyncProc/BasicAsyncProc.h>
00024 
00025 namespace Cntm
00026 {
00027 
00028         /**
00029          * Класс асинхронной процедуры. Асинхронная процедура - это такая процедура, завершение 
00030          * которой может произойти после начала операции, следующей за вызовом этой процедуры. В 
00031          * частности, через асинхронные процедуры можно запускать потоки.
00032          * 
00033          * Асинхронная процедура является единицей выполнения и наследует класс Cntm::ExecutionUnit, 
00034          * который предоставляет средства для останова единиц выполнения и асинхронных процедур в 
00035          * частности.
00036          * 
00037          * Создание асинхронной процедуры очень похоже на запуск обычной процедуры. При создании 
00038          * указывается объект, его метод, который будет выполнен асинхронно, дополнительные параметры 
00039          * и аргументы, которые будут переданы методу при его вызове. Рассмотрим пример создания:
00040          * \code
00041          * AsyncProc::Thread(this, &Class1::AsyncMethod333)("text", 54);
00042          * \endcode
00043          * Метод Thread()() - один из статических методов создания асинхронной процедуры, он будет 
00044          * рассмотрен ниже. Выражение AsyncProc::Thread(this, &Class1::AsyncMethod333), по сути, 
00045          * является идентификатором асинхронной процедуры, а выражение ("text", 54) означает факт 
00046          * запуска асинхронной процедуры. Поэтому метод Thread и ему подобные будут обозначаться так: 
00047          * Thread()(). При указании аргументов производится проверка типов указанных значений и типов 
00048          * аргументов метода, выполняемого асинхронно.
00049          * 
00050          * По способу запуска асинхронные процедуры делятся на запущенные при создании и с 
00051          * отсроченным запуском. В первом случае указанный при создании метод будет вызван сразу, 
00052          * как только это будет возможно, а во втором - только после явного запуска асинхронной 
00053          * процедуры. Методы создания отсроченных процедур имеют префиксы Suspend... .
00054          * 
00055          * По способу запуска указанного при создании метода асинхронные процедуры делятся на 
00056          * потоковые, отложенные и прямые. Рассмотрим каждый из них.
00057          * 
00058          * Потоковые асинхронные процедуры. Создаются статическими методами Thread()() и 
00059          * SuspendThread()(). В них создается новый поток, в котором и будет вызван указанный 
00060          * метод. При создании потоковой асинхронной процедуры м.б. указан приоритет создаваемого 
00061          * потока. Пример:
00062          * \code
00063          * class Class1: public RefBase
00064          * {
00065          *      void ThreadMethod1(string s, int e) { ... } // Метод, который будет вызван в другом потоке.
00066          * 
00067          *      void Start()
00068          *      {
00069          *              // Вызов метода в новом потоке и передача ему аргументов - числа и строки.
00070          *              AsyncProc::Thread(this, &Class1::ThreadMethod1)("text", 54);
00071          *      }
00072          * };
00073          * \endcode
00074          * 
00075          * Отложенные асинхронные процедуры. Создаются статическими методами Defer()() и 
00076          * SuspendDefer()(). Об отложенном способе вызова подробно рассказывается в документации 
00077          * по классу Cntm::DeferEvent, т.к. выполнение отложенной асинхронной процедуры имеет много 
00078          * общего с генерацией отложенного события. Вкратце, отложенность процедуры означает, что 
00079          * указанный метод будет вызван не в момент запуска, а при выполнении определенных условий. 
00080          * Отложенная асинхронная процедура тесно связана с понятием синхропространства 
00081          * (ознакомтесь с документацие по классу Cntm::SynchroSpace). Асинхронный метод, указанный 
00082          * при создании, выполняется внутри определенного синхропространства (которое тоже 
00083          * указывается тем или иным способом при создании асинхронной процедуры), вход в которое 
00084          * произведен в реентерабельном режиме. Если запуск процедуры произведен в том 
00085          * синхропространстве, которое указано при создании, то гарантируется, что метод будет запущен 
00086          * только после выхода из этого синхропространства. При создании отложенной асинхронной 
00087          * процедуры требуется указание синхропространства. Если оно не указано явно, то используется 
00088          * главное синхропространство. Пример:
00089          * \code
00090          * class Class2: public RefBase
00091          * {
00092          *      void DeferMethod1(const string& s, double e) { ... } // Метод, который будет вызван в другом потоке.
00093          * 
00094          *      void Start()
00095          *      {
00096          *              // Создание отложенной (defer) отсроченной (suspend) процедуры и передача ей 
00097          *              // строки и числа, которые будут переданы методу DeferMethod1() при его вызове.
00098          *              AsyncProc::SuspendDefer(this, &Class2::DeferMethod1)("text", 54);
00099          *      } 
00100          * };
00101          * \endcode
00102          * 
00103          * Прямые асинхронные процедуры. Создаются статическими методами Direct()() и 
00104          * SuspendDirect()(). По сути представляют вызов указанного при создании метода в момент 
00105          * запуска асинхронной процедуры. Прямая процедура, созданная методом Direct()(), вообще 
00106          * ничем не отличается от вызова указанного при создании метода, поэтому, ни какого интереса 
00107          * не представляет и добавлена только для функциональной полноты. Об использовании метода 
00108          * SuspendDirect()(), как и других отсроченных меодов будет рассказано ниже.
00109          * 
00110          * Взаимодействие с созданной асинхронной процедурой, как и с единицами выполнения 
00111          * (Cntm::ExecutionUnit) вообще,  осуществляется через хэндл процедуры (класс 
00112          * Cntm::AsyncProcHandle). Хэндл не является шаблонным классом, и никак не зависит от 
00113          * сигнатуры указанного при создании асинхронной процедуры метода. Через хэндл можно 
00114          * сообщить методу процедуры об останове. Асинхронный метод или методы, им запущенные, 
00115          * могут узнать об останове через методы Terminated() и CheckTerminating(), унаследованные 
00116          * им от класса Cntm::ExecutionUnit(). Хэндл предоставляет следующие возможности: узнать 
00117          * тип процедуры, был ли произведен запуск (для отсроченных процедур, обычные запускаются 
00118          * при создании), была ли завершена процедура и если была, то успешно или нет. Также хэндлы 
00119          * позволяют запустить отсроченную асинхронную процедуру, дождаться завершения асинхронной 
00120          * процедуры, установить отсроченную асинхронную процедуру, которая будет вызвана после 
00121          * завершения данной процедуры.
00122          *  
00123          * Асинхронный метод может возвращать значение результата. Это значение можно узнать с 
00124          * помощью класса результата асинхронной процедуры - Cntm::AsyncProcResult. Данный класс 
00125          * является шаблоном, параметром которого является тип возвращаемого значения. Класс 
00126          * Cntm::AsyncProcResult наследует Cntm::AsyncProcHandle. Все методы создания асинхронных 
00127          * процедур возвращают именно объект результата. Значение результата можно получить только 
00128          * после завершения асинхронной процедуры.
00129          * 
00130          * По своей сути хэндлы и результаты являются ссылочным указателями на объект асинхронной 
00131          * процедуры. Однако отсутствие хэндлов ни как не влияет на выполняющуюся процедуру, но 
00132          * если хэндлов, связанных с отсроченной незапущенной процедурой, не осталось, то эта 
00133          * процедура уже никогда не сможет быть запущена. Наличие хэндлов, связанных с процедурой, 
00134          * влияет только на значение результата асинхронного метода (подробнее об этом - ниже).
00135          * 
00136          * Рассмотрим пример асинхронных процедур.
00137          * \code
00138          * class Class3
00139          * {
00140          *      string Work()
00141          *      {
00142          *              sleep(1);
00143          *              ...
00144          *              return "text";
00145          *      }
00146          * 
00147          *      void Finish(AsyncProcResult<string> res)
00148          *      {
00149          *              cout << res << endl;
00150          *      }
00151          * 
00152          *      void Start()
00153          *      {
00154          *              AsyncProcResult<string> res = AsyncProc::SuspendThread(this, &Class3::Work)();
00155          *              AsyncProctHandle hdl = AsyncProc::SuspendThread(this, &Class3::Finish)(res);
00156          *              res.SetFinishProc(hdl);
00157          *              cout << "before start" << endl;
00158          *              res.Start();
00159          *              hdl.Wait();
00160          *              cout << "after finish" << endl;
00161          *      }
00162          * };
00163          * 
00164          * Вывод на консоль:
00165          * before start
00166          * text
00167          * after finish
00168          * \endcode
00169          * 
00170          * Разберем пример. В первой строке Start() создается отсроченная потоковая асинхронная 
00171          * процедура Work(), выполняющая некоторую работу и возвращающая строку. При создании 
00172          * нам возвращается объект результата res, через который мы можем узнать значение, которое 
00173          * вернул метод Work(). Во второй строке Start() создается обработчик завершения метода 
00174          * Work(), которому передается объект результата метода Work(). В третьей строке происходит 
00175          * связывание обработки завершения процедуры Work() с процедурой Finish(). В пятой строке 
00176          * происходит запуск процедуры Work(), которая после завершения запустит процедуру Finish(). 
00177          * Т.к. Work() закончил работу, то Finish() может получить значение результата (кстати, 
00178          * AsyncProcResult имеет оператор преобразования к типу, указанному в шаблоне, поэтому 
00179          * выражение cout << res допустимо). В шестой строке производится ожидание завершения этой 
00180          * цепочки методов.
00181          * 
00182          * Все 12 методов создания асинхронных процедур содержат параметры Object и Method. 
00183          * Object - это объект, чей метод Method будет асинхронно вызван. Object может задаваться как 
00184          * ссылочный указатель, как обычный указатель или как обычная ссылка, Method задается как 
00185          * указатель на метод класса, к которому принадлежит Object. 
00186          * 
00187          * Дополнительные параметры, указываемые при создании асинхронных процедур.
00188          * При создании потоков методами Thread()() и SuspendThread()() можно указать его приоритет 
00189          * (параметр с именем Priority) (см. перечисление Cntm::BasicAsyncProc::ThreadPriority). При 
00190          * создании отложенных процедур методами Defer()() и SuspendDefer()() требуется указание 
00191          * синхропространства (параметр Space), в котором будет выполняться асинхронный метод. 
00192          * Если синхропространство явно не указано, а переданный объект, метод которого будет 
00193          * выполнен, является синхрообъектом, то будет использовано синхропространство, к которому 
00194          * принадлежит синхрообъект, если передан не синхрообъект, то будет использовано главное 
00195          * синхропространство. Последний параметр всех 12 методов (называется HoldRef) имеет значение, 
00196          * только если переданный объект - с подсчетом ссылок. Этот параметр влияет на хранение ссылки 
00197          * на объект, чей метод будет выполняться. Если параметр устанвлен в true, то на время 
00198          * выполнения метода ссылка на объект будет сохранена (это поведение по умолчанию), если в 
00199          * false, то нет (это поведение следует использовать с большой осторожностью, т.к. может 
00200          * привести к вызову метода несуществующего объекта).
00201          *  
00202          * Применение асинхронных процедур.
00203          * 
00204          * Потоковые процедуры Thread()() используются для создания потоков с удобной передачей 
00205          * аргументов любых типов и возможностью получения результата. Отложенные процедуры 
00206          * Defer()() используются для синхронизированного выполнения методов объектов, т.к. 
00207          * гарантируют вызов указанного метода внутри синхропространства, например, некий поток 
00208          * может синхронизированно вызвать произвольный метод (для главного синхропространства 
00209          * это означает, что метод будет вызван в главном цикле обработки сообщений, в главном потоке) 
00210          * и либо продолжить работу либо дождаться завершения. Применение отсроченных асинхронных 
00211          * процедур. Они создаются методами Suspend...()(). Отсроченные процедуры можно рассматривать 
00212          * как объекты, инкапсулирующие вызов метода с уже подготовленными аргументами. Такие 
00213          * объекты вызовов можно передавать в качестве параметров (напомним, что любой объект 
00214          * вызова характеризуется нешаблонным хэндлом или результатом, зависящим только от типа 
00215          * возвращаемого значения), запуская или не запуская инкапсулированные вызовы при 
00216          * определенных условиях. Эта методика используется и в самих асинхронных процедурах для 
00217          * задания метода, который будет вызван после завершения выполнения асинхронной процедуры. 
00218          * В отличии от обычной прямой процедуры отсроченная прямая процедура SuspendDirect()() 
00219          * является логичной, полезной и вполне асинхронной.
00220          * 
00221          * Особенности.
00222          * 
00223          * При создании асинхронной процедуры указываются аргументы, которые впоследствии будут 
00224          * переданы асинхронному методу при его вызове. Для этого производится копирование значений 
00225          * аргументов во внутренний буфер с помощью конструкторов копирования. Копии аргументов будут 
00226          * уничтожены сразу после завершения работы асинхронного метода. Асинхронная процедура хранит 
00227          * копию результата, который вернул асинхронный метод. Значение результата создается с помощью 
00228          * конструктора копирования после завершения асинхронного метода. Значение результата будет 
00229          * уничтожено вместе с уничтожением объекта асинхронной процедуры, т.е. когда не останется ни 
00230          * одного хэндла, связанного с процедурой. Если процедура хранит ссылку на объект, то эта 
00231          * ссылка будет уничтожена сразу после завершения работы асинхронного метода. Если для 
00232          * отсроченной незапущенной процедуры были утеряны все хэндлы, то происходит уничтожение 
00233          * объекта процедуры вместе с копиями аргументов и ссылкой на объект (если она имелась).
00234          * 
00235          * Принудительный останов асинхронных процедур. Если принудительный останов отсроченной 
00236          * процедуры (метод Cntm::AsyncProcHandle::Terminate()) произведен до ее запуска (метод 
00237          * Cntm::AsyncProcHandle::Start()), то производится ее завершение (устанавливается флаг 
00238          * завершения, запускается обработчик завершения и т.д.), а указанный при создании метод 
00239          * объекта никогда вызван не будет. При принудительном останове запущенной процедуры 
00240          * гарантируется, что вызов указанного при создании метода объекта будет произведен (конечно, 
00241          * если не было ошибок при запуске).
00242          * 
00243          * Данный класс обеспечивает многопоточность.
00244          * @author Овсеевич Р.
00245          * \ingroup AsyncProc
00246          */
00247         class AsyncProc: public ExecutionUnit, public BasicAsyncProc
00248         {
00249         public:
00250 
00251                 /**
00252                  * Создать и запустить асинхронную потоковую процедуру. Создается новый поток и в нем производится запуск метода Method объекта Object.
00253                  * 
00254                  * Формат вызова: Thread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00255                  * 
00256                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00257                  * 
00258                  * Исключения:
00259                  * NullArgException - не указан объект обработчик (Object равен NULL).
00260                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00261                  * SystemException - системная ошибка при создании нового потока.
00262                  * @param Object - объект-обработчик. Задается обычным указателем.
00263                  * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке.
00264                  * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority).
00265                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00266                  */
00267                 template < typename MethodSignatureT >
00268                 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Thread(
00269                         typename SignatureInfo < MethodSignatureT > ::ClassType* Object,
00270                         MethodSignatureT Method,
00271                         ThreadPriority Priority = tpNormal,
00272                         bool HoldRef = true)
00273                 {
00274                         return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00275                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, false);
00276                 }
00277                 
00278                 /**
00279                  * Создать и запустить асинхронную потоковую процедуру. Создается новый поток и в нем производится запуск метода Method объекта Object.
00280                  * 
00281                  * Формат вызова: Thread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00282                  * 
00283                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00284                  * 
00285                  * Исключения:
00286                  * NullArgException - не указан объект обработчик (Object равен NULL).
00287                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00288                  * SystemException - системная ошибка при создании нового потока.
00289                  * @param Object - объект-обработчик. Задается ссылочным указателем.
00290                  * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке.
00291                  * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority).
00292                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00293                  */
00294                 template < typename MethodSignatureT >
00295                 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Thread(
00296                         RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 
00297                         MethodSignatureT Method, 
00298                         ThreadPriority Priority = tpNormal,
00299                         bool HoldRef = true)
00300                 {
00301                         return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00302                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, false);
00303                 }       
00304 
00305                 /**
00306                  * Создать асинхронную потоковую процедуру без ее запуска. Запуск можно произвести через хэндл или результат.
00307                  * 
00308                  * Формат вызова: SuspendThread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00309                  * 
00310                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00311                  * 
00312                  * Исключения:
00313                  * NullArgException - не указан объект обработчик (Object равен NULL).
00314                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00315                  * @param Object - объект-обработчик. Задается обычным указателем.
00316                  * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке.
00317                  * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority).
00318                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00319                  */
00320                 template < typename MethodSignatureT >
00321                 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendThread(
00322                         typename SignatureInfo < MethodSignatureT > ::ClassType* Object,
00323                         MethodSignatureT Method,
00324                         ThreadPriority Priority = tpNormal,
00325                         bool HoldRef = true)
00326                 {
00327                         return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00328                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, true);
00329                 }
00330                 
00331                 /**
00332                  * Создать асинхронную потоковую процедуру без ее запуска. Запуск можно произвести через хэндл или результат.
00333                  * 
00334                  * Формат вызова: SuspendThread(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00335                  * 
00336                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00337                  * 
00338                  * Исключения:
00339                  * NullArgException - не указан объект обработчик (Object равен NULL).
00340                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00341                  * @param Object - объект-обработчик. Задается ссылочным указателем.
00342                  * @param Method - метод объекта Object, который будет вызван асинхронно в другом потоке.
00343                  * @param Priority - приоритет потока, опционально, значение по умолчанию - tpNormal (см. перечисление Cntm::BasicAsyncProc::ThreadPriority).
00344                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00345                  */
00346                 template < typename MethodSignatureT >
00347                 static SpecUtils::ThreadProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendThread(
00348                         RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 
00349                         MethodSignatureT Method, 
00350                         ThreadPriority Priority = tpNormal,
00351                         bool HoldRef = true)
00352                 {
00353                         return SpecUtils::ThreadProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00354                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), Priority, HoldRef, true);
00355                 }       
00356 
00357                 /**
00358                  * Создать и запустить асинхронную отложенную процедуру. Производит синхронизированный запуск метода Method объекта Object в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство.
00359                  * 
00360                  * Формат вызова: Defer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00361                  * 
00362                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00363                  * 
00364                  * Исключения:
00365                  * NullArgException - не указан объект обработчик (Object равен NULL).
00366                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00367                  * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство.
00368                  * @param Object - объект-обработчик. Задается обычным указателем.
00369                  * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве.
00370                  * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство.
00371                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00372                  */
00373                 template < typename MethodSignatureT >
00374                 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Defer(
00375                         typename SignatureInfo < MethodSignatureT > ::ClassType* Object,
00376                         MethodSignatureT Method,
00377                         SynchroSpace::Ptr Space = SynchroSpace::Ptr(),
00378                         bool HoldRef = true)
00379                 {
00380                         return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00381                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object, Space), HoldRef, false);
00382                 }
00383                 
00384                 /**
00385                  * Создать и запустить асинхронную отложенную процедуру. Производит синхронизированный запуск метода Method объекта Object в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство.
00386                  * 
00387                  * Формат вызова: Defer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00388                  * 
00389                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00390                  * 
00391                  * Исключения:
00392                  * NullArgException - не указан объект обработчик (Object равен NULL).
00393                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00394                  * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство.
00395                  * @param Object - объект-обработчик. Задается ссылочным указателем.
00396                  * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве.
00397                  * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство.
00398                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00399                  */
00400                 template < typename MethodSignatureT >
00401                 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Defer(
00402                         RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 
00403                         MethodSignatureT Method, 
00404                         SynchroSpace::Ptr Space = SynchroSpace::Ptr(),
00405                         bool HoldRef = true)
00406                 {
00407                         return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00408                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object.Pointer(), Space), HoldRef, false);
00409                 }       
00410 
00411                 /**
00412                  * Создать асинхронную отсроченную отложенную процедуру. Когда процедура будет запущена, то метод Method объекта Object будет синхронизированно вызван в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство.
00413                  * 
00414                  * Формат вызова: SuspendDefer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00415                  * 
00416                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00417                  * 
00418                  * Исключения:
00419                  * NullArgException - не указан объект обработчик (Object равен NULL).
00420                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00421                  * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство.
00422                  * @param Object - объект-обработчик. Задается обычным указателем.
00423                  * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве.
00424                  * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство.
00425                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00426                  */
00427                 template < typename MethodSignatureT >
00428                 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDefer(
00429                         typename SignatureInfo < MethodSignatureT > ::ClassType* Object,
00430                         MethodSignatureT Method,
00431                         SynchroSpace::Ptr Space = SynchroSpace::Ptr(),
00432                         bool HoldRef = true)
00433                 {
00434                         return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00435                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object, Space), HoldRef, true);
00436                 }
00437                 
00438                 /**
00439                  * Создать асинхронную отсроченную отложенную процедуру. Когда процедура будет запущена, то метод Method объекта Object будет синхронизированно вызван в указанном синхропространстве Space. Если объект Object является синхрообъектом и синхропространство явно не указано, то используется синхропространство, к которому принадлежит синхрообъект (свойство Cntm::SynchroObject::Space()). Если объект Object не является синхрообъектом и синхропространство явно не указано, то используется главное синхропространство.
00440                  * 
00441                  * Формат вызова: SuspendDefer(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00442                  * 
00443                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00444                  * 
00445                  * Исключения:
00446                  * NullArgException - не указан объект обработчик (Object равен NULL).
00447                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00448                  * IllegalStateException - если синхропространство не указано явно, объект не является синхрообъектом и не создано главное синхропространство.
00449                  * @param Object - объект-обработчик. Задается ссылочным указателем.
00450                  * @param Method - метод объекта Object, который будет вызван синхронизированно в указанном синхропространстве.
00451                  * @param Space - синхропространство, в котором будет выполнен метод. Если явно не указано, тоиспользуется синхропространство объекта Object, если это синхрообъект, иначе используется главное синхропространство.
00452                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00453                  */
00454                 template < typename MethodSignatureT >
00455                 static SpecUtils::DeferProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDefer(
00456                         RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 
00457                         MethodSignatureT Method, 
00458                         SynchroSpace::Ptr Space = SynchroSpace::Ptr(),
00459                         bool HoldRef = true)
00460                 {
00461                         return SpecUtils::DeferProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00462                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), GetSpace(Object.Pointer(), Space), HoldRef, true);
00463                 }       
00464 
00465                 /**
00466                  * Создать и запустить прямую процедуру. По сути, ни чем не отличается от обычного запуска метода Method объекта Object.
00467                  * 
00468                  * Формат вызова: Direct(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00469                  * 
00470                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00471                  * 
00472                  * Исключения:
00473                  * NullArgException - не указан объект обработчик (Object равен NULL).
00474                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00475                  * @param Object - объект-обработчик. Задается обычным указателем.
00476                  * @param Method - метод объекта Object, который будет вызван при создании процедуры.
00477                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00478                  */
00479                 template < typename MethodSignatureT >
00480                 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Direct(
00481                         typename SignatureInfo < MethodSignatureT > ::ClassType* Object,
00482                         MethodSignatureT Method,
00483                         bool HoldRef = true)
00484                 {
00485                         return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00486                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, false);
00487                 }
00488                 
00489                 /**
00490                  * Создать и запустить прямую процедуру. По сути, ни чем не отличается от обычного запуска метода Method объекта Object.
00491                  * 
00492                  * Формат вызова: Direct(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00493                  * 
00494                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00495                  * 
00496                  * Исключения:
00497                  * NullArgException - не указан объект обработчик (Object равен NULL).
00498                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00499                  * @param Object - объект-обработчик. Задается ссылочным указателем.
00500                  * @param Method - метод объекта Object, который будет вызван при создании процедуры.
00501                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00502                  */
00503                 template < typename MethodSignatureT >
00504                 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Direct(
00505                         RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 
00506                         MethodSignatureT Method,
00507                         bool HoldRef = true)
00508                 {
00509                         return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00510                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, false);
00511                 }       
00512 
00513                 /**
00514                  * Создать прямую процедуру. Подготавливает вызов метода Method объекта Object.
00515                  * 
00516                  * Формат вызова: SuspendDirect(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00517                  * 
00518                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00519                  * 
00520                  * Исключения:
00521                  * NullArgException - не указан объект обработчик (Object равен NULL).
00522                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00523                  * @param Object - объект-обработчик. Задается обычным указателем.
00524                  * @param Method - метод объекта Object, который будет вызван при создании процедуры.
00525                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00526                  */
00527                 template < typename MethodSignatureT >
00528                 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDirect(
00529                         typename SignatureInfo < MethodSignatureT > ::ClassType* Object,
00530                         MethodSignatureT Method,
00531                         bool HoldRef = true)
00532                 {
00533                         return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00534                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, true);
00535                 }
00536                 
00537                 /**
00538                  * Создать прямую процедуру. Подготавливает вызов метода Method объекта Object.
00539                  * 
00540                  * Формат вызова: SuspendDirect(параметры процедуры)(аргументы асинхронного метода). Если аргументов нет, то просто ставятся круглые скобки.
00541                  * 
00542                  * Возвращается объект результата асинхронной процедуры Cntm::AsyncProcResult.
00543                  * 
00544                  * Исключения:
00545                  * NullArgException - не указан объект обработчик (Object равен NULL).
00546                  * IllegalStateException - сылочный объект, обрабатывающий процедуру, находится в удаляемом состоянии. Если требуется создать процедуру для выполнения в удаляемом состоянии объекта-обработчика, следует установить параметр HoldRef в false.
00547                  * @param Object - объект-обработчик. Задается ссылочным указателем.
00548                  * @param Method - метод объекта Object, который будет вызван при создании процедуры.
00549                  * @param HoldRef - хранить ли ссылку на объект Object, если это ссылочный объект. Параметр опциональный, значение по умолчанию - true.
00550                  */
00551                 template < typename MethodSignatureT >
00552                 static SpecUtils::DirectProcFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > SuspendDirect(
00553                         RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > Object, 
00554                         MethodSignatureT Method,
00555                         bool HoldRef = true)
00556                 {
00557                         return SpecUtils::DirectProcFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00558                                 (GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method), HoldRef, true);
00559                 }       
00560 
00561         private:
00562         
00563                 /**
00564                  * Определить синхропространство для отложенных процедур. Метод для случая, когда указан синхрообъект. Если синхропространство указано явно, то используется оно, иначе используется синхропространство объекта. 
00565                  */
00566                 static SynchroSpace::Ptr GetSpace(const IBasicSynchro* Object, const SynchroSpace::Ptr Space)
00567                 {
00568                         return (!Space && Object)? Object->Space() : Space;
00569                 }
00570 
00571                 /**
00572                  * Определить синхропространство для отложенных процедур. Метод для случая, когда указан не синхрообъект. Если синхропространство указано явно, то используется оно, иначе используется главное синхропространство. 
00573                  */
00574                 static SynchroSpace::Ptr GetSpace(const void* Object, const SynchroSpace::Ptr Space)
00575                 {
00576                         return Space;
00577                 }
00578         };
00579 
00580 }
00581 
00582 #endif //CNTM_ASYNCPROC_H

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