diff --git a/legacy/evas/src/bin/evas_cserve2.h b/legacy/evas/src/bin/evas_cserve2.h index 98c65471f6..91c6999a47 100644 --- a/legacy/evas/src/bin/evas_cserve2.h +++ b/legacy/evas/src/bin/evas_cserve2.h @@ -288,7 +288,7 @@ void cserve2_cache_stats_get(Client *client, unsigned int rid); void cserve2_cache_font_debug(Client *client, unsigned int rid); -Font_Request *cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request_Funcs *funcs, void *data); +Font_Request *cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request *dep, Font_Request_Funcs *funcs, void *data); void cserve2_request_waiter_add(Font_Request *req, unsigned int rid, Client *client); void cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err); void cserve2_request_cancel_all(Font_Request *req, Error_Type err); diff --git a/legacy/evas/src/bin/evas_cserve2_cache.c b/legacy/evas/src/bin/evas_cserve2_cache.c index 12fdec33ae..7704764d16 100644 --- a/legacy/evas/src/bin/evas_cserve2_cache.c +++ b/legacy/evas/src/bin/evas_cserve2_cache.c @@ -2460,7 +2460,7 @@ cserve2_cache_font_load(Client *client, const char *source, unsigned int sourcel fs->references++; DBG("adding FONT_LOAD '%s' request.", fs->name); fe->request = cserve2_request_add(CSERVE2_REQ_FONT_LOAD, rid, - client, &_font_load_funcs, fe); + client, NULL, &_font_load_funcs, fe); eina_hash_direct_add(font_entries, fe, fe); @@ -2518,7 +2518,7 @@ cserve2_cache_font_glyphs_load(Client *client, const char *source, unsigned int else { cserve2_request_add(CSERVE2_REQ_FONT_GLYPHS_LOAD, rid, - client, &_glyphs_load_funcs, req); + client, req->fe->request, &_glyphs_load_funcs, req); } return 0; } diff --git a/legacy/evas/src/bin/evas_cserve2_requests.c b/legacy/evas/src/bin/evas_cserve2_requests.c index 11a2e0bb1b..e4a8d34510 100644 --- a/legacy/evas/src/bin/evas_cserve2_requests.c +++ b/legacy/evas/src/bin/evas_cserve2_requests.c @@ -68,6 +68,9 @@ struct _Font_Request Eina_List *waiters; Eina_Bool processing; Font_Request_Funcs *funcs; + Font_Request *dependency; + Eina_List *dependents; /* list of requests that depend on this one finishing */ + Eina_Bool locked : 1; /* locked waiting for a dependency request to finish */ }; struct _Waiter @@ -105,7 +108,7 @@ _request_waiter_add(Font_Request *req, Client *client, unsigned int rid) } Font_Request * -cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request_Funcs *funcs __UNUSED__, void *data) +cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request *dep, Font_Request_Funcs *funcs, void *data) { Font_Request *req, *r; @@ -138,7 +141,7 @@ cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Fo if (!req) { DBG("Add request for rid: %d", rid); - req = malloc(sizeof(*req)); + req = calloc(1, sizeof(*req)); req->type = type; req->data = data; req->waiters = NULL; @@ -148,6 +151,13 @@ cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Fo EINA_INLIST_GET(req)); } + if (dep && !req->dependency) + { + req->locked = EINA_TRUE; + dep->dependents = eina_list_append(dep->dependents, req); + req->dependency = dep; + } + _request_waiter_add(req, client, rid); _cserve2_requests_process(); @@ -161,6 +171,21 @@ cserve2_request_waiter_add(Font_Request *req, unsigned int rid, Client *client) _request_waiter_add(req, client, rid); } +static void +_request_dependents_cancel(Font_Request *req, Error_Type err) +{ + Font_Request *dep; + + EINA_LIST_FREE(req->dependents, dep) + { + dep->locked = EINA_FALSE; + dep->dependency = NULL; + /* Maybe we need a better way to inform the creator of the request + * that it was cancelled because its dependency failed? */ + cserve2_request_cancel_all(dep, err); + } +} + void cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err) { @@ -180,6 +205,12 @@ cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err) } } + if (req->dependency) + req->dependency->dependents = eina_list_remove( + req->dependency->dependents, req); + + _request_dependents_cancel(req, err); + // TODO: When we have speculative preload, there may be no waiters, // so we need a flag or something else to make things still load. if ((!req->waiters) && (!req->processing)) @@ -210,9 +241,15 @@ cserve2_request_cancel_all(Font_Request *req, Error_Type err) free(w); } + _request_dependents_cancel(req, err); + if (req->processing) return; + if (req->dependency) + req->dependency->dependents = eina_list_remove( + req->dependency->dependents, req); + requests[req->type].waiting = eina_inlist_remove( requests[req->type].waiting, EINA_INLIST_GET(req)); req->funcs->msg_free(req->msg, req->data); @@ -247,6 +284,9 @@ _cserve2_request_failed(Font_Request *req, Error_Type type) req->funcs->msg_free(req->msg, req->data); requests[req->type].processing = eina_inlist_remove( requests[req->type].processing, EINA_INLIST_GET(req)); + + _request_dependents_cancel(req, type); + free(req); } @@ -254,7 +294,7 @@ static void _slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd, void *msg, void *data) { Slave_Worker *sw = data; - Font_Request *req = sw->data; + Font_Request *dep, *req = sw->data; Eina_List **working, **idle; Waiter *w; @@ -276,6 +316,13 @@ _slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd, void *msg, void *data) free(msg); requests[req->type].processing = eina_inlist_remove( requests[req->type].processing, EINA_INLIST_GET(req)); + + EINA_LIST_FREE(req->dependents, dep) + { + dep->locked = EINA_FALSE; + dep->dependency = NULL; + } + free(req); sw->data = NULL; @@ -416,6 +463,9 @@ _cserve2_requests_process(void) Font_Request *req = EINA_INLIST_CONTAINER_GET( requests[rtype].waiting, Font_Request); + if (req->locked) + continue; + requests[rtype].waiting = eina_inlist_remove( requests[rtype].waiting, requests[rtype].waiting); requests[rtype].processing = eina_inlist_append(