Bladeren bron

add task_queue

ithewei 6 jaren geleden
bovenliggende
commit
f1ecb8cdd7
5 gewijzigde bestanden met toevoegingen van 195 en 7 verwijderingen
  1. 1 1
      herr.cpp
  2. 1 1
      hifconf.cpp
  3. 4 5
      hobj.h
  4. 100 0
      htask.h
  5. 89 0
      task_queue.h

+ 1 - 1
herr.cpp

@@ -44,7 +44,7 @@ int  get_last_errcode() {
 }
 
 const char* get_errmsg(int err) {
-    if (err >= 0 && err >= SYS_NERR) {
+    if (err >= 0 && err <= SYS_NERR) {
         return strerror(err);
     }
 

+ 1 - 1
hifconf.cpp

@@ -130,7 +130,7 @@ int ifconfig(std::vector<ifconfig_t>& ifcs) {
         memset(&ifc, 0, sizeof(ifc));
         strncpy(ifc.name, pAddr->AdapterName, sizeof(ifc.name));
         strncpy(ifc.ip, "0.0.0.0", sizeof(ifc.ip));
-        strncpy(ifc.mask, "0.0.0.0", sizeof(ifc.ip));
+        strncpy(ifc.mask, "255.255.255.255", sizeof(ifc.mask));
         strncpy(ifc.mac, mac, sizeof(ifc.mac));
         tmp_ifcs.push_back(ifc);
 

+ 4 - 5
hobj.h

@@ -46,7 +46,6 @@ class HObj {
             } else {
                 ++iter;
             }
-            ++iter;
         }
     }
 
@@ -60,12 +59,12 @@ class HObj {
     }
 
     HObj* findChild(std::string objName) {
-        auto iter = _children.begin();
-        while (iter != _children.end()) {
-            if ((*iter)->name() == objName)
+        for (auto iter = _children.begin(); iter != _children.end(); ++iter) {
+            if ((*iter)->name() == objName) {
                 return *iter;
-            iter++;
+            }
         }
+        return NULL;
     }
 
     HVar  property(std::string key) {

+ 100 - 0
htask.h

@@ -0,0 +1,100 @@
+#ifndef H_TASK_H_
+#define H_TASK_H_
+
+#include <mutex>
+#include <condition_variable>
+
+#include "hobj.h"
+#include "herr.h"
+
+#define DEFAULT_TASK_TIMEOUT    5000  // ms
+
+class HTask : public HObj {
+public:
+    enum State {
+        TASK_STATE_NOT_READY,
+        TASK_STATE_READY,
+        TASK_STATE_EXECUTING,
+        TASK_STATE_FINISHED,
+        TASK_STATE_ERROR
+    };
+
+    HTask() {
+        state_ = TASK_STATE_NOT_READY;
+        errno = 0;
+        is_wait_ = false;
+        timeout_ = DEFAULT_TASK_TIMEOUT;
+    }
+
+    ~HTask() {
+    }
+
+    State GetState()    {return state_;}
+    int   GetErrno()    {return errno_;}
+    void  SetErrno(int errcode) {
+        errno_ = errcode;
+        if (errno_ != 0) {
+            state_ = TASK_STATE_ERROR;
+        }
+    }
+
+    virtual int Ready() {
+        state_ = TASK_STATE_READY;
+        return 0;
+    }
+
+    virtual int Exec() {
+        state_ = TASK_STATE_EXECUTING;
+        return 0;
+    }
+
+    virtual int Finish() {
+        state_ = TASK_STATE_FINISHED;
+        wake();
+        return 0;
+    }
+
+    void SetTimeout(time_t ms) {
+        timeout_ = ms;
+    }
+
+    int Wait(std::unique_lock<std::mutex>& locker) {
+        is_wait_ = true;
+        std::cv_status status = cond_.wait_for(locker, std::chrono::milliseconds(timeout_));
+        is_wait_ = false;
+        if (status == std::cv_status::timeout){
+            SetErrno(ERR_TASK_TIMEOUT);
+            return ERR_TASK_TIMEOUT;
+        } else {
+            state_ = TASK_STATE_FINISHED;
+        }
+        return 0;
+    }
+
+    void Lock() {
+        ctx_mutex.lock();
+    }
+
+    void Unlock() {
+        ctx_mutex.unlock();
+    }
+
+protected:
+    void wake() {
+        if (is_wait_){
+            is_wait_ = false;
+            cond_.notify_all();
+        }
+    }
+
+public:
+    std::mutex ctx_mutex;  // provide a ctx mutex
+protected:
+    State state_;
+    int errno_;
+    std::condition_variable cond_;
+    bool is_wait_;
+    time_t timeout_;
+};
+
+#endif // H_TASK_H_

+ 89 - 0
task_queue.h

@@ -0,0 +1,89 @@
+#ifndef TASK_QUEUE_H_
+#define TASK_QUEUE_H_
+
+#include <memory>
+#include <list>
+#include <mutex>
+
+#include "htask.h"
+
+class TaskQueue {
+public:
+    TaskQueue(int size = 0) : max_size(size) {
+
+    }
+
+    std::shared_ptr<HTask> Get() {
+        std::lock_guard<std::mutex> locker(mutex_);
+
+        std::shared_ptr<HTask> pTask = NULL;
+        if (task_queue_.size() == 0) {
+            // task_queue empty
+            return pTask;
+        }
+
+        pTask = task_queue_.front();
+        // note: remove after get
+        task_queue_.pop_front();
+
+        return pTask;
+    }
+
+    bool Add(std::shared_ptr<HTask> pTask) {
+        std::lock_guard<std::mutex> locker(mutex_);
+
+        if (max_size != 0 && task_queue_.size() >= max_size) {
+            // task_queue full
+            return false;
+        }
+        task_queue_.push_back(pTask);
+
+        return true;
+    }
+
+    bool AddAndWait(std::shared_ptr<HTask> pTask) {
+        std::unique_lock<std::mutex> locker(mutex_);
+
+        if (max_size != 0 && task_queue_.size() >= max_size) {
+            // task_queue full
+            return false;
+        }
+
+        task_queue_.push_back(pTask);
+        if (pTask->Wait(locker) == ERR_TASK_TIMEOUT) {
+            // remove
+            for (auto iter = task_queue_.begin(); iter != task_queue_.end(); ++iter) {
+                if (*iter == pTask) {
+                    task_queue_.erase(iter);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    bool Remove(std::shared_ptr<HTask> pTask) {
+        std::lock_guard<std::mutex> locker(mutex_);
+        for (auto iter = task_queue_.begin(); iter != task_queue_.end(); ++iter) {
+            if (*iter == pTask) {
+                task_queue_.erase(iter);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void RemoveAll() {
+        std::lock_guard<std::mutex> locker(mutex_);
+        task_queue_.clear();
+    }
+
+public:
+    size_t max_size;
+protected:
+    std::list<std::shared_ptr<HTask>>    task_queue_;
+    std::mutex                           mutex_;
+};
+
+#endif // TASK_QUEUE_H_