controller.h
Go to the documentation of this file.
00001 #ifndef GCACHE_CONTROLLER_H
00002 #define GCACHE_CONTROLLER_H
00003 
00004 #include "cache.h"
00005 
00008 namespace vcg {
00009 
00010 template <class Token>
00011 class Controller {
00012  public:
00014   std::vector<Token *> tokens;
00017   bool paused;
00019   bool stopped;
00020 
00021  public:
00023   Provider<Token> provider;
00025   std::vector<Cache<Token> *> caches;
00026 
00027   Controller(): paused(false), stopped(true) {}
00028   ~Controller() { if(!stopped) finish(); }
00029 
00031 
00032   void addCache(Cache<Token> *cache) {
00033     if(caches.size() == 0)
00034       cache->setInputCache(&provider);
00035     else
00036       cache->setInputCache(caches.back());
00037     assert(cache->input);
00038     caches.push_back(cache);
00039   }
00040 
00042   bool addToken(Token *token) {
00043     if(token->count.testAndSetOrdered(Token::OUTSIDE, Token::CACHE)) {
00044       tokens.push_back(token);
00045       return true;
00046     }
00047     return false;
00048   }
00049 
00051   //FUNCTOR has bool operator(Token *) and return true to remove
00052   template<class FUNCTOR> void removeTokens(FUNCTOR functor) {
00053     pause(); //this might actually be unnecessary if you mark tokens to be removed
00054     for(int i = (int)caches.size()-1; i >= 0; i--)
00055       caches[i]->flush(functor);
00056     provider.flush(functor);
00057 
00058     resume();
00059   }
00060 
00062   void setMaxTokens(int m) {
00063     mt::mutexlocker l(&provider.heap_lock);
00064     provider.max_tokens = m;
00065   }
00066 
00069   void updatePriorities() {
00070     if(tokens.size()) {
00071       mt::mutexlocker l(&provider.heap_lock);
00072       for(unsigned int i = 0; i < tokens.size(); i++)
00073         provider.heap.push(tokens[i]);
00074       tokens.clear();
00075     }
00076 
00077     provider.pushPriorities();
00078     for(unsigned int i = 0; i < caches.size(); i++)
00079       caches[i]->pushPriorities();
00080   }
00081 
00083   void start() {
00084     assert(stopped);
00085     assert(!paused);
00086     assert(caches.size() > 1);
00087     caches.back()->final = true;
00088     for(unsigned int i = 0; i < caches.size(); i++) //cache 0 is a provider, and his thread is not running.
00089       caches[i]->start();
00090     stopped = false;
00091   }
00092 
00094   void stop() {
00095     if(stopped) return;
00096     assert(!paused);
00097 
00098     //signal al caches to quit
00099     for(unsigned int i = 0; i < caches.size(); i++)
00100       caches[i]->quit = true;
00101 
00102     //abort current gets
00103     for(unsigned int i = 0; i < caches.size(); i++)
00104       caches[i]->abort();
00105 
00106     //make sure all caches actually run a cycle.
00107     for(unsigned int i = 0; i < caches.size(); i++)
00108       caches[i]->input->check_queue.open();
00109 
00110     for(unsigned int i = 0; i < caches.size(); i++)
00111       caches[i]->wait();
00112 
00113     stopped = true;
00114   }
00115 
00116   void finish() {
00117     stop();
00118     flush();
00119   }
00120 
00121   void pause() {
00122     assert(!stopped);
00123     assert(!paused);
00124 
00125     //lock all doors.
00126     for(unsigned int i = 0; i < caches.size(); i++)
00127       caches[i]->input->check_queue.lock();
00128 
00129     //abort all pending calls
00130     for(unsigned int i = 0; i < caches.size(); i++)
00131       caches[i]->abort();
00132 
00133     //make sure no cache is running (must be done after abort! otherwise we have to wait for the get)
00134     for(unsigned int i = 0; i < caches.size()-1; i++)
00135       caches[i]->input->check_queue.room.lock();
00136 
00137     paused = true;
00138   }
00139 
00140   void resume() {
00141     assert(!stopped);
00142     assert(paused);
00143     cout << "Resume" << endl;
00144 
00145     //unlock and open all doors
00146     for(unsigned int i = 0; i < caches.size(); i++) {
00147       caches[i]->input->check_queue.unlock();
00148       caches[i]->input->check_queue.open();
00149     }
00150 
00151     //allow all cache to enter again.
00152     for(unsigned int i = 0; i < caches.size()-1; i++)
00153       caches[i]->input->check_queue.room.unlock();
00154 
00155     paused = false;
00156   }
00158   void flush() {
00159     for(int i = (int)caches.size()-1; i >= 0; i--)
00160       caches[i]->flush();
00161     provider.heap.clear();
00162   }
00163 
00164   bool newData() {
00165     bool c = false;
00166     for(int i = (int)caches.size() -1; i >= 0; i--) {
00167       c |= caches[i]->newData();
00168     }
00169     return c;
00170   }
00171 
00172   bool isWaiting() {
00173     bool waiting = true;
00174     for(int i = (int)caches.size() -1; i >= 0; i--) {
00175       waiting &= caches[i]->input->check_queue.isWaiting();
00176     }
00177     return waiting;
00178   }
00179 };
00180 
00181 } //namespace
00182 #endif // CONTROLLER_H


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:30:09