Explorar o código

locate 测试完成,增加车位分配模块.

zx %!s(int64=5) %!d(string=hai) anos
pai
achega
d32eac0edb
Modificáronse 49 ficheiros con 10581 adicións e 119 borrados
  1. 3 0
      CMakeLists.txt
  2. 8 0
      communication/communication_message.h
  3. 3 3
      communication/communication_socket_base.cpp
  4. 26 73
      error_code/error_code.h
  5. 11 13
      lidar_locate/Locate_communicator.cpp
  6. 2 2
      lidar_locate/Locate_communicator.h
  7. 98 12
      main.cpp
  8. 0 1
      message/measure_message.pb.cc
  9. 1 0
      message/measure_message.pb.h
  10. 21 8
      message/message_base.pb.cc
  11. 9 2
      message/message_base.pb.h
  12. 8 0
      message/message_base.proto
  13. 4629 0
      message/parkspace_allocation_message.pb.cc
  14. 3205 0
      message/parkspace_allocation_message.pb.h
  15. 109 0
      message/parkspace_allocation_message.proto
  16. 477 0
      parkspace/Parkspace_communicator.cpp
  17. 82 0
      parkspace/Parkspace_communicator.h
  18. 2 1
      proto.sh
  19. 152 0
      system/StoreProcessTask.cpp
  20. 52 0
      system/StoreProcessTask.h
  21. 5 0
      system/TakeProcessTask.cpp
  22. 14 0
      system/TakeProcessTask.h
  23. 66 0
      system/system_communicator.cpp
  24. 42 0
      system/system_communicator.h
  25. 15 2
      test/Locate_client.cpp
  26. 33 0
      tool/TaskQueue/BaseTask.cpp
  27. 29 0
      tool/TaskQueue/BaseTask.h
  28. 23 0
      tool/TaskQueue/TQFactory.cpp
  29. 24 0
      tool/TaskQueue/TQFactory.h
  30. 58 0
      tool/TaskQueue/TQInterface.h
  31. 89 0
      tool/TaskQueue/TaskPool.h
  32. 288 0
      tool/TaskQueue/ThreadTaskQueue.cpp
  33. 89 0
      tool/TaskQueue/ThreadTaskQueue.h
  34. 35 0
      tool/TaskQueue/threadpp/impl/pthread_lock.h
  35. 73 0
      tool/TaskQueue/threadpp/impl/pthread_lock.hpp
  36. 45 0
      tool/TaskQueue/threadpp/impl/pthread_thread.h
  37. 110 0
      tool/TaskQueue/threadpp/impl/pthread_thread.hpp
  38. 33 0
      tool/TaskQueue/threadpp/impl/std_lock.h
  39. 52 0
      tool/TaskQueue/threadpp/impl/std_lock.hpp
  40. 40 0
      tool/TaskQueue/threadpp/impl/std_thread.h
  41. 64 0
      tool/TaskQueue/threadpp/impl/std_thread.hpp
  42. 37 0
      tool/TaskQueue/threadpp/impl/win_lock.h
  43. 80 0
      tool/TaskQueue/threadpp/impl/win_lock.hpp
  44. 53 0
      tool/TaskQueue/threadpp/impl/win_thread.h
  45. 81 0
      tool/TaskQueue/threadpp/impl/win_thread.hpp
  46. 101 0
      tool/TaskQueue/threadpp/recursive_lock.h
  47. 40 0
      tool/TaskQueue/threadpp/threadpp.h
  48. 33 0
      tool/TaskQueue/threadpp/threadpp_assert.h
  49. 31 2
      tool/thread_safe_map.h

+ 3 - 0
CMakeLists.txt

@@ -22,6 +22,7 @@ include_directories(
         ./tool/TaskQueue/threadpp
         ./system
         ./lidar_locate
+        ./parkspace
 )
 link_directories("/usr/local/lib")
 
@@ -41,6 +42,7 @@ aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/tool TOOL_SRC )
 aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/tool/TaskQueue TASK_QUEUE_SRC )
 aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/communication COMMUNICATION_SRC )
 aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/system SYSTEM_SRC )
+aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/parkspace PARKSPACE_SRC )
 
 add_executable(terminal
         main.cpp
@@ -58,6 +60,7 @@ add_executable(terminal
         ${TASK_QUEUE_SRC}
         ${COMMUNICATION_SRC}
         ${SYSTEM_SRC}
+        ${PARKSPACE_SRC}
         )
 
 target_link_libraries(terminal

+ 8 - 0
communication/communication_message.h

@@ -32,6 +32,14 @@ public:
 		eHarware_statu_msg=0x21,                //调度模块硬件状态消息
 		eExecute_request_msg=0x22,              //请求调度消息
 		eExecute_response_msg=0x23,             //调度结果反馈消息
+
+        eParkspace_allocation_status_msg = 0x31,   //车位分配模块状态消息,包括车位信息
+        eParkspace_allocation_request_msg = 0x32,  //请求分配车位消息
+        eParkspace_allocation_response_msg = 0x33, //分配车位结果反馈消息
+        eParkspace_search_request_msg = 0x34,    //查询车位请求消息
+        eParkspace_search_response_msg = 0x35,    //查询车位反馈消息
+        eParkspace_release_request_msg = 0x36,    //释放车位请求消息
+        eParkspace_release_response_msg = 0x37,    //释放车位反馈消息
 	};
 
 //通讯单元

+ 3 - 3
communication/communication_socket_base.cpp

@@ -147,7 +147,7 @@ Error_manager Communication_socket_base::communication_run()
 	m_communication_statu = COMMUNICATION_READY;
 	//启动4个线程。
 	//接受线程默认循环, 内部的nn_recv进行等待, 超时1ms
-	m_receive_condition.reset(false, true, false);
+	m_receive_condition.reset(false, false, false);
 	mp_receive_data_thread = new std::thread(&Communication_socket_base::receive_data_thread, this);
 	//解析线程默认等待, 需要接受线程去唤醒, 超时1ms, 超时后主动遍历m_receive_data_list
 	m_analysis_data_condition.reset(false, false, false);
@@ -239,8 +239,8 @@ void Communication_socket_base::receive_data_thread(Communication_socket_base* c
 	while (communicator->m_receive_condition.is_alive())
 	{
         std::this_thread::yield();
-        usleep(1);
-        communicator->m_receive_condition.wait();
+        //usleep(1);
+        communicator->m_receive_condition.wait_for_ex(std::chrono::microseconds(1));
 		if ( communicator->m_receive_condition.is_alive() )
 		{
 

+ 26 - 73
error_code/error_code.h

@@ -136,79 +136,32 @@ enum Error_code
     LOCATER_MSG_RESPONSE_HAS_NO_REQUEST,
     LOCATER_MSG_REQUEST_REPEATED,
 
-    //System_manager error from 0x04010000-0x0401FFFF
-    SYSTEM_READ_PARAMETER_ERROR=0x04010100,
-    SYSTEM_PARAMETER_ERROR,
-    SYSTEM_INPUT_TERMINOR_NO_LASERS,
-
-    //terminor_command_executor.cpp from 0x04010200-0x040102FF
-    TERMINOR_NOT_READY=0x04010200,
-    TERMINOR_INPUT_LASER_NULL,
-    TERMINOR_NOT_CONTAINS_LASER,
-    TERMINOR_INPUT_PLC_NULL,
-    TERMINOR_INPUT_LOCATER_NULL,
-    TERMINOR_CREATE_WORKING_THREAD_FAILED,
-    TERMINOR_FORCE_QUIT,
-    TERMINOR_LASER_TIMEOUT,
-    TERMINOR_POST_PLC_TIMEOUT,
-    TERMINOR_CHECK_RESULTS_ERROR,
-
-    ////Hardware limit from 0x05010000 - 0x0501ffff
-    ///railing.cpp from 0x05010100-0x050101ff
-    HARDWARE_LIMIT_LEFT_RAILING=0x05010100,         //左栏杆限制
-    HARDWARE_LIMIT_RAILING_PARAMETER_ERROR,
-    HARDWARE_LIMIT_RAILING_ERROR,
-    HARDWARE_LIMIT_CENTER_X_LEFT,
-    HARDWARE_LIMIT_CENTER_X_RIGHT,
-    HARDWARE_LIMIT_CENTER_Y_TOP,
-    HARDWARE_LIMIT_CENTER_Y_BOTTOM,
-    HARDWARE_LIMIT_HEIGHT_OUT_RANGE,
-    HARDWARE_LIMIT_ANGLE_OUT_RANGE,
-    //termonal_limit from 0x05010200-0x050102ff
-    HARDWARE_LIMIT_TERMINAL_LEFT_ERROR,
-    HARDWARE_LIMIT_TERMINAL_RIGHT_ERROR,
-    HARDWARE_LIMIT_TERMINAL_LR_ERROR,
-
-
-    //wj_lidar error from 0x06010000-0x0601FFFF
-        WJ_LIDAR_CONNECT_FAILED=0x06010000,
-    WJ_LIDAR_UNINITIALIZED,
-    WJ_LIDAR_READ_FAILED,
-    WJ_LIDAR_WRITE_FAILED,
-    WJ_LIDAR_GET_CLOUD_TIMEOUT,
-
-    //wj lidar protocol error from 0x06020000-0x0602FFFF
-        WJ_PROTOCOL_ERROR_BASE=0x06020000,
-    WJ_PROTOCOL_INTEGRITY_ERROR,
-    WJ_PROTOCOL_PARSE_FAILED,
-    WJ_PROTOCOL_EMPTY_PACKAGE,
-    WJ_PROTOCOL_EXCEED_MAX_SIZE,
-
-    //wj region detect error from 0x06030000-0x0603FFFF
-        WJ_REGION_EMPTY_CLOUD=0x06030000,
-    WJ_REGION_RECTANGLE_ANGLE_ERROR,
-    WJ_REGION_RECTANGLE_SIZE_ERROR,
-    WJ_REGION_RECTANGLE_SYMMETRY_ERROR,
-    WJ_REGION_CLUSTER_SIZE_ERROR,
-
-    //wj manager error from 0x06040000-0x0604FFFF
-    WJ_MANAGER_UNINITIALIZED=0x06040000,
-    WJ_MANAGER_LIDAR_DISCONNECTED,
-    WJ_MANAGER_PLC_DISCONNECTED,
-    WJ_MANAGER_EMPTY_CLOUD,
-
-    WJ_LIDAR_TASK_EMPTY_RESULT=0x06050000,
-    WJ_LIDAR_TASK_EMPTY_TASK,
-    WJ_LIDAR_TASK_WRONG_TYPE,
-    WJ_LIDAR_TASK_INVALID_TASK,
-    WJ_LIDAR_TASK_MEASURE_FAILED,
-
-
-
-    //task module, 任务模块  error from 0x10010000-0x1001FFFF
-	TASK_MODULE_ERROR_BASE 							= 0x10010000,
-	TASK_TYPE_IS_UNKNOW,
-	TASK_NO_RECEIVER,
+   /*
+    * parkspace error code
+    */
+    PARKSPACE_REQUEST_MSG_TYPE_ERROR                = 0x04010000,
+    PARKSPACE_ALLOCMSG_RESPONSE_HAS_NO_REQUEST,
+    PARKSPACE_SEARCHMSG_RESPONSE_HAS_NO_REQUEST,
+    PARKSPACE_RELEASEMSG_RESPONSE_HAS_NO_REQUEST,
+    PARKSPACE_ALLOC_REQUEST_INVALID,
+    PARKSPACE_SEARCH_REQUEST_INVALID,
+    PARKSPACE_RELEASE_REQUEST_INVALID,
+
+    PARKSPACE_ALLOC_REQUEST_REPEATED,
+    PARKSPACE_SEARCH_REQUEST_REPEATED,
+    PARKSPACE_RELEASE_REQUEST_REPEATED,
+
+    PARKSPACE_ALLOC_RESPONSE_TYPE_ERROR,
+    PARKSPACE_SEARCH_RESPONSE_TYPE_ERROR,
+    PARKSPACE_RELEASE_RESPONSE_TYPE_ERROR,
+
+    PARKSPACE_ALLOC_RESPONSE_INFO_ERROR,
+    PARKSPACE_SEARCH_RESPONSE_INFO_ERROR,
+    PARKSPACE_RELEASE_RESPONSE_INFO_ERROR,
+
+    PARKSPACE_ALLOC_REQUEST_CANCELED,
+    PARKSPACE_SEARCH_REQUEST_CANCELED,
+    PARKSPACE_RELEASE_REQUEST_CANCELED,
 
 
 	//Communication module, 通信模块

+ 11 - 13
lidar_locate/Locate_communicator.cpp

@@ -6,11 +6,11 @@
 //#include "locate_message.pb.h"
 
 namespace message {
-    bool operator<(const message::Measure_request_msg msg1, const message::Measure_request_msg msg2) {
+    bool operator<(const message::Measure_request_msg& msg1, const message::Measure_request_msg& msg2) {
         return (msg1.command_id() < msg2.command_id());
     }
 
-    bool operator==(const message::Measure_request_msg msg1, const message::Measure_request_msg msg2) {
+    bool operator==(const message::Measure_request_msg& msg1, const message::Measure_request_msg& msg2) {
         if (msg1.base_info().msg_type() == msg2.base_info().msg_type()
             && msg1.base_info().sender() == msg2.base_info().sender()
             && msg1.base_info().receiver() == msg2.base_info().receiver()
@@ -61,7 +61,7 @@ Error_manager Locate_communicator::locate_request(message::Measure_request_msg&
     if(request.base_info().sender()!=message::eMain||request.base_info().receiver()!=message::eMeasurer)
         return Error_manager(LOCATER_MSG_REQUEST_INVALID,MINOR_ERROR,"measure request invalid");
 
-    if(m_response_table.find(request)!=m_response_table.end())
+    if(m_response_table.find(request)==true)
         return Error_manager(LOCATER_MSG_REQUEST_REPEATED,MAJOR_ERROR," measure reques repeated");
     //设置超时,若没有设置,默认3000
     int timeout=request.base_info().has_timeout_ms()?request.base_info().timeout_ms():3000;
@@ -84,12 +84,11 @@ Error_manager Locate_communicator::locate_request(message::Measure_request_msg&
     auto start_time=std::chrono::system_clock::now();
     double time=0;
     do{
-        //在请求表中查询结果
-        std::map<message::Measure_request_msg,message::Measure_response_msg>::iterator it=m_response_table.find(request);
         //查询到记录
-        if(it!=m_response_table.end())
+        message::Measure_response_msg response;
+        ///查询是否存在,并且删除该记录,
+        if(m_response_table.find(request,response))
         {
-            message::Measure_response_msg response=it->second;
             //判断是否接收到回应,若回应信息被赋值则证明有回应
             if (response.has_base_info() && response.has_command_id())
             {
@@ -144,7 +143,8 @@ Error_manager Locate_communicator::check_msg(Communication_message*  p_msg)
 {
     //通过 p_msg->get_message_type() 和 p_msg->get_receiver() 判断这条消息是不是给我的.
     //子类重载时, 增加自己模块的判断逻辑, 以后再写.
-    if ( p_msg->get_message_type() == Communication_message::Message_type::eLocate_response_msg
+    if ( (p_msg->get_message_type() == Communication_message::Message_type::eLocate_response_msg
+        ||p_msg->get_message_type() == Communication_message::Message_type::eLocate_status_msg)
          && p_msg->get_receiver() == Communication_message::Communicator::eMain )
     {
         return Error_code::SUCCESS;
@@ -175,14 +175,12 @@ Error_manager Locate_communicator::execute_msg(Communication_message* p_msg)
             message::Measure_response_msg response;
             response.ParseFromString(p_msg->get_message_buf());
             message::Measure_request_msg request=create_request_by_response(response);
-            ///查询请求表是否存在
-            if(m_response_table.find(request)==m_response_table.end())
+            ///查询请求表是否存在,并且更新
+            if(m_response_table.find_update(request,response))
             {
                 return Error_manager(LOCATER_MSG_RESPONSE_HAS_NO_REQUEST,NEGLIGIBLE_ERROR,"measure response without request");
             }
-            ////更新表
 
-            m_response_table[request]=response;
             break;
         }
         ///测量系统状态
@@ -198,7 +196,7 @@ Error_manager Locate_communicator::execute_msg(Communication_message* p_msg)
 
 Error_manager Locate_communicator::cancel_request(message::Measure_request_msg& request)
 {
-    if(m_response_table.find(request)!=m_response_table.end())
+    if(m_response_table.find(request)==true)
         m_response_table.erase(request);
     return SUCCESS;
 }

+ 2 - 2
lidar_locate/Locate_communicator.h

@@ -17,8 +17,8 @@
 
 namespace message
 {
-    bool operator<(const message::Measure_request_msg msg1,const message::Measure_request_msg msg2);
-    bool operator==(const message::Measure_request_msg msg1,const message::Measure_request_msg msg2);
+    bool operator<(const message::Measure_request_msg& msg1,const message::Measure_request_msg& msg2);
+    bool operator==(const message::Measure_request_msg& msg1,const message::Measure_request_msg& msg2);
 }
 
 

+ 98 - 12
main.cpp

@@ -1,7 +1,7 @@
 //
 // Created by zx on 2020/6/18.
 //
-
+#include <fcntl.h>
 #include <iostream>
 #include <glog/logging.h>
 #include "TaskQueue/TQFactory.h"
@@ -11,40 +11,60 @@
 #include "Locate_communicator.h"
 #include "threadSafeQueue.h"
 
+#include "pathcreator.h"
+
+#include <glog/logging.h>
+#include <Parkspace_communicator.h>
+//using google::protobuf::io::FileInputStream;
+//using google::protobuf::io::FileOutputStream;
+using google::protobuf::io::ZeroCopyInputStream;
+using google::protobuf::io::CodedInputStream;
+using google::protobuf::io::ZeroCopyOutputStream;
+using google::protobuf::io::CodedOutputStream;
+using google::protobuf::Message;
+
+
 ///线程池
 tq::IQueue* g_pthread_queue = nullptr;
+
+GOOGLE_GLOG_DLL_DECL void shut_down_logging(const char* data, int size);
+void init_glog();
 Error_manager Init_communicators();
 
 
 int main(int argc,char* argv[])
 {
+    init_glog();
     Error_manager code=Init_communicators();
 	if(code!=SUCCESS)
     {
 	    LOG(ERROR)<<code.to_string();
     }
     g_pthread_queue= tq::TQFactory::CreateDefaultQueue();
-    g_pthread_queue->Start(6);
+    g_pthread_queue->Start(12);
 
     //std::thread* pthread=new std::thread(delete_thread);
-
+    StoreProcessTask* task=new StoreProcessTask();
     int N=0;
     while(1)
     {
-        usleep(10);
+
         StoreProcessTask* task=new StoreProcessTask();
 
-        task->init_task(rand(),rand()%6);
-        if(g_pthread_queue->TaskCount()<12)
+        char license[255]={0};
+        int rd=rand()%900000+100000;
+        sprintf(license,"鄂A%d",rd);
+        task->init_task(rand(),rand()%6,license);
+        if(g_pthread_queue->TaskCount()<1000)
         {
             g_pthread_queue->AddTask(task);
             N++;
-            printf("task size / pushed size : %d / %d\n",g_pthread_queue->TaskCount(),N);
+            printf("task size / pushed size : %04d / %08d  license : %s\n",g_pthread_queue->TaskCount(),N,license);
         }
-        else
-        {
+        else {
             delete task;
         }
+        usleep(1);
     }
 
     g_pthread_queue->WaitForFinish();
@@ -58,16 +78,82 @@ Error_manager Init_communicators()
     Error_manager code;
     if(Locate_communicator::get_instance_pointer()== nullptr)
         return FAILED;
-    code=Locate_communicator::get_instance_pointer()->communication_connect("tcp://127.0.0.1:9006");
+    code=Locate_communicator::get_instance_pointer()->communication_connect("tcp://127.0.0.1:4444");
     if(code!=SUCCESS)
     {
         return code;
     }
     Locate_communicator::get_instance_pointer()->communication_run();
 
+    //
+    if(Parkspace_communicator::get_instance_pointer()== nullptr)
+        return FAILED;
+    code=Parkspace_communicator::get_instance_pointer()->communication_connect("tcp://192.168.2.139:7001");
+    if(code!=SUCCESS)
+    {
+        return code;
+    }
+    Parkspace_communicator::get_instance_pointer()->communication_run();
     ///最后初始化与终端通讯的对象
     if(System_communicator::get_instance_pointer()== nullptr)
         return FAILED;
-
+    usleep(1000*3000);
     return SUCCESS;
-}
+}
+
+GOOGLE_GLOG_DLL_DECL void shut_down_logging(const char* data, int size)
+{
+    time_t tt;
+    time( &tt );
+    tt = tt + 8*3600;  // transform the time zone
+    tm* t= gmtime( &tt );
+    char buf[255]={0};
+    sprintf(buf,"./%d%02d%02d-%02d%02d%02d-dump.txt",
+            t->tm_year + 1900,
+            t->tm_mon + 1,
+            t->tm_mday,
+            t->tm_hour,
+            t->tm_min,
+            t->tm_sec);
+
+    FILE* tp_file=fopen(buf,"w");
+    fprintf(tp_file,data,strlen(data));
+    fclose(tp_file);
+
+}
+
+void init_glog()
+{
+    time_t tt = time(0);//时间cuo
+    struct tm* t = localtime(&tt);
+
+    char strYear[255]={0};
+    char strMonth[255]={0};
+    char strDay[255]={0};
+
+    sprintf(strYear,"%04d", t->tm_year+1900);
+    sprintf(strMonth,"%02d", t->tm_mon+1);
+    sprintf(strDay,"%02d", t->tm_mday);
+
+    char buf[255]={0};
+    getcwd(buf,255);
+    char strdir[255]={0};
+    sprintf(strdir,"%s/log/%s/%s/%s", buf,strYear,strMonth,strDay);
+    PathCreator creator;
+    creator.Mkdir(strdir);
+
+    char logPath[255] = { 0 };
+    sprintf(logPath, "%s/", strdir);
+    FLAGS_max_log_size = 100;
+    FLAGS_logbufsecs = 0;
+    google::InitGoogleLogging("LidarMeasurement");
+    google::SetStderrLogging(google::INFO);
+    google::SetLogDestination(0, logPath);
+    google::SetLogFilenameExtension("zxlog");
+    google::InstallFailureSignalHandler();
+    google::InstallFailureWriter(&shut_down_logging);
+    FLAGS_colorlogtostderr = true;        // Set log color
+    FLAGS_logbufsecs = 0;                // Set log output speed(s)
+    FLAGS_max_log_size = 1024;            // Set max log file size(GB)
+    FLAGS_stop_logging_if_full_disk = true;
+}

+ 0 - 1
message/measure_message.pb.cc

@@ -1710,7 +1710,6 @@ void Measure_response_msg::InternalSwap(Measure_response_msg* other) {
 }
 
 
-
 // @@protoc_insertion_point(namespace_scope)
 }  // namespace message
 

+ 1 - 0
message/measure_message.pb.h

@@ -601,6 +601,7 @@ class Measure_response_msg : public ::google::protobuf::Message /* @@protoc_inse
 };
 // ===================================================================
 
+
 // ===================================================================
 
 #ifdef __GNUC__

+ 21 - 8
message/message_base.pb.cc

@@ -236,20 +236,26 @@ void AddDescriptorsImpl() {
       "\030\004 \001(\002\022\024\n\014locate_width\030\005 \001(\002\022\025\n\rlocate_h"
       "eight\030\006 \001(\002\022\031\n\021locate_wheel_base\030\007 \001(\002\022\032"
       "\n\022locate_wheel_width\030\010 \001(\002\022\026\n\016locate_cor"
-      "rect\030\t \001(\010*\307\001\n\014Message_type\022\r\n\teBase_msg"
+      "rect\030\t \001(\010*\314\003\n\014Message_type\022\r\n\teBase_msg"
       "\020\000\022\020\n\014eCommand_msg\020\001\022\026\n\022eLocate_status_m"
       "sg\020\021\022\027\n\023eLocate_request_msg\020\022\022\030\n\024eLocate"
       "_response_msg\020\023\022\026\n\022eHarware_statu_msg\020!\022"
       "\030\n\024eExecute_request_msg\020\"\022\031\n\025eExecute_re"
-      "sponse_msg\020#*a\n\014Communicator\022\n\n\006eEmpty\020\000"
-      "\022\t\n\005eMain\020\001\022\016\n\teTerminor\020\200\002\022\013\n\006eTable\020\200\004"
-      "\022\016\n\teMeasurer\020\200\006\022\r\n\010eProcess\020\200\010*e\n\013Error"
-      "_level\022\n\n\006NORMAL\020\000\022\024\n\020NEGLIGIBLE_ERROR\020\001"
-      "\022\017\n\013MINOR_ERROR\020\002\022\017\n\013MAJOR_ERROR\020\003\022\022\n\016CR"
-      "ITICAL_ERROR\020\004"
+      "sponse_msg\020#\022$\n eParkspace_allocation_st"
+      "atus_msg\0201\022%\n!eParkspace_allocation_requ"
+      "est_msg\0202\022&\n\"eParkspace_allocation_respo"
+      "nse_msg\0203\022!\n\035eParkspace_search_request_m"
+      "sg\0204\022\"\n\036eParkspace_search_response_msg\0205"
+      "\022\"\n\036eParkspace_release_request_msg\0206\022#\n\037"
+      "eParkspace_release_response_msg\0207*a\n\014Com"
+      "municator\022\n\n\006eEmpty\020\000\022\t\n\005eMain\020\001\022\016\n\teTer"
+      "minor\020\200\002\022\013\n\006eTable\020\200\004\022\016\n\teMeasurer\020\200\006\022\r\n"
+      "\010eProcess\020\200\010*e\n\013Error_level\022\n\n\006NORMAL\020\000\022"
+      "\024\n\020NEGLIGIBLE_ERROR\020\001\022\017\n\013MINOR_ERROR\020\002\022\017"
+      "\n\013MAJOR_ERROR\020\003\022\022\n\016CRITICAL_ERROR\020\004"
   };
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 974);
+      descriptor, 1235);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "message_base.proto", &protobuf_RegisterTypes);
 }
@@ -280,6 +286,13 @@ bool Message_type_IsValid(int value) {
     case 33:
     case 34:
     case 35:
+    case 49:
+    case 50:
+    case 51:
+    case 52:
+    case 53:
+    case 54:
+    case 55:
       return true;
     default:
       return false;

+ 9 - 2
message/message_base.pb.h

@@ -82,11 +82,18 @@ enum Message_type {
   eLocate_response_msg = 19,
   eHarware_statu_msg = 33,
   eExecute_request_msg = 34,
-  eExecute_response_msg = 35
+  eExecute_response_msg = 35,
+  eParkspace_allocation_status_msg = 49,
+  eParkspace_allocation_request_msg = 50,
+  eParkspace_allocation_response_msg = 51,
+  eParkspace_search_request_msg = 52,
+  eParkspace_search_response_msg = 53,
+  eParkspace_release_request_msg = 54,
+  eParkspace_release_response_msg = 55
 };
 bool Message_type_IsValid(int value);
 const Message_type Message_type_MIN = eBase_msg;
-const Message_type Message_type_MAX = eExecute_response_msg;
+const Message_type Message_type_MAX = eParkspace_release_response_msg;
 const int Message_type_ARRAYSIZE = Message_type_MAX + 1;
 
 const ::google::protobuf::EnumDescriptor* Message_type_descriptor();

+ 8 - 0
message/message_base.proto

@@ -17,6 +17,14 @@ enum Message_type
     eExecute_request_msg=0x22;              //请求调度消息
     eExecute_response_msg=0x23;             //调度结果反馈消息
 
+    eParkspace_allocation_status_msg = 0x31;   //车位分配模块状态消息,包括车位信息
+    eParkspace_allocation_request_msg = 0x32;  //请求分配车位消息
+    eParkspace_allocation_response_msg = 0x33; //分配车位结果反馈消息
+    eParkspace_search_request_msg = 0x34;    //查询车位请求消息
+    eParkspace_search_response_msg = 0x35;    //查询车位反馈消息
+    eParkspace_release_request_msg = 0x36;    //释放车位请求消息
+    eParkspace_release_response_msg = 0x37;    //释放车位反馈消息
+
 }
 
 //通讯单元

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 4629 - 0
message/parkspace_allocation_message.pb.cc


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 3205 - 0
message/parkspace_allocation_message.pb.h


+ 109 - 0
message/parkspace_allocation_message.proto

@@ -0,0 +1,109 @@
+syntax = "proto2";
+package message;
+import "message_base.proto";
+
+// 请求
+// 1.分配车位
+// 2.查询车辆位置
+// 3.解锁车位
+
+message Car_info
+{
+    optional float                      car_length=1;           //车长
+    required float                      car_width=2;            //车宽
+    required float                      car_height=3;           //车高
+    required string                     license=4;              //车辆凭证号
+}
+
+//车位状态枚举
+enum Parkspace_status
+{
+    eParkspace_empty            = 0;         //空闲,可分配
+    eParkspace_occupied         = 1;         //被占用,不可分配
+    eParkspace_reserverd        = 2;         //被预约,预约车辆可分配
+    eParkspace_error            = 3;         //车位机械结构或硬件故障   
+}
+
+enum Direction
+{
+    eForward = 1;
+    eBackward = 2;
+}
+
+//单个车位基本信息与状态信息
+message Parkspace_info
+{
+    required int32              parkspace_id=1;         //车位编号
+    required int32              index=2;                //同层编号
+    required Direction          direction=3;            //前后
+    required int32              floor=4;                //楼层
+    optional float              length=5;               //车位长
+    required float              width=6;                //车位宽
+    required float              height=7;               //车位高
+    required Parkspace_status   parkspace_status=8;     //车位当前状态
+    optional Car_info           car_info=9;              //当前车位存入车辆的凭证号
+    optional string             entry_time=10;          //入场时间
+    optional string             leave_time=11;          //离场时间
+}
+
+//1.分配车位请求
+message Parkspace_allocation_request_msg
+{
+    required Base_info                  base_info=1;            //消息类型
+    required int32                      command_id=2;           //指令唯一标识符id
+    required Car_info                   car_info=3;
+    required int32                      terminal_id=4;          //终端id,优化车位分配用
+}
+
+//分配车位反馈
+message Parkspace_allocation_response_msg
+{
+    required Base_info                  base_info=1;            //消息类型
+    required int32                      command_id=2;           //指令唯一标识符id
+    required Error_manager              error_manager=3;        //分配成功与否标志
+    required Parkspace_info             allocated_space_info=4; //分配车位信息
+}
+
+//2.查询车辆位置请求
+message Parkspace_search_request_msg
+{
+    required Base_info                  base_info=1;            //消息类型
+    required int32                      command_id=2;           //指令唯一标识符id
+    required Car_info                   car_info=3;              //车辆凭证或号牌
+}
+
+//查询车辆位置反馈
+message Parkspace_search_response_msg
+{
+    required Base_info                  base_info=1;            //消息类型
+    required int32                      command_id=2;           //指令唯一标识符id
+    required Error_manager              error_manager=3;        //分配成功与否标志
+    optional Parkspace_info             car_position=4;         //待查询车辆存放位置
+}
+
+//3.解锁车位请求
+message Parkspace_release_request_msg
+{
+    required Base_info                  base_info=1;            //消息类型
+    required int32                      command_id=2;           //指令唯一标识符id
+    required Parkspace_info             release_space_info=3;   //待释放车位信息
+}
+
+//查询车辆位置反馈
+message Parkspace_release_response_msg
+{
+    required Base_info                  base_info=1;            //消息类型
+    required int32                      command_id=2;           //指令唯一标识符id
+    required Error_manager              error_manager=3;        //分配成功与否标志
+    required Parkspace_info             release_space_info=4;   //待释放车位信息
+}
+
+// 车位心跳状态信息
+message Parkspace_allocation_status_msg
+{
+    required Base_info                  base_info=1;            //消息类型
+    required Error_manager              error_manager=2;
+    repeated Parkspace_info             parkspace_info=3;       //车位状态
+}
+
+

+ 477 - 0
parkspace/Parkspace_communicator.cpp

@@ -0,0 +1,477 @@
+//
+// Created by zx on 2020/7/9.
+//
+
+#include "Parkspace_communicator.h"
+
+namespace message {
+    bool operator<(const message::Parkspace_allocation_request_msg &msg1,
+                   const message::Parkspace_allocation_request_msg &msg2) {
+        return (msg1.command_id() < msg2.command_id());
+    }
+
+    bool operator==(const message::Parkspace_allocation_request_msg &msg1,
+                    const message::Parkspace_allocation_request_msg &msg2)
+    {
+        if (msg1.base_info().msg_type() == msg2.base_info().msg_type()
+            && msg1.base_info().sender() == msg2.base_info().sender()
+            && msg1.base_info().receiver() == msg2.base_info().receiver()
+            && msg1.command_id() == msg2.command_id()
+            && msg1.terminal_id() == msg2.terminal_id()){
+            return true;
+        }
+        return false;
+    }
+
+    bool operator<(const message::Parkspace_search_request_msg &msg1,
+            const message::Parkspace_search_request_msg &msg2) {
+        return (msg1. command_id() < msg2.command_id());
+    }
+
+bool operator==(const message::Parkspace_search_request_msg &msg1, const message::Parkspace_search_request_msg &msg2)
+{
+    if (msg1.base_info().msg_type() == msg2.base_info().msg_type()
+        && msg1.base_info().sender() == msg2.base_info().sender()
+        && msg1.base_info().receiver() == msg2.base_info().receiver()
+        && msg1.command_id() == msg2.command_id()) {
+        return true;
+    }
+    return false;
+}
+
+bool operator<(const message::Parkspace_release_request_msg &msg1, const message::Parkspace_release_request_msg &msg2)
+{
+    return (msg1.command_id() < msg2.command_id());
+}
+
+bool operator==(const message::Parkspace_release_request_msg &msg1, const message::Parkspace_release_request_msg &msg2)
+{
+    if (msg1.base_info().msg_type() == msg2.base_info().msg_type()
+        && msg1.base_info().sender() == msg2.base_info().sender()
+        && msg1.base_info().receiver() == msg2.base_info().receiver()
+        && msg1.command_id() == msg2.command_id()) {
+        return true;
+    }
+    return false;
+}
+
+}
+
+
+Parkspace_communicator::~Parkspace_communicator(){}
+/*
+ * 请求分配车位
+ */
+Error_manager Parkspace_communicator::alloc_request(message::Parkspace_allocation_request_msg& request,message::Parkspace_allocation_response_msg& result)
+{
+    /*
+     * 检查request合法性,以及模块状态
+     */
+    if(request.base_info().sender()!=message::eMain||request.base_info().receiver()!=message::eTable)
+        return Error_manager(PARKSPACE_ALLOC_REQUEST_INVALID,MINOR_ERROR,"parkspace alloc request invalid");
+
+    if(m_alloc_table.find(request)==true)
+        return Error_manager(PARKSPACE_ALLOC_REQUEST_REPEATED,MAJOR_ERROR," parkspace alloc request repeated");
+    //设置超时,若没有设置,默认1000
+    int timeout=request.base_info().has_timeout_ms()?request.base_info().timeout_ms():1000;
+    //向测量节点发送测量请求,并记录请求
+
+    Error_manager code;
+    Communication_message message;
+
+    message::Base_info base_msg;
+    base_msg.set_msg_type(message::eParkspace_allocation_request_msg);
+    base_msg.set_sender(message::eMain);
+    base_msg.set_receiver(message::eTable);
+    base_msg.set_timeout_ms(timeout);
+    message.reset(base_msg,request.SerializeAsString());
+
+    code=encapsulate_msg(&message);
+    if(code!=SUCCESS)
+        return code;
+    //循环查询请求是否被处理
+    auto start_time=std::chrono::system_clock::now();
+    double time=0;
+    do{
+        //查询到记录
+        message::Parkspace_allocation_response_msg response;
+        ///查询是否存在,并且删除该记录,
+        if(m_alloc_table.find(request,response))
+        {
+            //判断是否接收到回应,若回应信息被赋值则证明有回应
+            if (response.has_base_info() && response.has_command_id())
+            {
+                message::Base_info response_base = response.base_info();
+                //检查类型是否匹配
+                if (response_base.msg_type() != message::eParkspace_allocation_response_msg) {
+                    return Error_manager(PARKSPACE_ALLOC_RESPONSE_TYPE_ERROR, MAJOR_ERROR,
+                                         "parkspace alloc response msg type error");
+                }
+                //检查基本信息是否匹配
+                if (response_base.sender() != message::eTable ||
+                    response_base.receiver() != message::eMain ||
+                    response.command_id() != request.command_id()) {
+                    return Error_manager(PARKSPACE_ALLOC_RESPONSE_INFO_ERROR, MAJOR_ERROR,
+                                         "parkspace alloc response msg info error");
+                }
+                result = response;
+                m_alloc_table.erase(request);
+
+                return SUCCESS;
+
+            }
+        }
+        else
+        {
+            //未查询到记录,任务已经被提前取消,记录被删除
+            return Error_manager(PARKSPACE_ALLOC_REQUEST_CANCELED,MINOR_ERROR,"parkspace alloc request canceled");
+        }
+
+        auto end_time=std::chrono::system_clock::now();
+        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
+        time=1000.0*double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
+        std::this_thread::yield();
+        usleep(1000);
+    }while(time<double(timeout));
+    return Error_manager(RESPONSE_TIMEOUT,MINOR_ERROR,"parkspace alloc request timeout");
+
+}
+
+/*
+ * 查询车辆所在位置请求
+ */
+Error_manager Parkspace_communicator::search_request(message::Parkspace_search_request_msg& request,
+        message::Parkspace_search_response_msg& result)
+{
+    /*
+     * 检查request合法性,以及模块状态
+     */
+    if(request.base_info().sender()!=message::eMain||request.base_info().receiver()!=message::eTable)
+        return Error_manager(PARKSPACE_SEARCH_REQUEST_INVALID,MINOR_ERROR,"parkspace search request invalid");
+
+    if(m_search_table.find(request)==true)
+        return Error_manager(PARKSPACE_SEARCH_REQUEST_REPEATED,MAJOR_ERROR," parkspace search request repeated");
+    //设置超时,若没有设置,默认1000
+    int timeout=request.base_info().has_timeout_ms()?request.base_info().timeout_ms():1000;
+    //向测量节点发送测量请求,并记录请求
+
+    Error_manager code;
+    Communication_message message;
+
+    message::Base_info base_msg;
+    base_msg.set_msg_type(message::eParkspace_search_request_msg);
+    base_msg.set_sender(message::eMain);
+    base_msg.set_receiver(message::eTable);
+    base_msg.set_timeout_ms(timeout);
+    message.reset(base_msg,request.SerializeAsString());
+
+    code=encapsulate_msg(&message);
+    if(code!=SUCCESS)
+        return code;
+    //循环查询请求是否被处理
+    auto start_time=std::chrono::system_clock::now();
+    double time=0;
+    do{
+        //查询到记录
+        message::Parkspace_search_response_msg response;
+        ///查询是否存在,并且删除该记录,
+        if(m_search_table.find(request,response))
+        {
+            //判断是否接收到回应,若回应信息被赋值则证明有回应
+            if (response.has_base_info() && response.has_command_id())
+            {
+                message::Base_info response_base = response.base_info();
+                //检查类型是否匹配
+                if (response_base.msg_type() != message::eParkspace_search_response_msg) {
+                    return Error_manager(PARKSPACE_SEARCH_RESPONSE_TYPE_ERROR, MAJOR_ERROR,
+                                         "parkspace search response msg type error");
+                }
+                //检查基本信息是否匹配
+                if (response_base.sender() != message::eTable ||
+                    response_base.receiver() != message::eMain ||
+                    response.command_id() != request.command_id()) {
+                    return Error_manager(PARKSPACE_SEARCH_RESPONSE_INFO_ERROR, MAJOR_ERROR,
+                                         "parkspace search response msg info error");
+                }
+                result = response;
+                m_search_table.erase(request);
+
+                return SUCCESS;
+
+            }
+        }
+        else
+        {
+            //未查询到记录,任务已经被提前取消,记录被删除
+            return Error_manager(PARKSPACE_SEARCH_REQUEST_CANCELED,MINOR_ERROR,"parkspace search request canceled");
+        }
+
+        auto end_time=std::chrono::system_clock::now();
+        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
+        time=1000.0*double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
+        std::this_thread::yield();
+        usleep(1000);
+    }while(time<double(timeout));
+    return Error_manager(RESPONSE_TIMEOUT,MINOR_ERROR,"parkspace search request timeout");
+}
+
+/*
+ * 释放车位请求(停车失败或者取车完成时调用)
+ */
+Error_manager Parkspace_communicator::release_request(message::Parkspace_release_request_msg& request,
+        message::Parkspace_release_response_msg& result)
+{
+    /*
+    * 检查request合法性,以及模块状态
+    */
+    if(request.base_info().sender()!=message::eMain||request.base_info().receiver()!=message::eTable)
+        return Error_manager(PARKSPACE_RELEASE_REQUEST_INVALID,MINOR_ERROR,"parkspace release request invalid");
+
+    if(m_release_table.find(request)==true)
+        return Error_manager(PARKSPACE_RELEASE_REQUEST_REPEATED,MAJOR_ERROR," parkspace release request repeated");
+    //设置超时,若没有设置,默认1000
+    int timeout=request.base_info().has_timeout_ms()?request.base_info().timeout_ms():1000;
+    //向测量节点发送测量请求,并记录请求
+
+    Error_manager code;
+    Communication_message message;
+
+    message::Base_info base_msg;
+    base_msg.set_msg_type(message::eParkspace_release_request_msg);
+    base_msg.set_sender(message::eMain);
+    base_msg.set_receiver(message::eTable);
+    base_msg.set_timeout_ms(timeout);
+    message.reset(base_msg,request.SerializeAsString());
+
+    code=encapsulate_msg(&message);
+    if(code!=SUCCESS)
+        return code;
+    //循环查询请求是否被处理
+    auto start_time=std::chrono::system_clock::now();
+    double time=0;
+    do{
+        //查询到记录
+        message::Parkspace_release_response_msg response;
+        ///查询是否存在,并且删除该记录,
+        if(m_release_table.find(request,response))
+        {
+            //判断是否接收到回应,若回应信息被赋值则证明有回应
+            if (response.has_base_info() && response.has_command_id())
+            {
+                message::Base_info response_base = response.base_info();
+                //检查类型是否匹配
+                if (response_base.msg_type() != message::eParkspace_release_response_msg) {
+                    return Error_manager(PARKSPACE_RELEASE_RESPONSE_TYPE_ERROR, MAJOR_ERROR,
+                                         "parkspace release response msg type error");
+                }
+                //检查基本信息是否匹配
+                if (response_base.sender() != message::eTable ||
+                    response_base.receiver() != message::eMain ||
+                    response.command_id() != request.command_id()) {
+                    return Error_manager(PARKSPACE_RELEASE_RESPONSE_INFO_ERROR, MAJOR_ERROR,
+                                         "parkspace release response msg info error");
+                }
+                result = response;
+                m_release_table.erase(request);
+
+                return SUCCESS;
+
+            }
+        }
+        else
+        {
+            //未查询到记录,任务已经被提前取消,记录被删除
+            return Error_manager(PARKSPACE_RELEASE_REQUEST_CANCELED,MINOR_ERROR,"parkspace release request canceled");
+        }
+
+        auto end_time=std::chrono::system_clock::now();
+        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
+        time=1000.0*double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
+        std::this_thread::yield();
+        usleep(1000);
+    }while(time<double(timeout));
+    return Error_manager(RESPONSE_TIMEOUT,MINOR_ERROR,"parkspace release request timeout");
+}
+
+
+Error_manager Parkspace_communicator::check_statu()
+{
+    return SUCCESS;
+}
+
+
+
+Parkspace_communicator::Parkspace_communicator(){}
+
+Error_manager Parkspace_communicator::encapsulate_msg(Communication_message* message)
+{
+    switch (message->get_message_type())
+    {
+        case Communication_message::eParkspace_allocation_request_msg:
+        {
+            message::Parkspace_allocation_request_msg request;
+            request.ParseFromString(message->get_message_buf());
+            //记录数据
+            m_alloc_table[request]=message::Parkspace_allocation_response_msg();
+            //发送请求
+            return Communication_socket_base::encapsulate_msg(message);
+        }
+        case Communication_message::eParkspace_search_request_msg:
+        {
+            message::Parkspace_search_request_msg request;
+            request.ParseFromString(message->get_message_buf());
+            //记录数据
+            m_search_table[request]=message::Parkspace_search_response_msg();
+            //发送请求
+            return Communication_socket_base::encapsulate_msg(message);
+        }
+        case Communication_message::eParkspace_release_request_msg:
+        {
+            message::Parkspace_release_request_msg request;
+            request.ParseFromString(message->get_message_buf());
+            //记录数据
+            m_release_table[request]=message::Parkspace_release_response_msg();
+            //发送请求
+            return Communication_socket_base::encapsulate_msg(message);
+        }
+        default:
+            return Error_manager(PARKSPACE_REQUEST_MSG_TYPE_ERROR,NEGLIGIBLE_ERROR,"parkspace message table is not exist");
+    }
+
+}
+Error_manager Parkspace_communicator::execute_msg(Communication_message* p_msg)
+{
+    if(p_msg== nullptr)
+        return Error_manager(POINTER_IS_NULL,CRITICAL_ERROR,"parkspace response msg pointer is null");
+
+
+    //车位response消息
+    switch (p_msg->get_message_type())
+    {
+        ///测量结果反馈消息
+        case Communication_message::eParkspace_allocation_response_msg:
+        {
+            message::Parkspace_allocation_response_msg response;
+            response.ParseFromString(p_msg->get_message_buf());
+            message::Parkspace_allocation_request_msg request=create_request_by_response(response);
+            ///查询请求表是否存在,并且更新
+            if(m_alloc_table.find_update(request,response))
+            {
+                return Error_manager(PARKSPACE_ALLOCMSG_RESPONSE_HAS_NO_REQUEST,NEGLIGIBLE_ERROR,"parkspace alloc response without request");
+            }
+
+            break;
+        }
+        case Communication_message::eParkspace_search_response_msg:
+        {
+            message::Parkspace_search_response_msg response;
+            response.ParseFromString(p_msg->get_message_buf());
+            message::Parkspace_search_request_msg request=create_request_by_response(response);
+            ///查询请求表是否存在,并且更新
+            if(m_search_table.find_update(request,response))
+            {
+                return Error_manager(PARKSPACE_SEARCHMSG_RESPONSE_HAS_NO_REQUEST,NEGLIGIBLE_ERROR,"parkspace search response without request");
+            }
+            break;
+        }
+        case Communication_message::eParkspace_release_response_msg:
+        {
+            message::Parkspace_release_response_msg response;
+            response.ParseFromString(p_msg->get_message_buf());
+            message::Parkspace_release_request_msg request=create_request_by_response(response);
+            ///查询请求表是否存在,并且更新
+            if(m_release_table.find_update(request,response))
+            {
+                return Error_manager(PARKSPACE_RELEASEMSG_RESPONSE_HAS_NO_REQUEST,NEGLIGIBLE_ERROR,"parkspace release response without request");
+            }
+            break;
+        }
+            ///测量系统状态
+        case Communication_message::eParkspace_allocation_status_msg:
+        {
+            m_parkspace_status_msg=*p_msg;
+            break;
+        }
+    }
+    return SUCCESS;
+
+}
+/*
+ * 检测消息类型是否可被处理
+ */
+Error_manager Parkspace_communicator::check_msg(Communication_message* p_msg)
+{
+    //通过 p_msg->get_message_type() 和 p_msg->get_receiver() 判断这条消息是不是给我的.
+    //子类重载时, 增加自己模块的判断逻辑, 以后再写.
+    if ( (p_msg->get_message_type() == Communication_message::Message_type::eParkspace_allocation_response_msg
+        ||p_msg->get_message_type() == Communication_message::Message_type::eParkspace_search_response_msg
+        ||p_msg->get_message_type() == Communication_message::Message_type::eParkspace_release_response_msg
+        ||p_msg->get_message_type() == Communication_message::Message_type::eParkspace_allocation_status_msg)
+         && p_msg->get_receiver() == Communication_message::Communicator::eMain )
+    {
+        return Error_code::SUCCESS;
+    }
+    else
+    {
+        //认为接受人
+        return Error_code::INVALID_MESSAGE;
+    }
+    return SUCCESS;
+}
+/*
+ * 心跳发送函数,重载
+ */
+Error_manager Parkspace_communicator::encapsulate_send_data()
+{
+    return SUCCESS;
+}
+//检查消息是否可以被解析, 需要重载
+Error_manager Parkspace_communicator::check_executer(Communication_message* p_msg)
+{
+    return SUCCESS;
+}
+
+/*
+ * 根据接收到的response,生成对应的 request
+ */
+message::Parkspace_allocation_request_msg
+Parkspace_communicator::create_request_by_response(message::Parkspace_allocation_response_msg& response)
+{
+    message::Parkspace_allocation_request_msg request;
+    message::Base_info baseInfo;
+    baseInfo.set_msg_type(message::eLocate_request_msg);
+    baseInfo.set_sender(response.base_info().sender());
+    baseInfo.set_receiver(response.base_info().receiver());
+    request.mutable_base_info()->CopyFrom(baseInfo);
+    request.set_command_id(response.command_id());
+    request.set_terminal_id(response.command_id());
+    return request;
+}
+
+message::Parkspace_search_request_msg
+Parkspace_communicator::create_request_by_response(message::Parkspace_search_response_msg& response)
+{
+    message::Parkspace_search_request_msg request;
+    message::Base_info baseInfo;
+    baseInfo.set_msg_type(message::eLocate_request_msg);
+    baseInfo.set_sender(response.base_info().sender());
+    baseInfo.set_receiver(response.base_info().receiver());
+    request.mutable_base_info()->CopyFrom(baseInfo);
+    request.set_command_id(response.command_id());
+
+
+    return request;
+}
+
+message::Parkspace_release_request_msg
+Parkspace_communicator::create_request_by_response(message::Parkspace_release_response_msg& response)
+{
+    message::Parkspace_release_request_msg request;
+    message::Base_info baseInfo;
+    baseInfo.set_msg_type(message::eLocate_request_msg);
+    baseInfo.set_sender(response.base_info().sender());
+    baseInfo.set_receiver(response.base_info().receiver());
+    request.mutable_base_info()->CopyFrom(baseInfo);
+    request.set_command_id(response.command_id());
+    return request;
+}

+ 82 - 0
parkspace/Parkspace_communicator.h

@@ -0,0 +1,82 @@
+//
+// Created by zx on 2020/7/9.
+//
+
+#ifndef NNXX_TESTS_PARKSPACE_COMMUNICATOR_H
+#define NNXX_TESTS_PARKSPACE_COMMUNICATOR_H
+
+#include <parkspace_allocation_message.pb.h>
+#include "communication_socket_base.h"
+#include "singleton.h"
+#include "thread_safe_map.h"
+
+namespace message
+{
+    bool operator<(const message::Parkspace_allocation_request_msg& msg1,const message::Parkspace_allocation_request_msg& msg2);
+    bool operator==(const message::Parkspace_allocation_request_msg& msg1,const message::Parkspace_allocation_request_msg& msg2);
+
+    bool operator<(const message::Parkspace_search_request_msg& msg1,const message::Parkspace_search_request_msg& msg2);
+    bool operator==(const message::Parkspace_search_request_msg& msg1,const message::Parkspace_search_request_msg& msg2);
+
+    bool operator<(const message::Parkspace_release_request_msg& msg1,const message::Parkspace_release_request_msg& msg2);
+    bool operator==(const message::Parkspace_release_request_msg& msg1,const message::Parkspace_release_request_msg& msg2);
+}
+
+
+class Parkspace_communicator :public Singleton<Parkspace_communicator>, public Communication_socket_base
+{
+    friend Singleton<Parkspace_communicator>;
+public:
+    virtual ~Parkspace_communicator();
+    /*
+     * 请求分配车位
+     */
+    Error_manager alloc_request(message::Parkspace_allocation_request_msg& request,message::Parkspace_allocation_response_msg& result);
+
+    /*
+     * 查询车辆所在位置请求
+     */
+    Error_manager search_request(message::Parkspace_search_request_msg& request,message::Parkspace_search_response_msg& response);
+
+    /*
+     * 释放车位请求(停车失败或者取车完成时调用)
+     */
+    Error_manager release_request(message::Parkspace_release_request_msg& request,message::Parkspace_release_response_msg& response);
+
+
+    Error_manager check_statu();
+
+
+protected:
+    Parkspace_communicator();
+    virtual Error_manager encapsulate_msg(Communication_message* message);
+    virtual Error_manager execute_msg(Communication_message* p_msg);
+    /*
+     * 检测消息是否可被处理
+     */
+    virtual Error_manager check_msg(Communication_message* p_msg);
+    /*
+     * 心跳发送函数,重载
+     */
+    virtual Error_manager encapsulate_send_data();
+    //检查消息是否可以被解析, 需要重载
+    virtual Error_manager check_executer(Communication_message* p_msg);
+
+    /*
+     * 根据接收到的response,生成对应的 request
+     */
+    message::Parkspace_allocation_request_msg create_request_by_response(message::Parkspace_allocation_response_msg& msg);
+    message::Parkspace_search_request_msg create_request_by_response(message::Parkspace_search_response_msg& msg);
+    message::Parkspace_release_request_msg create_request_by_response(message::Parkspace_release_response_msg& msg);
+
+
+protected:
+    thread_safe_map<message::Parkspace_allocation_request_msg,message::Parkspace_allocation_response_msg>       m_alloc_table;
+    thread_safe_map<message::Parkspace_search_request_msg,message::Parkspace_search_response_msg>               m_search_table;
+    thread_safe_map<message::Parkspace_release_request_msg,message::Parkspace_release_response_msg>             m_release_table;
+
+    Communication_message                               m_parkspace_status_msg;
+};
+
+
+#endif //NNXX_TESTS_PARKSPACE_COMMUNICATOR_H

+ 2 - 1
proto.sh

@@ -1,3 +1,4 @@
 protoc -I=./message message_base.proto --cpp_out=./message
 protoc -I=./message measure_message.proto --cpp_out=./message
-protoc -I=./message hardware_message.proto --cpp_out=./message
+protoc -I=./message hardware_message.proto --cpp_out=./message
+protoc -I=./message parkspace_allocation_message.proto --cpp_out=./message

+ 152 - 0
system/StoreProcessTask.cpp

@@ -0,0 +1,152 @@
+//
+// Created by zx on 2020/7/7.
+//
+
+#include <Parkspace_communicator.h>
+#include "StoreProcessTask.h"
+
+StoreProcessTask::StoreProcessTask()
+{
+    m_command_id=-1;
+    m_terminor_id=-1;
+    mb_completed=false;
+}
+
+StoreProcessTask::~StoreProcessTask()
+{
+
+}
+
+Error_manager StoreProcessTask::init_task(unsigned int command_id, unsigned int terminor_id,std::string license)
+{
+    m_command_id=command_id;
+    m_terminor_id=terminor_id;
+    m_license=license;
+    return SUCCESS;
+}
+
+Error_manager StoreProcessTask::locate_step() {
+    message::Measure_request_msg request;
+    message::Base_info base_info;
+    base_info.set_msg_type(message::eLocate_request_msg);
+    base_info.set_sender(message::eMain);
+    base_info.set_receiver(message::eMeasurer);
+    base_info.set_timeout_ms(5000); //测量超时5s
+    request.mutable_base_info()->CopyFrom(base_info);
+
+    request.set_command_id(m_command_id);
+    request.set_terminal_id(m_terminor_id);
+
+    Error_manager code=Locate_communicator::get_instance_pointer()->locate_request(request,m_measure_response_msg);
+    if(code!=SUCCESS)
+        return code;
+
+    if(m_measure_response_msg.error_manager().error_code()==0)
+        return SUCCESS;
+    else
+        return Error_manager(FAILED,MINOR_ERROR,"measure response error_code error");
+
+}
+
+/*
+     * 分配车位
+     */
+Error_manager StoreProcessTask::alloc_space_step()
+{
+    /*
+     * 检查是否有测量数据
+     */
+    if(m_measure_response_msg.has_locate_information()==false)
+    {
+        return Error_manager(FAILED,MINOR_ERROR," parkspace alloc request without measure info");
+    }
+
+    message::Parkspace_allocation_request_msg request;
+    message::Base_info base_info;
+    base_info.set_msg_type(message::eParkspace_allocation_request_msg);
+    base_info.set_sender(message::eMain);
+    base_info.set_receiver(message::eTable);
+    base_info.set_timeout_ms(1000); //测量超时1s
+    request.mutable_base_info()->CopyFrom(base_info);
+
+    message::Car_info car_info;
+    car_info.set_license(m_license);
+    car_info.set_car_width(m_measure_response_msg.locate_information().locate_width());
+    car_info.set_car_height(m_measure_response_msg.locate_information().locate_height());
+    request.mutable_car_info()->CopyFrom(car_info);
+
+    request.set_command_id(m_command_id);
+    request.set_terminal_id(m_terminor_id);
+    request.mutable_car_info()->set_license(m_license);
+
+    Error_manager code=Parkspace_communicator::get_instance_pointer()->alloc_request(request,m_parcspace_alloc_response_msg);
+    if(code!=SUCCESS)
+        return code;
+
+    if(m_parcspace_alloc_response_msg.error_manager().error_code()==0)
+        return SUCCESS;
+    else
+        return Error_manager(FAILED,MINOR_ERROR,"parkspace alloc response error_code error");
+}
+
+/*
+ * 车位解锁,当停车失败时需要车位解锁
+ */
+Error_manager StoreProcessTask::release_space_step()
+{
+    /*
+    * 检查是否曾经分配过车位
+    */
+    if(m_parcspace_alloc_response_msg.has_allocated_space_info()==false)
+    {
+        return Error_manager(FAILED,MINOR_ERROR," parkspace release request without space info");
+    }
+
+    message::Parkspace_release_request_msg request;
+    message::Base_info base_info;
+    base_info.set_msg_type(message::eParkspace_release_request_msg);
+    base_info.set_sender(message::eMain);
+    base_info.set_receiver(message::eTable);
+    base_info.set_timeout_ms(1000); //测量超时1s
+    request.mutable_base_info()->CopyFrom(base_info);
+
+    message::Parkspace_info space_info=m_parcspace_alloc_response_msg.allocated_space_info();
+    request.mutable_release_space_info()->CopyFrom(space_info);
+
+    request.set_command_id(m_command_id);
+
+
+    message::Parkspace_release_response_msg release_response;
+    Error_manager code=Parkspace_communicator::get_instance_pointer()->release_request(request,release_response);
+    if(code!=SUCCESS)
+        return code;
+
+    if(release_response.error_manager().error_code()==0)
+        return SUCCESS;
+    else
+        return Error_manager(FAILED,MINOR_ERROR,"parkspace release response error_code error");
+}
+
+void StoreProcessTask::Main()
+{
+    Error_manager code;
+    //开始执行停车指令
+    //第一步测量
+    code=locate_step();
+    if(code!=SUCCESS)
+    {
+        LOG(ERROR) << "terminor id: "<< m_terminor_id<<" , "<<code.to_string();
+        return;
+    }
+
+    //第二步分配车位
+    code=alloc_space_step();
+    if(code!=SUCCESS)
+    {
+        LOG(ERROR) << "terminor id: "<< m_terminor_id<<" , "<<code.to_string();
+        return;
+    }
+
+    //执行动作
+
+}

+ 52 - 0
system/StoreProcessTask.h

@@ -0,0 +1,52 @@
+//
+// Created by zx on 2020/7/7.
+//
+
+#ifndef NNXX_TESTS_STOREPROCESS_H
+#define NNXX_TESTS_STOREPROCESS_H
+
+#include <parkspace_allocation_message.pb.h>
+#include "TaskQueue/BaseTask.h"
+#include "Locate_communicator.h"
+
+class StoreProcessTask :public tq::BaseTask{
+public:
+    StoreProcessTask();
+    virtual  ~StoreProcessTask();
+    Error_manager init_task(unsigned int command_id, unsigned int terminor_id,std::string license);
+
+protected:
+    virtual void Main();
+
+    /*
+     * 定位
+     */
+    Error_manager locate_step();
+
+    /*
+     * 分配车位
+     */
+    Error_manager alloc_space_step();
+
+   /*
+    * 车位解锁,当停车失败时需要车位解锁
+    */
+    Error_manager release_space_step();
+
+protected:
+    unsigned int                m_command_id;
+    unsigned int                m_terminor_id;
+    std::string                 m_license;          //当前流程的车辆标识(车牌号)
+
+
+    //以下的流程中产生的数据
+    message::Measure_response_msg                   m_measure_response_msg;         //测量数据
+    message::Parkspace_allocation_response_msg      m_parcspace_alloc_response_msg; //分配的车位数据
+
+public:
+    bool                        mb_completed;
+
+};
+
+
+#endif //NNXX_TESTS_STOREPROCESS_H

+ 5 - 0
system/TakeProcessTask.cpp

@@ -0,0 +1,5 @@
+//
+// Created by zx on 2020/7/7.
+//
+
+#include "TakeProcessTask.h"

+ 14 - 0
system/TakeProcessTask.h

@@ -0,0 +1,14 @@
+//
+// Created by zx on 2020/7/7.
+//
+
+#ifndef NNXX_TESTS_TAKEPROCESS_H
+#define NNXX_TESTS_TAKEPROCESS_H
+
+
+class TakeProcess {
+
+};
+
+
+#endif //NNXX_TESTS_TAKEPROCESS_H

+ 66 - 0
system/system_communicator.cpp

@@ -0,0 +1,66 @@
+//
+// Created by huli on 2020/6/28.
+//
+
+#include "system_communicator.h"
+
+System_communicator::System_communicator()
+{
+
+}
+
+System_communicator::~System_communicator()
+{
+
+}
+
+//定时封装发送消息, 一般为心跳和状态信息, 需要子类重载
+Error_manager System_communicator::encapsulate_send_data()
+{
+
+	return Error_code::SUCCESS;
+}
+
+/*
+ * 发送消息函数
+ */
+Error_manager System_communicator::encapsulate_msg(Communication_message* message)
+{
+    switch(message->get_message_type())
+    {
+        default:break;
+    }
+
+}
+
+/*
+ * 检测消息是否合法
+ */
+Error_manager System_communicator::check_msg(Communication_message* p_msg)
+{
+
+    return SUCCESS;
+}
+
+//检查消息是否可以被处理, 需要重载
+Error_manager System_communicator::check_executer(Communication_message* p_msg)
+{
+    return SUCCESS;
+}
+
+/*
+ * 处理接收到的消息
+ */
+Error_manager System_communicator::execute_msg(Communication_message* p_msg)
+{
+    /*
+     * 接收终端指令, 生成流程
+     */
+}
+
+
+
+
+
+
+

+ 42 - 0
system/system_communicator.h

@@ -0,0 +1,42 @@
+//
+// Created by huli on 2020/6/28.
+//
+
+#ifndef NNXX_TESTS_SYSTEM_COMMUNICATION_H
+#define NNXX_TESTS_SYSTEM_COMMUNICATION_H
+
+#include "../tool/singleton.h"
+#include "../communication/communication_socket_base.h"
+
+class System_communicator:public Singleton<System_communicator>, public Communication_socket_base
+{
+// 子类必须把父类设定为友元函数,这样父类才能使用子类的私有构造函数。
+   friend class Singleton<System_communicator>;
+private:
+ // 父类的构造函数必须保护,子类的构造函数必须私有。
+ System_communicator();
+public:
+    //必须关闭拷贝构造和赋值构造,只能通过 get_instance 函数来进行操作唯一的实例。
+    System_communicator(const System_communicator& other) = delete;
+    System_communicator& operator =(const System_communicator& other) = delete;
+    ~System_communicator();
+
+protected:
+    //重载函数
+    virtual Error_manager encapsulate_msg(Communication_message* message);
+    virtual Error_manager execute_msg(Communication_message* p_msg);
+    /*
+     * 检测消息是否可被处理
+     */
+    virtual Error_manager check_msg(Communication_message* p_msg);
+    /*
+     * 心跳发送函数,重载
+     */
+    virtual Error_manager encapsulate_send_data();
+    //检查消息是否可以被解析, 需要重载
+    virtual Error_manager check_executer(Communication_message* p_msg);
+    
+};
+
+
+#endif //NNXX_TESTS_SYSTEM_COMMUNICATION_H

+ 15 - 2
test/Locate_client.cpp

@@ -12,7 +12,7 @@
 int main()
 {
     nnxx::socket socket{ nnxx::SP, nnxx::BUS };
-    socket.bind("tcp://127.0.0.1:9006");
+    socket.bind("tcp://127.0.0.1:4444");
 
     int n=0;
 
@@ -37,8 +37,21 @@ int main()
             response.set_terminal_id(request.terminal_id());
             response.mutable_base_info()->CopyFrom(base_msg);
 
-
             int succ=int((rand()%1000)/999);
+            if(succ==0)
+            {
+                message::Locate_information locate_info;
+                locate_info.set_locate_x(0.9);
+                locate_info.set_locate_y(2.25);
+                locate_info.set_locate_height(1.8);
+                locate_info.set_locate_width(1.7);
+                locate_info.set_locate_length(4.5);
+                locate_info.set_locate_wheel_base(2.7);
+                locate_info.set_locate_angle(90.0);
+                locate_info.set_locate_correct(true);
+                response.mutable_locate_information()->CopyFrom(locate_info);
+            }
+
             error_code.set_error_code(succ);
             response.mutable_error_manager()->CopyFrom(error_code);
 

+ 33 - 0
tool/TaskQueue/BaseTask.cpp

@@ -0,0 +1,33 @@
+//
+//  BaseTaskQueue.cpp
+//  LibDriveRating-CXX
+//
+//  Created by Melo Yao on 6/9/14.
+//  Copyright (c) 2014 AutoNavi. All rights reserved.
+//
+
+#include "BaseTask.h"
+
+namespace tq {
+    BaseTask::BaseTask():ITask(),_cancelled(false)
+    {
+    }
+    
+    void BaseTask::Cancel()
+    {
+        _cancelled = true;
+    }
+    
+    bool BaseTask::IsCancelled() const
+    {
+        return _cancelled;
+    }
+    
+    void BaseTask::Run()
+    {
+        if (_cancelled) {
+            return;
+        }
+        Main();
+    }
+}

+ 29 - 0
tool/TaskQueue/BaseTask.h

@@ -0,0 +1,29 @@
+//
+//  BaseTaskQueue.h
+//  LibDriveRating-CXX
+//
+//  Created by Melo Yao on 6/9/14.
+//  Copyright (c) 2014 AutoNavi. All rights reserved.
+//
+
+#ifndef __LibDriveRating_CXX__BaseTaskQueue__
+#define __LibDriveRating_CXX__BaseTaskQueue__
+
+#include "TQInterface.h"
+namespace tq
+{
+    class BaseTask : public ITask
+    {
+    private:
+        volatile bool _cancelled;
+    public:
+        BaseTask();
+        void Run();
+        void Cancel();
+        bool IsCancelled() const;
+        
+        virtual void Main() = 0;
+        virtual TaskCategory GetCategory() const {return NoCategory;}
+    };
+}
+#endif /* defined(__LibDriveRating_CXX__BaseTaskQueue__) */

+ 23 - 0
tool/TaskQueue/TQFactory.cpp

@@ -0,0 +1,23 @@
+//
+//  TQFactory.cpp
+//  LibDriveRating-CXX
+//
+//  Created by Melo Yao on 6/10/14.
+//  Copyright (c) 2014 AutoNavi. All rights reserved.
+//
+
+#include "TQFactory.h"
+#include "ThreadTaskQueue.h"
+namespace tq {
+    IQueue* TQFactory::CreateDefaultQueue()
+    {
+        return new ThreadTaskQueue();
+    }
+    
+    void TQFactory::ReleaseQueue(IQueue* queue)
+    {
+        delete queue;
+    }
+    
+    
+}

+ 24 - 0
tool/TaskQueue/TQFactory.h

@@ -0,0 +1,24 @@
+//
+//  TQFactory.h
+//  LibDriveRating-CXX
+//
+//  Created by Melo Yao on 6/10/14.
+//  Copyright (c) 2014 AutoNavi. All rights reserved.
+//
+
+#ifndef __LibDriveRating_CXX__TQFactory__
+#define __LibDriveRating_CXX__TQFactory__
+
+#include "TQInterface.h"
+
+namespace tq {
+    class TQFactory
+    {
+    public:
+        static IQueue* CreateDefaultQueue();
+
+        static void ReleaseQueue(IQueue* queue);
+    };
+}
+
+#endif /* defined(__LibDriveRating_CXX__TQFactory__) */

+ 58 - 0
tool/TaskQueue/TQInterface.h

@@ -0,0 +1,58 @@
+//
+//  TQInterface.h
+//  LibDriveRating-CXX
+//
+//  Created by Melo Yao on 6/9/14.
+//  Copyright (c) 2014 AutoNavi. All rights reserved.
+//
+
+#ifndef __LibDriveRating_CXX__TQInterface__
+#define __LibDriveRating_CXX__TQInterface__
+
+namespace tq {
+    typedef unsigned long TaskCategory;
+
+    const TaskCategory NoCategory = 0;
+
+    class ITask
+    {
+    public:
+        virtual void Run() = 0;
+        virtual void Cancel() = 0;
+        virtual bool IsCancelled() const = 0;
+        virtual TaskCategory GetCategory() const = 0;
+        virtual ~ITask(){}
+    };
+    
+    typedef void (*TaskRecycler)(ITask* task,void* context);
+
+    class IQueue
+    {
+    public:
+        virtual void Start(unsigned int nThreads = 1) = 0;
+
+        virtual void Stop() = 0;
+
+        virtual void AddTask(ITask* task) = 0;
+        
+        virtual void GetTasks(ITask** tasksBuf, unsigned int taskBufSize) const= 0;
+        
+        virtual unsigned int TaskCount() const = 0;
+        
+        virtual void CancelAll() = 0;
+        
+        virtual void WaitForFinish() = 0;
+
+        virtual void Suspend() = 0;
+        
+        virtual void Resume() = 0;
+        
+        virtual void SetTaskRecycler(TaskCategory cat, TaskRecycler recycler,void *context){}
+
+        virtual void ClearTaskRecycler(TaskCategory cat){}
+
+        virtual ~IQueue() {}
+    };
+}
+
+#endif /* defined(__LibDriveRating_CXX__TQInterface__) */

+ 89 - 0
tool/TaskQueue/TaskPool.h

@@ -0,0 +1,89 @@
+#ifndef H_TASK_POOL_H
+#define H_TASK_POOL_H
+#include <list>
+#include "threadpp/threadpp.h"
+#include <cstdlib>
+#include <cstdio>
+namespace tq
+{
+    template <typename TaskType>
+    class TaskPool
+    {
+    public:
+        TaskPool(unsigned capacity = 10);
+        ~TaskPool();
+        TaskType* GetTask(TaskType const& taskPrototype);
+        void RecycleTask(TaskType* task);
+        void Purge();
+    private:
+        threadpp::lock _mutex;
+        std::list<TaskType*> _tasks;
+        unsigned _capacity;
+    };
+
+    template <typename TaskType>
+    TaskType* TaskPool<TaskType>::GetTask(TaskType const& taskPrototype)
+    {
+        _mutex.lock();
+        if(!_tasks.empty())
+        {
+
+            TaskType* taskptr = _tasks.front();
+            _tasks.pop_front();
+            _mutex.unlock();
+            new (taskptr)TaskType(taskPrototype);
+            return taskptr;
+        }
+        else
+        {
+            _mutex.unlock();
+            static int newcount = 0;
+            TaskType* taskptr = new TaskType(taskPrototype);
+            return taskptr;
+        }
+    }
+
+    template <typename TaskType>
+    void TaskPool<TaskType>::RecycleTask(TaskType* task)
+    {
+        (*task).~TaskType();
+        _mutex.lock();
+        if(_tasks.size()<_capacity)
+        {
+            _tasks.push_back(task);
+        }
+        else
+        {
+            free(task);
+        }
+        _mutex.unlock();
+    }
+    
+    template <typename TaskType>
+    void TaskPool<TaskType>::Purge()
+    {
+        _mutex.lock();
+        if(!_tasks.empty())
+        {
+            for(typename std::list<TaskType*>::const_iterator it = _tasks.begin();it!=_tasks.end();++it)
+            {
+                free(*it);
+            }
+            _tasks.clear();
+        }
+        _mutex.unlock();
+    }
+
+    template <typename TaskType>
+    TaskPool<TaskType>::TaskPool(unsigned capacity):
+    _capacity(capacity)
+    {
+    }
+
+    template <typename TaskType>
+    TaskPool<TaskType>::~TaskPool()
+    {
+        this->Purge();
+    }
+}
+#endif

+ 288 - 0
tool/TaskQueue/ThreadTaskQueue.cpp

@@ -0,0 +1,288 @@
+//
+//  ThreadTaskQueue.cpp
+//  LibDriveRating-CXX
+//
+//  Created by Melo Yao on 6/9/14.
+//  Copyright (c) 2014 AutoNavi. All rights reserved.
+//
+
+#include "ThreadTaskQueue.h"
+#include <algorithm>
+#define WAIT_TIMEOUT 5000
+
+using namespace threadpp;
+
+namespace tq{
+    
+    class QueueRunnable
+    {
+        ThreadTaskQueue* queue;
+        ITask* currentTask;
+    protected:
+        static void run_callback(void*);
+        thread* th;
+        
+        QueueRunnable(ThreadTaskQueue* q):queue(q),currentTask(NULL){}
+        void run();
+        void CancelCurrentTask();
+        bool TaskIsRunning() const;
+        friend class ThreadTaskQueue;
+    };
+    
+    void QueueRunnable::run_callback(void *ctx)
+    {
+        ((QueueRunnable*) ctx)->run();
+    }
+    
+    void QueueRunnable::run()
+    {
+        while (queue->IsStarted()) {
+            queue->LockQueue();
+            ITask* task = queue->NextTask();
+            if (task == NULL) {
+                queue->UnlockQueue();
+                continue;
+            }
+            currentTask = task;
+            queue->UnlockQueue();
+            task->Run();
+
+            queue->LockQueue();
+            currentTask = NULL;
+            queue->FinishTask(task);
+            queue->NotifyQueue();
+            queue->UnlockQueue();
+        }
+    }
+    
+    void QueueRunnable::CancelCurrentTask()
+    {
+        queue->LockQueue();
+        if(currentTask)
+        {
+            currentTask->Cancel();
+        }
+        queue->UnlockQueue();
+    }
+    
+    bool QueueRunnable::TaskIsRunning() const
+    {
+        return currentTask != NULL;
+    }
+    
+    ThreadTaskQueue::ThreadTaskQueue():_tasklist(),_started(false),_suspended(false)
+    {
+        
+    }
+    
+    void ThreadTaskQueue::Start(unsigned int nThreads)
+    {
+        _mutex.lock();
+        if (_started) {
+            _mutex.unlock();
+            return;
+        }
+        _started = true;
+        _threads.reserve(nThreads);
+        for (int i = 0; i<nThreads; ++i) {
+            QueueRunnable* runnable = new QueueRunnable(this);
+            runnable->th = new thread(QueueRunnable::run_callback, runnable);
+            _threads.push_back(runnable);
+        }
+        _mutex.unlock();
+    }
+    
+    void ThreadTaskQueue::Stop()
+    {
+        _mutex.lock();
+        if (!_started) {
+            _mutex.unlock();
+            return;
+        }
+        _started = false;
+        for (std::list<ITask*>::iterator it = _tasklist.begin(); it!= _tasklist.end(); ++it) {
+            delete *it;
+        }
+        _tasklist.clear();
+        _mutex.notify_all();
+        std::vector<QueueRunnable*> copy(_threads);
+        _threads.clear();
+        _mutex.unlock();
+        for (std::vector<QueueRunnable*>::iterator it = copy.begin(); it!=copy.end(); ++it) {
+            (*it)->th->join();
+            thread* t = (*it)->th;
+            delete (*it);
+            delete t;
+        }
+    }
+    
+    bool ThreadTaskQueue::IsStarted() const
+    {
+        return _started;
+    }
+
+
+    void ThreadTaskQueue::AddTask(ITask* task)
+    {
+        _mutex.lock();
+        if (_started) {
+            _tasklist.push_back(task);
+            _mutex.notify_all();
+        }
+        _mutex.unlock();
+    }
+    
+    void ThreadTaskQueue::GetTasks(ITask** tasksBuf, unsigned int taskBufSize) const
+    {
+        recursivelock* mutex = const_cast<recursivelock*>(&_mutex);
+        mutex->lock();
+        size_t count = 0;
+        for (std::list<ITask*>::const_iterator it = _tasklist.begin(); it!=_tasklist.end(); ++it) {
+            if (count<taskBufSize) {
+                tasksBuf[count] = *it;
+                count++;
+            }
+            else
+            {
+                break;
+            }
+        }
+        mutex->unlock();
+    }
+    
+    unsigned int ThreadTaskQueue::TaskCount() const
+    {
+        recursivelock* mutex = const_cast<recursivelock*>(&_mutex);
+        mutex->lock();
+        unsigned int count = (unsigned int)_tasklist.size();
+        mutex->unlock();
+        return count;
+    }
+    
+    void ThreadTaskQueue::CancelAll()
+    {
+        _mutex.lock();
+        for (std::vector<QueueRunnable*>::iterator it = _threads.begin(); it!=_threads.end(); ++it) {
+            (*it)->CancelCurrentTask();
+        }
+        for (std::list<ITask*>::const_iterator it = _tasklist.begin(); it!=_tasklist.end(); ++it) {
+            (*it)->Cancel();
+        }
+        _mutex.unlock();
+        
+    }
+    
+    void ThreadTaskQueue::WaitForFinish()
+    {
+        
+        while (true) {
+            _mutex.lock();
+            bool isExecuting = false;
+            for (std::vector<QueueRunnable*>::iterator it = _threads.begin(); it!=_threads.end(); ++it) {
+                if ((*it)->TaskIsRunning()) {
+                    isExecuting = true;
+                    break;
+                }
+            }
+            if (!isExecuting&&_tasklist.size() == 0) {
+                _mutex.unlock();
+                break;
+            }
+            _mutex.wait(100);
+            _mutex.unlock();
+        }
+        
+    }
+    
+    void ThreadTaskQueue::Suspend()
+    {
+        _mutex.lock();
+        _suspended = true;
+        _mutex.unlock();
+    }
+    
+    void ThreadTaskQueue::Resume()
+    {
+        _mutex.lock();
+        _suspended = false;
+        _mutex.notify_all();
+        _mutex.unlock();
+
+    }
+    
+    void ThreadTaskQueue::NotifyQueue()
+    {
+        _mutex.notify_all();
+    }
+    
+    ITask* ThreadTaskQueue::NextTask()
+    {
+        while (_started && (_tasklist.empty()||_suspended)) {
+            _mutex.wait(WAIT_TIMEOUT);//defensive waiting time limit.
+        }
+        ITask* task = NULL;
+        if (_tasklist.size()>0) {
+            task = _tasklist.front();
+            _tasklist.pop_front();
+        }
+        return task;
+    }
+    
+    inline
+    void ThreadTaskQueue::LockQueue()
+    {
+        _mutex.lock();
+    }
+    
+    inline
+    void ThreadTaskQueue::UnlockQueue()
+    {
+        _mutex.unlock();
+    }
+
+    inline
+    void ThreadTaskQueue::FinishTask(ITask* task)
+    {
+        if(task->GetCategory() != NoCategory)
+        {
+            _recyclerMutex.lock();
+            std::map<TaskCategory,RecyclerPair>::iterator it = _recyclers.find(task->GetCategory());
+            if(it!=_recyclers.end())
+            {
+                RecyclerPair pair = it->second;
+                _recyclerMutex.unlock();
+                pair.recycler(task,pair.context);
+                return;
+            }
+            _recyclerMutex.unlock();
+        }
+        //禁止析构
+        delete task;
+
+    }
+    
+    void ThreadTaskQueue::SetTaskRecycler(TaskCategory cat, TaskRecycler recycler,void *context)
+    {
+        _recyclerMutex.lock();
+        std::pair<TaskCategory,RecyclerPair> pair(cat, RecyclerPair(recycler,context));
+        _recyclers.insert(pair);
+        _recyclerMutex.unlock();
+    }
+
+    void ThreadTaskQueue::ClearTaskRecycler(TaskCategory cat)
+    {
+        _recyclerMutex.lock();
+        std::map<TaskCategory,RecyclerPair>::iterator it = _recyclers.find(cat);
+        if(it!=_recyclers.end())
+        {
+            _recyclers.erase(it);
+        }
+        _recyclerMutex.unlock();
+    }
+
+    ThreadTaskQueue::~ThreadTaskQueue()
+    {
+        this->Stop();//Defensive stop.
+    }
+    
+}

+ 89 - 0
tool/TaskQueue/ThreadTaskQueue.h

@@ -0,0 +1,89 @@
+//
+//  ThreadTaskQueue.h
+//  LibDriveRating-CXX
+//
+//  Created by Melo Yao on 6/9/14.
+//  Copyright (c) 2014 AutoNavi. All rights reserved.
+//
+
+#ifndef __LibDriveRating_CXX__ThreadTaskQueue__
+#define __LibDriveRating_CXX__ThreadTaskQueue__
+
+#include "TQInterface.h"
+#include "BaseTask.h"
+#include <list>
+#include <map>
+#include <vector>
+#include "threadpp/threadpp.h"
+
+namespace tq
+{
+    class QueueRunnable;
+    
+    class ThreadTaskQueue:public IQueue
+    {
+    public:
+        ThreadTaskQueue();
+        
+        void Start(unsigned int nThreads = 1);
+        
+        void Stop();
+        
+        bool IsStarted() const;
+
+        void AddTask(ITask* task);//Will transfer the ownership of task.
+        
+        void GetTasks(ITask** tasksBuf, unsigned int taskBufSize) const;
+        
+        unsigned int TaskCount() const;
+        
+        void CancelAll();
+        
+        void WaitForFinish() ;
+        
+        void Suspend();
+        
+        void Resume();
+
+        void SetTaskRecycler(TaskCategory cat, TaskRecycler recycler,void *context);
+
+        void ClearTaskRecycler(TaskCategory cat);
+        
+        ~ThreadTaskQueue();
+        
+    protected:
+        
+        void LockQueue();
+        
+        void UnlockQueue();
+        
+        void NotifyQueue();
+        
+        ITask* NextTask();
+
+        void FinishTask(ITask* task);
+        
+        friend class QueueRunnable;
+
+    private:
+        struct RecyclerPair
+        {
+            TaskRecycler recycler;
+            void *context;
+            RecyclerPair(TaskRecycler r,void* c):
+                recycler(r),context(c)
+            {
+            }
+        };
+
+        std::map<TaskCategory,RecyclerPair> _recyclers;
+        std::list<ITask*> _tasklist;
+        std::vector<QueueRunnable*> _threads;
+        threadpp::recursivelock _mutex;
+        threadpp::lock _recyclerMutex;
+        bool _started;
+        bool _suspended;
+    };
+}
+
+#endif /* defined(__LibDriveRating_CXX__ThreadTaskQueue__) */

+ 35 - 0
tool/TaskQueue/threadpp/impl/pthread_lock.h

@@ -0,0 +1,35 @@
+//
+//  pthread_lock.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef __threadpp__pthread_lock__
+#define __threadpp__pthread_lock__
+//extern "C"
+//{
+#include <pthread.h>
+//}
+namespace threadpp
+{
+    class pthread_lock
+    {
+        pthread_mutex_t _mutex;
+        pthread_cond_t _cond;
+        void operator=(const pthread_lock& l){};
+        pthread_lock(const pthread_lock& l){};
+    public:
+        pthread_lock();
+        ~pthread_lock();
+        void lock();
+        void unlock();
+        void wait();
+        void wait(unsigned long millisecs);
+        void notify();
+        void notify_all();
+    };
+}
+#include "pthread_lock.hpp"
+#endif /* defined(__threadpp__pthread_lock__) */

+ 73 - 0
tool/TaskQueue/threadpp/impl/pthread_lock.hpp

@@ -0,0 +1,73 @@
+//
+//  pthread_lock.cpp
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+#ifndef __threadpp__pthread_lock__hpp__
+#define __threadpp__pthread_lock__hpp__
+#include "../threadpp_assert.h"
+#include <errno.h>
+#include <cstring>
+
+#include <sys/time.h>
+
+static inline void timespec_for(struct timespec* t,unsigned long millisecs) {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    t->tv_nsec = tv.tv_usec*1000 + millisecs*1000000;
+    t->tv_sec = tv.tv_sec + (t->tv_nsec/1000000000);
+    t->tv_nsec = t->tv_nsec%1000000000;
+}
+
+namespace threadpp{
+    inline pthread_lock::pthread_lock()
+    {
+        pthread_mutex_init(&_mutex, NULL);
+        pthread_cond_init(&_cond, NULL);
+    }
+    
+    inline pthread_lock::~pthread_lock()
+    {
+        pthread_mutex_destroy(&_mutex);
+        pthread_cond_destroy(&_cond);
+    }
+    
+    inline void pthread_lock::lock()
+    {
+        int code = pthread_mutex_lock(&_mutex);
+        ASSERT(code == 0, "lock failed,error:%s",strerror(code));
+    }
+    
+    inline void pthread_lock::unlock()
+    {
+        int code = pthread_mutex_unlock(&_mutex);
+        ASSERT(code == 0, "unlock failed,error:%s",strerror(code));
+    }
+    
+    inline void pthread_lock::wait()
+    {
+        int code = pthread_cond_wait(&_cond, &_mutex);
+        ASSERT(code == 0 || code == ETIMEDOUT, "wait failed,error:%s",strerror(code));
+    }
+    
+    inline void pthread_lock::wait(unsigned long millisecs)
+    {
+        struct timespec ts;
+        timespec_for(&ts,millisecs);
+        int code = pthread_cond_timedwait(&_cond, &_mutex, &ts);
+        ASSERT(code == 0 || code == ETIMEDOUT, "timed wait failed,error:%s",strerror(code));
+    }
+    
+    inline void pthread_lock::notify()
+    {
+        pthread_cond_signal(&_cond);
+    }
+    
+    inline void pthread_lock::notify_all()
+    {
+        pthread_cond_broadcast(&_cond);
+    }
+}
+#endif

+ 45 - 0
tool/TaskQueue/threadpp/impl/pthread_thread.h

@@ -0,0 +1,45 @@
+//
+//  pthread_thread.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef __threadpp__pthread_thread__
+#define __threadpp__pthread_thread__
+#include <pthread.h>
+namespace threadpp
+{
+    class pthread_thread
+    {
+        struct pthread_context
+        {
+            void(*fp)(void* context);
+            void* context;
+        } _context;
+        
+        pthread_t _thread;
+        pthread_thread(){};
+        void operator=(const pthread_thread& t){};
+        pthread_thread(const pthread_thread& t){};
+        static void* pthread_fp_delegate(void*);
+    public:
+        typedef void (*runnable)(void* ctx);
+        typedef unsigned long long id_type;
+        
+        static id_type null_id();
+        
+        pthread_thread(runnable r,void* t);
+        
+        ~pthread_thread();
+        void join();
+        void detach();
+        bool is_equal(const pthread_thread& t) const;
+        id_type get_id() const;
+        static id_type current_thread_id();
+        static void sleep(unsigned long millisecs);
+    };
+}
+#include "pthread_thread.hpp"
+#endif /* defined(__threadpp__pthread_thread__) */

+ 110 - 0
tool/TaskQueue/threadpp/impl/pthread_thread.hpp

@@ -0,0 +1,110 @@
+//
+//  pthread_thread.cpp
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef __threadpp__pthread_thread__hpp__
+#define __threadpp__pthread_thread__hpp__
+
+#include <errno.h>
+#include "../threadpp_assert.h"
+#include <cstring>
+#include <cmath>
+#include <unistd.h>
+namespace threadpp
+{
+    inline pthread_thread::id_type pthread_thread::null_id()
+    {
+        return 0;
+    }
+    
+    inline void* pthread_thread::pthread_fp_delegate(void* ctx)
+    {
+        pthread_thread::pthread_context* pctx =static_cast<pthread_thread::pthread_context*>(ctx);
+        pctx->fp(pctx->context);
+        return NULL;
+    }
+    
+    inline pthread_thread::pthread_thread(runnable r,void* t)
+    {
+        _context.fp = r;
+        _context.context = t;
+        int code = pthread_create(&_thread, NULL, pthread_thread::pthread_fp_delegate, &_context);
+        ASSERT(code==0,"create thread failed,error:%s",strerror(code));
+    }
+    
+//    pthread_thread::pthread_thread(runnable r,void* t,float priority)
+//    {
+//        _context.fp = r;
+//        _context.context = t;
+//        pthread_attr_t tattr;
+//        pthread_attr_init(&tattr);
+//        struct sched_param schp;
+//        int policy = SCHED_FIFO;
+//        pthread_attr_getschedpolicy(&tattr, &policy);
+//        pthread_attr_getschedparam(&tattr, &schp);
+//        float pr =fminf(1.0f,fmaxf(0.0f, priority));
+//        schp.sched_priority = sched_get_priority_min(policy) + pr*(sched_get_priority_max(policy) - sched_get_priority_min(policy));
+//        pthread_attr_setschedparam(&tattr, &schp);
+//        int code = pthread_create(&_thread, &tattr, pthread_thread::pthread_fp_delegate, &_context);
+//        ASSERT(code==0,"create thread failed,error:%s",strerror(code));
+//        pthread_attr_destroy(&tattr);
+//    }
+    
+    inline pthread_thread::~pthread_thread()
+    {
+        ASSERT(_thread == 0,"%s","must join or detach a thread before destructing it");
+    }
+    
+    inline void pthread_thread::join()
+    {
+        void* ret = NULL;
+        int code = pthread_join(_thread, &ret);
+        _thread = 0;
+        ASSERT(code==0,"join thread failed,error:%s",strerror(code));
+    }
+    
+    inline void pthread_thread::detach()
+    {
+        int code = pthread_detach(_thread);
+        _thread = 0;
+        ASSERT(code==0,"join thread failed,error:%s",strerror(code));
+
+    }
+    
+    inline bool pthread_thread::is_equal(const pthread_thread& t) const
+    {
+        return pthread_equal(_thread, t._thread);
+    }
+    
+    inline void pthread_thread::sleep(unsigned long millisecs)
+    {
+        usleep((useconds_t)millisecs*1000);
+    }
+    
+    inline pthread_thread::id_type pthread_thread::get_id() const
+    {
+#ifdef __APPLE__
+        __uint64_t tid;
+        return pthread_threadid_np(_thread, &tid);
+        return tid;
+#else
+        return (unsigned long long)(_thread);
+#endif
+    }
+    
+    inline pthread_thread::id_type pthread_thread::current_thread_id()
+    {
+#ifdef __APPLE__
+        __uint64_t tid;
+        pthread_threadid_np(pthread_self(), &tid);
+        return tid;
+#else
+        return (unsigned long long)(pthread_self());
+#endif
+    }
+}
+#endif

+ 33 - 0
tool/TaskQueue/threadpp/impl/std_lock.h

@@ -0,0 +1,33 @@
+//
+//  std_lock.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef __threadpp__std_lock__
+#define __threadpp__std_lock__
+#include <mutex>
+#include <condition_variable>
+namespace threadpp
+{
+    class std_lock
+    {
+        std::mutex _mutex;
+        std::condition_variable_any _cond;
+        void operator=(const std_lock& l){};
+        std_lock(const std_lock& l){};
+    public:
+        std_lock();
+        ~std_lock();
+        void lock();
+        void unlock();
+        void wait();
+        void wait(unsigned long millisecs);
+        void notify();
+        void notify_all();
+    };
+}
+#include "std_lock.hpp"
+#endif /* defined(__threadpp__std_lock__) */

+ 52 - 0
tool/TaskQueue/threadpp/impl/std_lock.hpp

@@ -0,0 +1,52 @@
+//
+//  std_lock.cpp
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+#ifndef __threadpp__std_lock__hpp__
+#define __threadpp__std_lock__hpp__
+#include "../threadpp_assert.h"
+
+namespace threadpp{
+    
+    inline std_lock::std_lock():_mutex(),_cond()
+    {
+    }
+    
+    inline std_lock::~std_lock()
+    {
+    }
+    
+    inline void std_lock::lock()
+    {
+        _mutex.lock();
+    }
+    
+    inline void std_lock::unlock()
+    {
+        _mutex.unlock();
+    }
+    
+    inline void std_lock::wait()
+    {
+        _cond.wait(_mutex);
+    }
+    
+    inline void std_lock::wait(unsigned long millisecs)
+    {
+        _cond.wait_for(_mutex, std::chrono::milliseconds(millisecs));
+    }
+    
+    inline void std_lock::notify()
+    {
+        _cond.notify_one();
+    }
+    
+    inline void std_lock::notify_all()
+    {
+        _cond.notify_all();
+    }
+}
+#endif

+ 40 - 0
tool/TaskQueue/threadpp/impl/std_thread.h

@@ -0,0 +1,40 @@
+//
+//  std_thread.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef __threadpp__std_thread__
+#define __threadpp__std_thread__
+#include <thread>
+
+namespace threadpp
+{
+    class std_thread
+    {
+        std::thread _thread;
+        std_thread(){};
+        void operator=(const std_thread& t){};
+        std_thread(const std_thread& t){};
+    public:
+        typedef unsigned long long id_type;
+        
+        typedef void (*runnable)(void* ctx);
+        
+        static id_type null_id();
+        
+        std_thread(runnable r,void* t);
+        
+        ~std_thread();
+        void join();
+        void detach();
+        bool is_equal(const std_thread& t) const;
+        id_type get_id() const;
+        static id_type current_thread_id();
+        static void sleep(unsigned long millisecs);
+    };
+}
+#include "std_thread.hpp"
+#endif /* defined(__threadpp__std_thread__) */

+ 64 - 0
tool/TaskQueue/threadpp/impl/std_thread.hpp

@@ -0,0 +1,64 @@
+//
+//  std_thread.cpp
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+#ifndef __threadpp__std_thread__hpp__
+#define __threadpp__std_thread__hpp__
+#include <functional>
+#include <algorithm>
+namespace threadpp
+{
+    inline std_thread::id_type std_thread::null_id()
+    {
+        return 0;
+    }
+    
+    inline void* std_fp_delegate(std_thread::runnable r, void* context)
+    {
+        r(context);
+        return nullptr;
+    }
+    
+    inline std_thread::std_thread(runnable r,void* t):_thread(std::bind(std_fp_delegate,r,t))
+    {
+    }
+    
+    inline std_thread::~std_thread()
+    {
+        
+    }
+    
+    inline void std_thread::join()
+    {
+        _thread.join();
+    }
+    
+    inline void std_thread::detach()
+    {
+        _thread.detach();
+    }
+    
+    inline bool std_thread::is_equal(const std_thread& t) const
+    {
+        return _thread.get_id() == t._thread.get_id();
+    }
+    
+    inline std_thread::id_type std_thread::get_id() const
+    {
+        return std::hash<std::thread::id>()(_thread.get_id());
+    }
+    
+    inline void std_thread::sleep(unsigned long millisecs)
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(millisecs));
+    }
+    
+    inline std_thread::id_type std_thread::current_thread_id()
+    {
+        return std::hash<std::thread::id>()(std::this_thread::get_id());
+    }
+}
+#endif

+ 37 - 0
tool/TaskQueue/threadpp/impl/win_lock.h

@@ -0,0 +1,37 @@
+//
+//  win_lock.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef __threadpp__win_lock__
+#define __threadpp__win_lock__
+
+#include <windows.h>
+
+namespace threadpp
+{
+    class win_lock
+    {
+        CRITICAL_SECTION _mutex;
+        CONDITION_VARIABLE _cond;
+        volatile unsigned int _owner;
+        volatile unsigned int _count;
+        void operator=(const win_lock& l){};
+        win_lock(const win_lock& l){};
+    public:
+        win_lock();
+        ~win_lock();
+        void lock();
+        void unlock();
+        void wait();
+        void wait(unsigned long millisecs);
+        void notify();
+        void notify_all();
+    };
+}
+
+#include "win_lock.hpp"
+#endif /* defined(__threadpp__win_lock__) */

+ 80 - 0
tool/TaskQueue/threadpp/impl/win_lock.hpp

@@ -0,0 +1,80 @@
+//
+//  win_lock.cpp
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+#ifndef __threadpp__win_lock__hpp__
+#define __threadpp__win_lock__hpp__
+
+#include "win_thread.h"
+#include "../threadpp_assert.h"
+#include "stdio.h"
+namespace threadpp{
+    
+    static inline void test_error(const char* title)
+    {
+        DWORD e = GetLastError();
+        ASSERT(e==0,"%s failed,error:%d",title,e);
+    }
+    
+    inline win_lock::win_lock():_owner(0),_count(0)
+    {
+        SetLastError(0);
+        InitializeCriticalSection(&_mutex);
+        InitializeConditionVariable(&_cond);
+        test_error("init");
+    }
+    
+    inline win_lock::~win_lock()
+    {
+        DeleteCriticalSection(&_mutex);
+    }
+    
+    inline void win_lock::lock()
+    {
+        SetLastError(0);
+        
+        EnterCriticalSection(&_mutex);
+        
+        test_error("lock");
+    }
+    
+    inline void win_lock::unlock()
+    {
+        SetLastError(0);
+        LeaveCriticalSection(&_mutex);
+        test_error("unlock");
+    }
+    
+    inline void win_lock::wait()
+    {
+        SetLastError(0);
+        SleepConditionVariableCS(&_cond,&_mutex,0xFFFFFFFF);
+        test_error("wait");
+    }
+    
+    inline void win_lock::wait(unsigned long millisecs)
+    {
+        SetLastError(0);
+        SleepConditionVariableCS(&_cond,&_mutex,millisecs);
+        DWORD e = GetLastError();
+        ASSERT(e==0||e == ERROR_TIMEOUT,"timed wait failed,error:",e);
+    }
+    
+    inline void win_lock::notify()
+    {
+        SetLastError(0);
+        WakeConditionVariable(&_cond);
+        test_error("notify");
+    }
+    
+    inline void win_lock::notify_all()
+    {
+        SetLastError(0);
+        WakeAllConditionVariable(&_cond);
+        test_error("notify all");
+    }
+}
+#endif

+ 53 - 0
tool/TaskQueue/threadpp/impl/win_thread.h

@@ -0,0 +1,53 @@
+//
+//  win_thread.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef __threadpp__win_thread__
+#define __threadpp__win_thread__
+
+#include <windows.h>
+
+namespace threadpp
+{
+    class win_thread
+    {
+        struct win_context
+        {
+            void(*fp)(void*);
+            void* context;
+        } _context;
+#if NO_CRT
+        typedef DWORD handle_t;
+#else
+		typedef unsigned handle_t;
+#endif
+		static handle_t __stdcall win_fp_delegate(void* context);
+        handle_t _thread_id;
+        HANDLE _handle;
+        win_thread(){};
+        void operator=(const win_thread& t){};
+        win_thread(const win_thread& t){};
+    public:
+        typedef void (*runnable)(void* ctx);
+        typedef unsigned int id_type;
+        
+        static id_type null_id();
+        
+        win_thread(runnable r,void* t);
+        
+        ~win_thread();
+        void join();
+        void detach();
+        bool is_equal(const win_thread& t) const;
+        id_type get_id() const;
+        static id_type current_thread_id();
+        static void sleep(unsigned long millisecs);
+    };
+}
+
+#include "win_thread.hpp"
+#endif /* defined(__threadpp__win_thread__) */

+ 81 - 0
tool/TaskQueue/threadpp/impl/win_thread.hpp

@@ -0,0 +1,81 @@
+//
+//  win_thread.cpp
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+#ifndef __threadpp__win_thread__hpp__
+#define __threadpp__win_thread__hpp__
+
+#include "../threadpp_assert.h"
+#if NO_CRT
+#else
+#include <process.h>
+#endif
+namespace threadpp
+{
+
+    inline win_thread::id_type win_thread::null_id()
+    {
+        return 0;
+    }
+    
+	inline win_thread::handle_t win_thread::win_fp_delegate(void *context)
+    {
+        win_context* wctx = static_cast<win_context*>(context);
+        wctx->fp(wctx->context);
+        return 0;
+    }
+    
+    inline win_thread::win_thread(runnable r,void* t)
+    {
+        _context.fp = r;
+        _context.context = t;
+#if NO_CRT
+		_handle = CreateThread(NULL,NULL,win_thread::win_fp_delegate,&_context,0,&_thread_id);
+#else
+		_handle = (HANDLE)_beginthreadex(NULL,0,win_thread::win_fp_delegate,&_context,0,&_thread_id);
+#endif		
+    }
+    
+    inline win_thread::~win_thread()
+    {
+        ASSERT(_handle == 0,"%s","must join or detach a thread before destructing it");
+    }
+    
+    inline void win_thread::join()
+    {
+        unsigned code = WaitForSingleObject(_handle,0xFFFFFFFF);
+        CloseHandle(_handle);
+        _handle = 0;
+        ASSERT(code == WAIT_OBJECT_0 || code == WAIT_ABANDONED, "failed to join,error:%d",code);
+    }
+    
+    inline void win_thread::detach()
+    {
+		CloseHandle(_handle);
+        _handle = 0;
+    }
+    
+    inline bool win_thread::is_equal(const win_thread& t) const
+    {
+        return _thread_id == t._thread_id;
+    }
+    
+    inline void win_thread::sleep(unsigned long millisecs)
+    {
+		Sleep(millisecs);
+    }
+    
+	inline win_thread::id_type win_thread::get_id() const
+	{
+		return static_cast<unsigned int>(_thread_id);
+	}
+
+	inline win_thread::id_type win_thread::current_thread_id()
+	{
+		return  static_cast<unsigned int>(GetCurrentThreadId());
+	}
+}
+#endif

+ 101 - 0
tool/TaskQueue/threadpp/recursive_lock.h

@@ -0,0 +1,101 @@
+//
+//  recursive_lock.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/16/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef threadpp_recursive_lock_h
+#define threadpp_recursive_lock_h
+#include "threadpp_assert.h"
+namespace threadpp
+{
+    template <typename locktype,typename threadtype>
+    class recursive_lock
+    {
+        locktype _lock;
+        volatile typename threadtype::id_type _owner;
+        volatile unsigned int _count;
+    public:
+        recursive_lock();
+        void lock();
+        void unlock();
+        void wait();
+        void wait(unsigned long millisecs);
+        void notify();
+        void notify_all();
+    };
+    
+    template <typename locktype,typename threadtype>
+    recursive_lock<locktype,threadtype>::recursive_lock():_owner(threadtype::null_id()),_count(0)
+    {
+    }
+    
+    template <typename locktype,typename threadtype>
+    void recursive_lock<locktype,threadtype>::lock()
+    {
+        typename threadtype::id_type tid = threadtype::current_thread_id();
+        if(tid == _owner)
+        {
+            _count++;
+        }
+        else
+        {
+            _lock.lock();
+            _owner = tid;
+            _count=1;
+        }
+    }
+    
+    template <typename locktype,typename threadtype>
+    void recursive_lock<locktype,threadtype>::unlock()
+    {
+        typename threadtype::id_type tid = threadtype::current_thread_id();
+        ASSERT(tid == _owner,"%s", "unlock failed,try to unlock not owned mutex");
+        _count--;
+        if (_count == 0) {
+            _owner = threadtype::null_id();
+            _lock.unlock();
+        }
+    }
+    
+    template <typename locktype,typename threadtype>
+    void recursive_lock<locktype,threadtype>::wait()
+    {
+        typename threadtype::id_type owner = _owner;
+        unsigned count = _count;
+        _owner = threadtype::null_id();
+        _count = 0;
+        _lock.wait();
+        _owner = owner;
+        _count = count;
+
+    }
+    
+    template <typename locktype,typename threadtype>
+    void recursive_lock<locktype,threadtype>::wait(unsigned long millisecs)
+    {
+        typename threadtype::id_type owner = _owner;
+        unsigned count = _count;
+        _owner = threadtype::null_id();
+        _count = 0;
+        _lock.wait(millisecs);
+        _owner = owner;
+        _count = count;
+    }
+    
+    template <typename locktype,typename threadtype>
+    void recursive_lock<locktype,threadtype>::notify()
+    {
+        _lock.notify();
+    }
+    
+    template <typename locktype,typename threadtype>
+    void recursive_lock<locktype,threadtype>::notify_all()
+    {
+        _lock.notify_all();
+    }
+}
+
+#endif

+ 40 - 0
tool/TaskQueue/threadpp/threadpp.h

@@ -0,0 +1,40 @@
+//
+//  threadpp.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef threadpp_threadpp_h
+#define threadpp_threadpp_h
+#include "recursive_lock.h"
+#if __posix || __APPLE__ || __linux
+#include "impl/pthread_thread.h"
+#include "impl/pthread_lock.h"
+namespace threadpp
+{
+    typedef pthread_thread thread;
+    typedef pthread_lock lock;
+    typedef recursive_lock<pthread_lock, pthread_thread> recursivelock;
+}
+#elif defined(WIN32)
+#include "impl/win_thread.h"
+#include "impl/win_lock.h"
+namespace threadpp
+{
+    typedef win_thread thread;
+    typedef win_lock lock;
+    typedef recursive_lock<win_lock, win_thread> recursivelock;
+}
+#elif __cplusplus>=201103L
+#include "impl/std_thread.h"
+#include "impl/std_lock.h"
+namespace threadpp
+{
+    typedef std_thread thread;
+    typedef std_lock lock;
+    typedef recursive_lock<std_lock, std_thread> recursivelock;
+}
+#endif
+#endif

+ 33 - 0
tool/TaskQueue/threadpp/threadpp_assert.h

@@ -0,0 +1,33 @@
+//
+//  defines.h
+//  threadpp
+//
+//  Created by Melo Yao on 1/15/15.
+//  Copyright (c) 2015 Melo Yao. All rights reserved.
+//
+
+#ifndef threadpp_assert_h
+#define threadpp_assert_h
+
+//forward VC++ DEBUG symbol.
+#if defined(_DEBUG) && !defined(DEBUG)
+#define DEBUG _DEBUG
+#endif
+
+#if DEBUG //assertions
+#ifdef __cplusplus
+#include <cassert>
+#include <cstdio>
+#else
+#include <assert.h>
+#include <stdio.h>
+#endif
+#define ASSERT0(__cond__) assert(__cond__)
+#define ASSERT(__cond__,__msg__,...) \
+do {if(!(__cond__)){printf(__msg__,__VA_ARGS__);printf("\n");assert(false);}}while(0)
+#else
+#define ASSERT0(__cond__)
+#define ASSERT(__cond__,__msg__,...)
+#endif //assertions
+
+#endif

+ 31 - 2
tool/thread_safe_map.h

@@ -25,7 +25,36 @@ public:
         return dataMap_.erase(key);
     }
 
-    this_iterator find( const Key& key )
+    bool find_update(const Key& key,const Val& val)
+    {
+        std::lock_guard<std::mutex> lk(mtx_);
+        if(dataMap_.find(key)!=dataMap_.end()) {
+            dataMap_[key]=val;
+            return true;
+        }
+        return false;
+    }
+
+    bool find(const Key& key)
+    {
+        std::lock_guard<std::mutex> lk(mtx_);
+        if(dataMap_.find(key)!=dataMap_.end()) {
+            return true;
+        }
+        return false;
+    }
+
+    bool find(const Key& key,Val& val)
+    {
+        std::lock_guard<std::mutex> lk(mtx_);
+        if(dataMap_.find(key)!=dataMap_.end()) {
+            val=dataMap_[key];
+            return true;
+        }
+        return false;
+    }
+
+    /*this_iterator find( const Key& key )
     {
         std::lock_guard<std::mutex> lk(mtx_);
         return dataMap_.find(key);
@@ -34,7 +63,7 @@ public:
     {
         std::lock_guard<std::mutex> lk(mtx_);
         return dataMap_.find(key);
-    }
+    }*/
 
     this_iterator end()
     {