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