00001 /* nonBlockDelete.cc 00002 */ 00003 #include "osl/misc/nonBlockDelete.h" 00004 #include "osl/misc/pointerQueue.h" 00005 #include <boost/thread.hpp> 00006 #include <iostream> 00007 00008 static volatile bool finish = false; 00009 00010 class osl::misc::NonBlockDelete::Queue : public PointerQueue<void> 00011 { 00012 public: 00013 Queue() : thread(0) 00014 { 00015 } 00016 boost::thread *thread; 00017 }; 00018 00019 struct osl::misc::NonBlockDelete::Runner 00020 { 00021 boost::shared_ptr<Queue> queue; 00022 Runner(const boost::shared_ptr<Queue>& q) : queue(q) 00023 { 00024 } 00025 void operator()() 00026 { 00027 while (! finish) 00028 { 00029 boost::shared_ptr<void> ptr; 00030 ptr = queue->pop_front(); 00031 const int count = ptr.use_count(); 00032 if (count > 1) 00033 std::cerr << "NonBlockDelete " << count << " > 1 " 00034 << ptr.get() << std::endl; 00035 // release ptr 00036 } 00037 } 00038 }; 00039 00040 00041 osl::misc::NonBlockDelete& osl::misc:: 00042 NonBlockDelete::instance() 00043 { 00044 static NonBlockDelete the_instance; 00045 return the_instance; 00046 } 00047 00048 osl::misc:: 00049 NonBlockDelete::NonBlockDelete() 00050 : queue(new Queue()) 00051 { 00052 queue->thread = new boost::thread(Runner(queue)); 00053 } 00054 00055 osl::misc:: 00056 NonBlockDelete::~NonBlockDelete() 00057 { 00058 finish = true; 00059 queue->quit(1); 00060 queue->thread->join(); 00061 delete queue->thread; 00062 } 00063 00064 int osl::misc:: 00065 NonBlockDelete::waiting() 00066 { 00067 NonBlockDelete& the_instance = instance(); 00068 return the_instance.queue->size(); 00069 } 00070 00071 void osl::misc::NonBlockDelete::resetAny(boost::shared_ptr<void>& ptr) 00072 { 00073 if (finish) { 00074 ptr.reset(); 00075 return; 00076 } 00077 instance().push_back(ptr); 00078 } 00079 00080 void osl::misc::NonBlockDelete::push_back(boost::shared_ptr<void>& ptr) 00081 { 00082 if (finish) { 00083 ptr.reset(); 00084 return; 00085 } 00086 queue->push_back(ptr); 00087 } 00088 00089 void osl::misc:: 00090 NonBlockDelete::deleteAll() 00091 { 00092 NonBlockDelete& the_instance = instance(); 00093 while (the_instance.queue->size()) 00094 { 00095 boost::shared_ptr<void> ptr 00096 = the_instance.queue->pop_front_non_block(); 00097 } 00098 boost::thread::yield(); 00099 } 00100 00101 bool osl::misc:: 00102 NonBlockDelete::deleteOne() 00103 { 00104 NonBlockDelete& the_instance = instance(); 00105 if (the_instance.queue->size() == 0) 00106 return false; 00107 boost::shared_ptr<void> ptr 00108 = the_instance.queue->pop_front_non_block(); 00109 return true; 00110 } 00111 00112 00113 /* ------------------------------------------------------------------------- */ 00114 // ;;; Local Variables: 00115 // ;;; mode:c++ 00116 // ;;; c-basic-offset:2 00117 // ;;; End: