Add support for a request to depend on another
authorsachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 29 Jun 2012 22:03:57 +0000 (22:03 +0000)
committersachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 29 Jun 2012 22:03:57 +0000 (22:03 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@73058 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/bin/evas_cserve2.h
src/bin/evas_cserve2_cache.c
src/bin/evas_cserve2_requests.c

index 98c6547..91c6999 100644 (file)
@@ -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);
index 12fdec3..7704764 100644 (file)
@@ -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;
 }
index 11a2e0b..e4a8d34 100644 (file)
@@ -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(