1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
/* nonBlockDelete.cc
*/
#include "osl/misc/nonBlockDelete.h"
#include "osl/misc/pointerQueue.h"
#include "osl/oslConfig.h"
#include <boost/thread.hpp>
#include <iostream>
static volatile bool finish = false;
class osl::misc::NonBlockDelete::Queue : public PointerQueue<void>
{
public:
Queue() : thread(0)
{
}
boost::thread *thread;
};
struct osl::misc::NonBlockDelete::Runner
{
boost::shared_ptr<Queue> queue;
Runner(const boost::shared_ptr<Queue>& q) : queue(q)
{
}
void operator()()
{
while (! finish)
{
boost::shared_ptr<void> ptr;
ptr = queue->pop_front();
const int count = ptr.use_count();
if (count > 1)
std::cerr << "NonBlockDelete " << count << " > 1 "
<< ptr.get() << std::endl;
// release ptr
}
}
};
osl::misc::NonBlockDelete& osl::misc::
NonBlockDelete::instance()
{
static NonBlockDelete the_instance;
return the_instance;
}
osl::misc::
NonBlockDelete::NonBlockDelete()
: queue(new Queue())
{
queue->thread = new boost::thread(Runner(queue));
}
osl::misc::
NonBlockDelete::~NonBlockDelete()
{
finish = true;
queue->quit(1);
queue->thread->join();
delete queue->thread;
}
int osl::misc::
NonBlockDelete::waiting()
{
NonBlockDelete& the_instance = instance();
return the_instance.queue->size();
}
void osl::misc::NonBlockDelete::resetAny(boost::shared_ptr<void>& ptr)
{
if (finish || OslConfig::memoryUseRatio() > 0.9) {
ptr.reset();
return;
}
instance().push_back(ptr);
}
void osl::misc::NonBlockDelete::push_back(boost::shared_ptr<void>& ptr)
{
if (finish) {
ptr.reset();
return;
}
queue->push_back(ptr);
}
void osl::misc::
NonBlockDelete::deleteAll()
{
NonBlockDelete& the_instance = instance();
while (the_instance.queue->size())
{
boost::shared_ptr<void> ptr
= the_instance.queue->pop_front_non_block();
}
boost::thread::yield();
}
bool osl::misc::
NonBlockDelete::deleteOne()
{
NonBlockDelete& the_instance = instance();
if (the_instance.queue->size() == 0)
return false;
boost::shared_ptr<void> ptr
= the_instance.queue->pop_front_non_block();
return true;
}
/* ------------------------------------------------------------------------- */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
|