door.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * GCache                                                                    *
00003 * Author: Federico Ponchio                                                  *
00004 *                                                                           *
00005 * Copyright(C) 2011                                                         *
00006 * Visual Computing Lab                                                      *
00007 * ISTI - Italian National Research Council                                  *
00008 *                                                                           *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 
00025 #ifndef CACHE_DOOR_H
00026 #define CACHE_DOOR_H
00027 
00028 #include <wrap/system/multithreading/mt.h>
00029 #include <wrap/system/multithreading/atomic_int.h>
00030 
00031 #ifdef NEXUS_USE_QT
00032 #include <QWaitCondition>
00033 #endif
00034 
00035 #define METHOD_2
00036 
00037 #ifdef METHOD_1
00038 
00039 class QDoor {
00040  private:
00041   mt::semaphore door;
00042   mt::mutex room;     //lock when entering. unlock when exiting
00043   QAtomicInt key; //keep tracks of door status
00044 
00045  public:
00046   QDoor():key(0) {}
00047   void open() {
00048     if(key.testAndSetOrdered(0, 1))
00049       door.release(1);
00050   }
00051 
00052   void enter() {
00053     door.acquire(1); //here I am sure that key is 1
00054     //if here a open appends will have no effect.
00055     key.testAndSetOrdered(1, 0);
00056     room.lock();
00057   }
00058   void leave() {
00059     room.unlock();
00060   }
00061   void lock() {
00062     int r = key.fetchAndStoreOrdered(-1);
00063     if(r == 1) //if the door was open
00064       door.tryAcquire(1); //might file if whe are between enter acquire and key = 0.
00065   }
00066   void unlock() {
00067     key = 0;
00068   }
00069 };
00070 #endif
00071 
00072 #ifdef METHOD_2
00073 
00074 //a door needs to be open for the thread to continue,
00075 //if it is open the thread enter and closes the door
00076 //this mess is to avoid [if(!open.available()) open.release(1)]
00077 
00078 class QDoor {
00079  private:
00080   mt::semaphore _open;
00081   mt::semaphore _close;
00082 
00083  public:
00084   mt::mutex room;
00085   QDoor(): _open(0), _close(1) {} //this means closed
00086 
00087   void open() {
00088     if(_close.tryAcquire(1)) //check it is not open
00089       _open.release(1); //open
00090   }
00091   void close() {
00092     if(_open.tryAcquire(1)) //check not already closed
00093       _close.release(1);
00094   }
00095   void enter(bool close = false) {
00096     _open.acquire(1);
00097     if(close)
00098       _close.release(1); //close door behind
00099     else
00100       _open.release(1);  //leave door opened
00101    room.lock();
00102   }
00103   void leave() { room.unlock(); }
00104 
00105   void lock() {
00106     //door might be open or closed, but we might happen just in the middle
00107     //of someone opening, closing or entering it.
00108     while(!_open.tryAcquire(1) && !_close.tryAcquire(1)) {}
00109     //no resources left, door is locked
00110   }
00111   void unlock(bool open = false) {
00112     if(open)
00113       _open.release(1);
00114     else
00115       _close.release(1);
00116   }
00117   bool isWaiting() {
00118     if(_open.tryAcquire(1)) {
00119       _close.release(1);
00120       return false;
00121     }
00122     return true;
00123   }
00124 };
00125 
00126 
00127 #endif
00128 
00129 
00130 #ifdef METHOD_3
00131 
00136 class QDoor {
00137  public:
00138 
00139   QDoor(void) : doorOpen(false), waiting(false) {}
00140 
00142   void open(void) {
00143     m.lock();
00144     doorOpen = true;
00145     m.unlock();
00146     c.wakeAll(); arglebargle
00147   }
00148 
00152   void enter(bool close = false) {
00153     m.lock();
00154     waiting = true;
00155     while (!doorOpen)
00156       c.wait(&(m));
00157 
00158     if(close)
00159       doorOpen = false;
00160     waiting = false;
00161     m.unlock();
00162   }
00163   void leave() {}
00164   bool isWaiting() {
00165     m.lock();
00166     bool w = waiting;
00167     m.unlock();
00168     return w;
00169   }
00170   void lock() { //prevend door opening and entering
00171     m.lock();
00172   }
00173   void unlock(bool open = false) { //reverse effect of lock
00174     doorOpen = open;
00175     m.unlock();
00176   }
00177  private:
00178   mt::mutex m;
00179   QWaitCondition c;
00180   bool doorOpen;
00181   bool waiting;
00182 };
00183 
00184 #endif
00185 
00186 
00187 #endif //CACHE_DOOR_H


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