From e624fd6eb09dbe5729389437263e1e116e58fdbd Mon Sep 17 00:00:00 2001 From: Kazumasa Mitsunari Date: Tue, 15 May 2018 11:37:39 +0900 Subject: [PATCH 1/1] [Local]:2nd step for blocking sequence Change-Id: I267b9cdbc4a95b80a0b6cada688ed251e3093611 Signed-off-by: Kazumasa Mitsunari --- src/allocate_queue.hpp | 13 ++++++ src/app.cpp | 102 +++++++++++++++++++++++++++++++++++++++++-- src/app.hpp | 8 +++- src/windowmanager-client.hpp | 7 ++- 4 files changed, 124 insertions(+), 6 deletions(-) diff --git a/src/allocate_queue.hpp b/src/allocate_queue.hpp index 2a977b1..68b9008 100644 --- a/src/allocate_queue.hpp +++ b/src/allocate_queue.hpp @@ -27,7 +27,20 @@ public: ~AllocateRequestList(); AllocateRequestList(const AllocateRequestList &obj) = delete; + typedef std::function onEndDraw; + typedef std::function onReverted; + + // Client Database Interface void addClient(WMClient* client); + WMClient* loopUpClient(const char* appid); + + // Request Interface + bool hasRequestingApp(const char *appid); + void revertRequestingState(); + void removeAllRequesting(); + bool addRequest(WMClient *, onEndDraw, onReverted); + + //void revertRequestingState();//??? /* bool queue(int request_num); bool pushTop(int request_num); diff --git a/src/app.cpp b/src/app.cpp index 53a645e..6d3f1bb 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -38,6 +38,8 @@ #include "windowmanager-client.hpp" #include "allocate_queue.hpp" +#define TIME_OUT 1000000UL /* 1s */ + namespace wm { /* DrawingArea name used by "{layout}.{area}" */ @@ -94,6 +96,16 @@ struct result load_layer_map(char const *filename) { } // namespace +static int App::processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata){ + HMI_NOTICE("Time out occurs because the client replys endDraw slow, so revert the request"); + reinterpret_cast(userdata)->timerHandler(); +} + +void App::timerHandler(){ + // TODO: write reset process + unsigned seq = allocate_list.curerntSequenceNumber(); + allocate_list.resetRequest(seq); +} /** * App Impl @@ -336,15 +348,73 @@ void App::layout_commit() { this->display->flush(); } -void App::api_activate_surface(char const *drawing_name, char const *drawing_area, const reply_func &reply) { +void App::api_activate_surface(char const *appid, char const *drawing_name, char const *drawing_area, const reply_func &reply) { ST(); + /* + * Check Phase + */ + auto const &surface_id = this->lookup_id(drawing_name); + std::string role = std::string(drawing_name); + // newState = checkPolicy(role); + const WMClient* client = allocate_list.loopUpClient(appid); + if(client != nullptr){ + reply("client is not registered"); + return; + } + auto const &surface_id_tmp = client->surfaceID(role); + auto const &layer_id_tmp = client->layerID(); - if (!surface_id) { - reply("Surface does not exist"); + if(!surface_id_tmp && !layer_id_tmp){ + reply("invalid window manager client"); + HMI_DEBUG("appid:%s, requested_role:%s, surfaceID:%d in layer %d", + appid, role, surface_id_tmp, layer_id_tmp); + } + + /* + * Queueing Phase + */ + static unsigned ++sequence_number; + unsigned current = allocate_list.curerntSequenceNumber(); + + if(sequence_number != current){ + // Add request, then invoked after the previous task is finished + allocate_list.addAllocateRequest(client, sequence_number, tasks); + reply(nullptr); return; + } + + /* + * Do allocate tasks + */ + do { + // TODO: Tasks will be changed according to policy manager result + // do task(onTransition (activate)) + }while (!allocate_list.requestFinished()) + + // lm_.updateLayout(jobj); + // TODO: emit syncDraw with application + do{ + client->emit_syncdraw(role); + }while (!allocate_list.requestFinished()); + + if(timer_ev_src != nullptr){ + // firsttime set into sd_event + int ret = sd_event_add_time(afb_daemon_get_event_loop(), &timer_ev_src, + CLOCK_BOOTTIME, time(NULL) + TIME_OUT, 0, processTimerHandler, this); } + else{ + // update timer limitation after second time + sd_event_source_set_time(timer_ev_src, time(NULL) + TIME_OUT); + sd_event_source_set_enabled(timer_ev_src, SD_EVENT_ONESHOT); + } + + if (!surface_id) + { + reply("Surface does not exist"); + return; + } if (!this->controller->surface_exists(*surface_id)) { reply("Surface does not exist in controller!"); @@ -492,6 +562,7 @@ void App::api_activate_surface(char const *drawing_name, char const *drawing_are void App::api_deactivate_surface(char const *drawing_name, const reply_func &reply) { ST(); auto const &surface_id = this->lookup_id(drawing_name); + WMClient* client = allocate_list.lookupClient(appid); if (!surface_id) { reply ("Surface does not exist"); @@ -593,6 +664,31 @@ void App::check_flushdraw(int surface_id) { } void App::api_enddraw(char const *drawing_name) { + unsigned request_seq = allocate_list.searchAllocatingApp(appid); + unsigned current_seq = allocate_list.currentSequence(); + if(current_seq != request_seq){ + if(request_seq == 0){ + HMI_ERROR("[req_num:%d] You don't have Window Resource", request_seq); + } + else{ + HMI_ERROR("[req_num:%d] unknown error. Application may not obey the sequence manner. please call endDraw after syncDraw"); + } + return; + } + allocate_list.allocate(appid, request_seq); + if(allocate_list.endDrawFullfilled(request_seq)){ + // do task for endDraw + do{ + // visible application + }while(false); + do{ + // emit flush Draw + allocate_list.resetRequest(request_seq); + }while(false); + } + else{ + // wait other apps call endDraw + } for (unsigned i = 0, iend = this->pending_end_draw.size(); i < iend; i++) { auto n = this->lookup_name(this->pending_end_draw[i]); if (n && *n == drawing_name) { diff --git a/src/app.hpp b/src/app.hpp index 5cfd78f..e7a9ae0 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -203,7 +203,7 @@ struct App { result api_request_surface(char const *drawing_name, char const *appid, int flag); char const *api_request_surface(char const *drawing_name, char const *ivi_id); - void api_activate_surface(char const *drawing_name, char const *drawing_area, const reply_func &reply); + void api_activate_surface(char const *appid, char const *drawing_name, char const *drawing_area, const reply_func &reply); void api_deactivate_surface(char const *drawing_name, const reply_func &reply); void api_enddraw(char const *drawing_name); result api_get_display_info(); @@ -216,7 +216,10 @@ struct App { void surface_created(uint32_t surface_id); void surface_removed(uint32_t surface_id); -private: + // Do not use this function + static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata); + + private: optional lookup_id(char const *name); optional lookup_name(int id); @@ -226,6 +229,7 @@ private: void check_flushdraw(int surface_id); int init_layers(); + void timerHandler(); void surface_set_layout(int surface_id, optional sub_surface_id = nullopt); void layout_commit(); diff --git a/src/windowmanager-client.hpp b/src/windowmanager-client.hpp index 6aec0f3..bf0a9d7 100644 --- a/src/windowmanager-client.hpp +++ b/src/windowmanager-client.hpp @@ -33,14 +33,19 @@ public: WMClient(const char* appid, unsigned layerID, unsigned surfaceID, const char* role); virtual ~WMClient(); //WMClient::WMClient(const WMClient &obj); + const vector> surfaceIDList(); + optional surfaceID(role); + bool hasRequestingApp(appid); + void createNewRequest(int count, const vector &applist); -private: + private: unsigned layer; std::vector surfaces; std::string appid; std::vector roles; std::unordered_map event_list; unsigned request_number; + std::vector requestingTask; }; } -- 2.16.6