00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 00002 00003 // -- BEGIN LICENSE BLOCK ---------------------------------------------- 00004 // This file is part of FZIs ic_workspace. 00005 // 00006 // This program is free software licensed under the LGPL 00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3). 00008 // You can find a copy of this license in LICENSE folder in the top 00009 // directory of the source code. 00010 // 00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany 00012 // 00013 // -- END LICENSE BLOCK ------------------------------------------------ 00014 00015 //---------------------------------------------------------------------- 00022 //---------------------------------------------------------------------- 00023 #include "icl_core_thread/ActiveObject.h" 00024 00025 namespace icl_core { 00026 namespace thread { 00027 00028 ActiveObject::ActiveObject(const icl_core::String& description, icl_core::ThreadPriority priority) 00029 : Thread(description, priority), 00030 m_sem(0) 00031 { 00032 } 00033 00034 void ActiveObject::run() 00035 { 00036 onThreadStart(); 00037 00038 // Continually process the operation queue. 00039 while (execute()) 00040 { 00041 m_sem.wait(); 00042 if (execute()) 00043 { 00044 // Process all queued operations. 00045 while (!m_operation_queue.empty()) 00046 { 00047 // Try to lock the queue mutex 00048 if (m_operation_queue_mutex.lock()) 00049 { 00050 // Extract the next pending operation from the queue. 00051 ActiveOperation *op = m_operation_queue.front(); 00052 m_operation_queue.pop_front(); 00053 00054 // Release the mutex before executing the operation! 00055 m_operation_queue_mutex.unlock(); 00056 00057 // Finally, execute the operation. 00058 op->invoke(); 00059 delete op; 00060 } 00061 } 00062 } 00063 } 00064 00065 // Delete any pending operations. 00066 while (!m_operation_queue.empty()) 00067 { 00068 delete m_operation_queue.front(); 00069 m_operation_queue.pop_front(); 00070 } 00071 00072 onThreadStop(); 00073 } 00074 00075 void ActiveObject::stop() 00076 { 00077 Thread::stop(); 00078 m_sem.post(); 00079 } 00080 00081 void ActiveObject::queue(ActiveOperation *active_operation) 00082 { 00083 if (execute() && m_operation_queue_mutex.lock()) 00084 { 00085 m_operation_queue.push_back(active_operation); 00086 m_operation_queue_mutex.unlock(); 00087 m_sem.post(); 00088 } 00089 else 00090 { 00091 delete active_operation; 00092 } 00093 } 00094 00095 } 00096 }