From 5ac52dc6412f8311b6cfbd0e99652c914d5c6168 Mon Sep 17 00:00:00 2001 From: Kazumasa Mitsunari Date: Fri, 25 May 2018 11:17:55 +0900 Subject: [Local]:5th step for blocking sequence Change-Id: Ic47c59a77d3b45f62bed8ee2617dddc4ed58afbe Signed-off-by: Kazumasa Mitsunari --- include/hmi-debug.h | 19 ++++++ src/app.cpp | 30 +++------ src/applist.cpp | 154 ++++++++++++++++++++++++++++++++----------- src/applist.hpp | 60 +++++++++-------- src/request.cpp | 12 +++- src/windowmanager-client.cpp | 32 ++++++--- src/windowmanager-client.hpp | 7 ++ 7 files changed, 216 insertions(+), 98 deletions(-) diff --git a/include/hmi-debug.h b/include/hmi-debug.h index 2bd3478..282386c 100644 --- a/include/hmi-debug.h +++ b/include/hmi-debug.h @@ -47,6 +47,8 @@ enum LOG_LEVEL{ #define HMI_SEQ_INFO(seq_num, args,...) _HMI_SEQ_LOG(LOG_LEVEL_INFO, __FILENAME__, __FUNCTION__, __LINE__, seq_num, args, ##__VA_ARGS__) #define HMI_SEQ_DEBUG(seq_num, args,...) _HMI_SEQ_LOG(LOG_LEVEL_DEBUG, __FILENAME__, __FUNCTION__, __LINE__, seq_num, args, ##__VA_ARGS__) +#define DUMP(args, ...) _DUMP(LOG_LEVEL_DEBUG, args, ##__VA_ARGS__) + static char ERROR_FLAG[6][20] = {"NONE", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG"}; static void _HMI_LOG(enum LOG_LEVEL level, const char* file, const char* func, const int line, const char* prefix, const char* log, ...) @@ -95,4 +97,21 @@ static void _HMI_SEQ_LOG(enum LOG_LEVEL level, const char* file, const char* fun va_end(args); free(message); } + +static void _DUMP(enum LOG_LEVEL level, const char *log, ...) +{ + const int log_level = (getenv("USE_HMI_DEBUG") == NULL) ? LOG_LEVEL_ERROR : atoi(getenv("USE_HMI_DEBUG")); + if (log_level < level) + { + return; + } + char *message; + va_list args; + va_start(args, log); + if (log == NULL || vasprintf(&message, log, args) < 0) + message = NULL; + fprintf(stderr, "%s \n", message); + va_end(args); + free(message); +} #endif //__HMI_DEBUG_H__ \ No newline at end of file diff --git a/src/app.cpp b/src/app.cpp index 4ec4059..7462c99 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -829,32 +829,22 @@ void App::process_request() void App::api_enddraw(char const *appid, char const *drawing_name) { std::string id(appid); - unsigned request_seq = app_list.lookUpAllocatingApp(id); + std::string role(drawing_name); unsigned current_seq = app_list.currentSequenceNumber(); - if (current_seq != request_seq) + bool result = app_list.setEndDrawFinished(current_seq, id, role); + if (!result) { - if (request_seq == 0) - { - HMI_ERROR("wm", "You don't have Window Resource"); - } - else - { - HMI_ERROR("wm", "unknown error. Application may not obey the sequence manner. please call endDraw after syncDraw"); - } + HMI_ERROR("wm", "%s doesn't have Window Resource", id.c_str()); return; } - std::string role = drawing_name; - //std::string area = drawing_area; - app_list.setEndDrawFinished(request_seq, role); - - if (app_list.endDrawFullfilled(request_seq)) + if (app_list.endDrawFullfilled(current_seq)) { // do task for endDraw - this->do_enddraw(request_seq); - app_list.removeRequest(request_seq); - HMI_SEQ_INFO(request_seq, "Finish sequence"); - app_list.setCurrentSequence(request_seq + 1); + this->do_enddraw(current_seq); + app_list.removeRequest(current_seq); + HMI_SEQ_INFO(current_seq, "Finish sequence"); + app_list.next(); if (app_list.haveRequest()) { this->process_request(); @@ -862,7 +852,7 @@ void App::api_enddraw(char const *appid, char const *drawing_name) } else { - HMI_SEQ_INFO(request_seq, "Wait other App call endDraw"); + HMI_SEQ_INFO(current_seq, "Wait other App call endDraw"); return; } for (unsigned i = 0, iend = this->pending_end_draw.size(); i < iend; i++) diff --git a/src/applist.cpp b/src/applist.cpp index 477a51b..be88977 100644 --- a/src/applist.cpp +++ b/src/applist.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include #include #include "applist.hpp" #include "../include/hmi-debug.h" @@ -25,11 +25,16 @@ using std::unique_ptr; namespace wm { -AppList::AppList(){} +AppList::AppList() + : req_list(0), + client_list(0), + current_seq(1) +{} + AppList::~AppList(){} -void AppList::addClient(const std::string &appid, const std::string &role){ - shared_ptr client(new WMClient(appid, role)); +void AppList::addClient(const string &appid, const string &role){ + shared_ptr client = std::make_shared(appid, role); client_list[appid] = client; } @@ -42,25 +47,31 @@ bool AppList::contains(const string &appid){ return (client_list.end() != result) ? true : false; } -/* -* Call contains before calling this function -*/ +/** + * @brief get WMClient object. Before call this function, must call "contains" + * to check the key is contained, otherwise, you have to take care of std::out_of_range. + * @param string[in] application id(key) + * @return WMClient object + */ shared_ptr AppList::lookUpClient(const string &appid) { - /* auto result = client_list.find(appid); - return (client_list.end() != result) ? - &(result->second()) : nullptr; */ - return client_list[appid]; + return client_list.at(appid); +} + +int AppList::countClient() +{ + return client_list.size(); } unsigned AppList::currentSequenceNumber(){ return current_seq; } +// Is this function necessary ? unsigned AppList::getSequenceNumber(const string &appid){ - for(auto x : req_list){ + for(const auto& x : req_list){ // Since app will not request twice and more, comparing appid is enough? - if( (x.appid == appid)) + if( (x.trigger.appid == appid)) { return x.seq_num; } @@ -69,9 +80,12 @@ unsigned AppList::getSequenceNumber(const string &appid){ } unsigned AppList::addAllocateRequest(WMRequest req){ - req.seq_num = req_list.back().seq_num + 1; - req.allocating = false; - req.end_draw_finished = false; + if(req_list.size() == 0){ + req.seq_num = 1; + } + else{ + req.seq_num = req_list.back().seq_num + 1; + } req_list.push_back(req); return req.seq_num; } @@ -80,37 +94,65 @@ bool AppList::requestFinished(){ return req_list.empty(); } -unsigned AppList::lookUpAllocatingApp(const string &appid){ - for(auto x: req_list){ - if(appid == x.appid){ - if(false == x.allocating) - return x.seq_num; +bool AppList::setAction(unsigned request_seq, const string &appid, const string &role, const string &area){ + bool result = false; + for (auto& x : req_list) + { + if (request_seq != x.seq_num) + { + continue; } + WMAction action{appid, role, area, false}; + + x.sync_draw_req.push_back(action); + result = true; + break; } - return 0; + return result; } -void AppList::setEndDrawFinished(unsigned request_seq, const string &role){ - for(auto x: req_list){ - if(request_seq == x.seq_num){ - if(role == x.role){ - x.end_draw_finished = true; +bool AppList::setEndDrawFinished(unsigned request_seq, const string &appid, const string &role){ + bool result = false; + for (auto& x : req_list) + { + if (request_seq < x.seq_num) + { + break; + } + if (request_seq == x.seq_num) + { + for(auto& y : x.sync_draw_req){ + if (y.appid == appid && y.role == role) + { + y.end_draw_finished = true; + result = true; + } } } } + req_dump(); + return result; } +/** + * @brief check all actions of the requested sequence is finished + * @param unsigned sequence_num + * @return true if all action is set. + */ bool AppList::endDrawFullfilled(unsigned request_seq){ bool result = false; - for (auto x : req_list) + for (const auto& x : req_list) { if(request_seq < x.seq_num){ break; } if(request_seq == x.seq_num){ - result = x.end_draw_finished && x.allocating; - if(result == false){ - break; + result = true; + for(const auto& y : x.sync_draw_req){ + result &= y.end_draw_finished; + if(!result){ + break; + } } } } @@ -119,19 +161,53 @@ bool AppList::endDrawFullfilled(unsigned request_seq){ void AppList::removeRequest(unsigned req_seq){ req_list.erase(remove_if(req_list.begin(), req_list.end(), - [req_seq](WMRequest x) { return x.seq_num == req_seq;} - )); + [req_seq](WMRequest x) { + return x.seq_num == req_seq; + })); } -void AppList::setCurrentSequence(unsigned req_seq){ - this->current_seq = req_seq; - if(0 == this->current_seq){ - this->current_seq = 1; - } +void AppList::next(){ + ++this->current_seq; + if (0 == this->current_seq) + { + this->current_seq = 1; + } } bool AppList::haveRequest(){ - return true; + return !req_list.empty(); +} + +void AppList::client_dump(){ + DUMP("======= client dump ====="); + for(const auto& x : client_list){ + const auto& y = x.second; + DUMP("APPID : %s", y->appID().c_str()); + } + DUMP("======= client dump end====="); } +void AppList::req_dump() +{ + DUMP("======= req dump ====="); + DUMP("current sequence: %d", current_seq); + for(const auto& x : req_list){ + DUMP("sequence number: %d", x.seq_num); + DUMP("Trigger : (APPID :%s, ROLE :%s, AREA :%s, TASK: %d)", + x.trigger.appid.c_str(), + x.trigger.role.c_str(), + x.trigger.area.c_str(), + x.trigger.task); + + for (const auto& y : x.sync_draw_req){ + DUMP( + "Action : (APPID :%s, ROLE :%s, AREA :%s, END_RAW_FINISHED: %d)", + y.appid.c_str(), + y.role.c_str(), + y.area.c_str(), + y.end_draw_finished); + } + } + DUMP("======= req dump end =====\n"); +} } \ No newline at end of file diff --git a/src/applist.hpp b/src/applist.hpp index 55355ef..5da91cf 100644 --- a/src/applist.hpp +++ b/src/applist.hpp @@ -33,19 +33,32 @@ typedef enum Task{ TASK_RELEASE }ResourceTask; -struct WMRequest{ +struct WMTriger { + std::string appid; + std::string role; + std::string area; + Task task; +}; + +struct WMAction +{ + std::string appid; + std::string role; + std::string area; + bool end_draw_finished; +}; + +struct WMRequest +{ + WMRequest(); explicit WMRequest(std::string appid, std::string role, std::string area, ResourceTask task); virtual ~WMRequest(); WMRequest(const WMRequest &obj); - std::string appid; - std::string role; - std::string area; - Task task; unsigned seq_num; - bool allocating; - bool end_draw_finished; + struct WMTriger trigger; + std::vector sync_draw_req; }; class AppList { @@ -58,6 +71,7 @@ public: void addClient(const std::string &appid, const std::string &role); void removeClient(const std::string &appid); bool contains(const std::string &appid); + int countClient(); std::shared_ptr lookUpClient(const std::string &appid); // Request Interface @@ -67,29 +81,21 @@ public: /* TODO: consider, which is better WMClient or std::string appid? if appid is key to manage resources, it is better to select std::string otherwise WMClient is better, IMO */ - bool requestFinished(); - unsigned lookUpAllocatingApp(const std::string &appid); - void setEndDrawFinished(unsigned request_seq, const std::string &role); - bool endDrawFullfilled(unsigned request_seq); - void removeRequest(unsigned request_seq); - void setCurrentSequence(unsigned request_seq); - bool haveRequest(); - /* void revertRequestingState(); - void removeAllRequesting(); */ - - //void revertRequestingState();//??? + bool requestFinished(); + bool setAction(unsigned request_seq, const std::string &appid, const std::string &role, const std::string &area); + bool setEndDrawFinished(unsigned request_seq, const std::string &appid, const std::string &role); + bool endDrawFullfilled(unsigned request_seq); + void removeRequest(unsigned request_seq); + void next(); + bool haveRequest(); - /* bool queue(int request_num); - bool pushTop(int request_num); - bool dequeue(); - void deleteAllElement(); - void removeElement(int request_num); - bool hasElement(int request_num); */ + void client_dump(); + void req_dump(); private: - std::vector req_list; - std::unordered_map> client_list; - unsigned current_seq; + std::vector req_list; + std::unordered_map> client_list; + unsigned current_seq; }; } diff --git a/src/request.cpp b/src/request.cpp index 415a80d..2e674d8 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -20,8 +20,13 @@ namespace wm { using std::string; -WMRequest::WMRequest(string appid, string role, string area, Task task){ +WMRequest::WMRequest(){} +WMRequest::WMRequest(string appid, string role, string area, Task task) + : seq_num(0), + trigger{appid, role, area, task}, + sync_draw_req(0) +{ } WMRequest::~WMRequest(){ @@ -29,8 +34,9 @@ WMRequest::~WMRequest(){ } WMRequest::WMRequest(const WMRequest &obj){ - + this->seq_num = obj.seq_num; + this->trigger = obj.trigger; + this->sync_draw_req = obj.sync_draw_req; } - } \ No newline at end of file diff --git a/src/windowmanager-client.cpp b/src/windowmanager-client.cpp index 876ab9f..bc24978 100644 --- a/src/windowmanager-client.cpp +++ b/src/windowmanager-client.cpp @@ -13,7 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include // for debug +using std::cerr;//debug +using std::cout;//debug +using std::endl;//debug #include "windowmanager-client.hpp" namespace wm { @@ -21,27 +24,42 @@ namespace wm { using std::string; const std::vector wm_events = { + // Private event for applications "syncDraw", "flushDraw", "visible", "invisible", "active", "inactive" }; WMClient::WMClient(const string &appid, unsigned layerID, unsigned surfaceID, const string &role) :id(appid), - layer(layerID) + layer(layerID), + roles(0), + surfaces(0) { roles.push_back(role); surfaces.push_back(surfaceID); for(auto x: wm_events){ +#if GTEST_ENABLED + string ev = x; +#else afb_event ev = afb_daemon_make_event(x.c_str()); +#endif event_list[x] = ev; } } WMClient::WMClient(const string &appid, const string &role) - :id(appid) + : id(appid), + layer(0), + roles(0), + surfaces(0), + event_list(0) { roles.push_back(role); for(auto x: wm_events){ +#if GTEST_ENABLED + string ev = x; +#else afb_event ev = afb_daemon_make_event(x.c_str()); +#endif event_list[x] = ev; } } @@ -49,12 +67,8 @@ WMClient::WMClient(const string &appid, const string &role) WMClient::~WMClient(){ } -/* const std::vector> surfaceIDList(){ - +string WMClient::appID(){ + return this->id; } -std::optional surfaceID(role); - -} */ - } \ No newline at end of file diff --git a/src/windowmanager-client.hpp b/src/windowmanager-client.hpp index 045055b..fccaba7 100644 --- a/src/windowmanager-client.hpp +++ b/src/windowmanager-client.hpp @@ -34,6 +34,8 @@ public: WMClient(const std::string &appid, unsigned layerID, unsigned surfaceID, const std::string &role); WMClient(const std::string &appid, const std::string &role); virtual ~WMClient(); + + std::string appID(); //WMClient::WMClient(const WMClient &obj); /* const std::vector> surfaceIDList(); optional surfaceID(role); */ @@ -43,7 +45,12 @@ public: std::vector surfaces; std::string id; std::vector roles; +#if GTEST_ENABLED +// This is for unit test. afb_make_event occurs sig11 if call not in afb-binding + std::unordered_map event_list; +#else std::unordered_map event_list; +#endif //std::vector requestingTask; }; } -- cgit 1.2.3-korg