Changeset 16094


Ignore:
Timestamp:
05/23/13 19:12:13 (12 years ago)
Author:
tbretz
Message:
Improved performance; renamed functions; added fSize; improved starting/stopping of thread
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/queue.h

    r15625 r16094  
    66
    77template<class T>
    8 class Queue : std::deque<T>
     8class Queue : std::list<T>
    99{
    1010    std::mutex fMutex;        // Mutex needed for the conditional
     
    1313    enum state_t
    1414    {
     15        kIdle,
    1516        kRun,
    16         kWait,
    17         kStop
     17        kStop,
     18        kAbort,
    1819    };
     20
     21    size_t fSize;                 // Only necessary for before C++11
    1922
    2023    state_t fState;               // Stop signal for the thread
     
    2831    {
    2932        std::unique_lock<std::mutex> lock(fMutex);
     33
    3034        while (1)
    3135        {
    32             while (std::deque<T>::empty() && fState==kRun)
     36            while (std::list<T>::empty() && fState==kRun)
    3337                fCond.wait(lock);
    3438
    35             if (fState==kStop)
     39            if (fState==kAbort)
    3640                break;
    3741
    38             if (fState==kWait && std::deque<T>::empty())
     42            if (fState==kStop && std::list<T>::empty())
    3943                break;
    4044
    41             const T val = std::deque<T>::front();
    42             std::deque<T>::pop_front();
     45            const T &val = std::list<T>::front();
    4346
    4447            // Theoretically, we can loose a signal here, but this is
     
    5053
    5154            lock.lock();
     55
     56            std::list<T>::pop_front();
     57            fSize--;
    5258        }
     59
     60        std::list<T>::clear();
     61        fSize = 0;
     62
     63        fState = kIdle;
    5364    }
    5465
    5566public:
    56     Queue(const callback &f) : fState(kRun), fCallback(f)
     67    Queue(const callback &f) : fSize(0), fState(kIdle), fCallback(f)
    5768    {
    58         fThread = std::thread(std::bind(&Queue::Thread, this));
     69        start();
    5970    }
    6071    ~Queue()
    6172    {
    62         stop();
    63         join();
     73        wait(true);
    6474    }
    6575
    66     void post(const T &val)
     76    bool start()
    6777    {
    6878        const std::lock_guard<std::mutex> lock(fMutex);
     79        if (fState!=kIdle)
     80            return false;
    6981
    70         std::deque<T>::push_back(val);
    71         fCond.notify_one();
     82        fState = kRun;
     83        fThread = std::thread(std::bind(&Queue::Thread, this));
     84        return true;
    7285    }
    7386
    74     void wait()
     87    bool stop()
    7588    {
    76         fMutex.lock();
    77         fState = kWait;
     89        const std::lock_guard<std::mutex> lock(fMutex);
     90        if (fState==kIdle)
     91            return false;
     92
     93        fState = kStop;
    7894        fCond.notify_one();
    79         fMutex.unlock();
     95
     96        return true;
    8097    }
    8198
    82     void stop()
     99    bool abort()
    83100    {
    84         fMutex.lock();
    85         fState = kStop;
     101        const std::lock_guard<std::mutex> lock(fMutex);
     102        if (fState==kIdle)
     103            return false;
     104
     105        fState = kAbort;
    86106        fCond.notify_one();
    87         fMutex.unlock();
     107
     108        return true;
    88109    }
    89110
    90     void join()
     111    bool wait(bool abrt=false)
    91112    {
    92         // This can happen is the thread is not running anymore
    93         try
    94113        {
    95             fThread.join();
     114            const std::lock_guard<std::mutex> lock(fMutex);
     115            if (fState==kIdle)
     116                return false;
     117
     118            if (fState==kRun)
     119            {
     120                fState = abrt ? kAbort : kStop;
     121                fCond.notify_one();
     122            }
    96123        }
    97         catch (const std::system_error &)
    98         {
    99         }
     124
     125        fThread.join();
     126        return true;
     127    }
     128
     129    bool post(const T &val)
     130    {
     131        const std::lock_guard<std::mutex> lock(fMutex);
     132        if (fState==kIdle)
     133            return false;
     134
     135        std::list<T>::push_back(val);
     136        fSize++;
     137
     138        fCond.notify_one();
     139
     140        return true;
     141    }
     142
     143    size_t size() const
     144    {
     145        return fSize;
    100146    }
    101147};
Note: See TracChangeset for help on using the changeset viewer.