Move image opening/loading to the new requests system
authorsachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 17 Jul 2012 14:23:09 +0000 (14:23 +0000)
committersachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 17 Jul 2012 14:23:09 +0000 (14:23 +0000)
A lot going on here:
 - Request callbacks were adapted to fit the new scheme
 - The old requests systems in the cache was wiped out
 - Old slave handling in evas_cserve2_main.c is dead too
 - PRELOAD commands are responded with LOADED now

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@73984 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/bin/evas_cserve2.h
src/bin/evas_cserve2_cache.c
src/bin/evas_cserve2_client.c
src/bin/evas_cserve2_main.c
src/bin/evas_cserve2_requests.c
src/lib/cserve2/evas_cs2.h
src/lib/cserve2/evas_cs2_client.c

index 27c7df6..a671bee 100644 (file)
@@ -209,7 +209,9 @@ typedef enum {
 } Font_Rend_Flags;
 
 typedef enum {
-   CSERVE2_REQ_FONT_LOAD = 0,
+   CSERVE2_REQ_IMAGE_OPEN = 0,
+   CSERVE2_REQ_IMAGE_LOAD,
+   CSERVE2_REQ_FONT_LOAD,
    CSERVE2_REQ_FONT_GLYPHS_LOAD,
    CSERVE2_REQ_LAST
 } Font_Request_Type;
@@ -298,9 +300,6 @@ void cserve2_request_cancel_all(Font_Request *req, Error_Type err);
 void cserve2_requests_init(void);
 void cserve2_requests_shutdown(void);
 
-void cserve2_cache_requests_process(void);
-void cserve2_cache_requests_response(Slave_Command type, void *msg, void *data);
-
 void cserve2_font_init(void);
 void cserve2_font_shutdown(void);
 void *cserve2_font_slave_cb(Slave_Thread_Data *sd, Slave_Command *cmd, const void *cmddata, void *data);
index 3a31033..327f3f8 100644 (file)
 #include "evas_cserve2.h"
 #include "evas_cs2_utils.h"
 
-typedef struct _Request_Funcs Request_Funcs;
-typedef struct _Request Request;
-
 typedef struct _Entry Entry;
 typedef struct _Reference Reference;
-typedef struct _Waiter Waiter;
 typedef struct _File_Data File_Data;
 typedef struct _Image_Data Image_Data;
 typedef struct _File_Watch File_Watch;
@@ -25,23 +21,6 @@ typedef struct _Font_Source Font_Source;
 typedef struct _Font_Entry Font_Entry;
 typedef struct _Font_Cache Font_Cache;
 
-typedef void *(*Request_Msg_Create)(Entry *e, int *size);
-typedef void (*Request_Response)(Entry *e, void *resp);
-typedef void (*Request_Error)(Entry *e, Error_Type error);
-
-struct _Request_Funcs {
-   Request_Msg_Create msg_create;
-   Request_Response response;
-   Request_Error error;
-};
-
-struct _Request {
-   Entry *entry;
-   Eina_List *waiters;
-   Eina_Bool processing;
-   Request_Funcs *funcs;
-};
-
 typedef enum {
    CSERVE2_IMAGE_FILE,
    CSERVE2_IMAGE_DATA,
@@ -51,7 +30,7 @@ typedef enum {
 struct _Entry {
    unsigned int id;
    Eina_List *references;
-   Request *request;
+   Font_Request *request;
    Entry_Type type;
 #ifdef DEBUG_LOAD_TIME
    struct timeval load_start;
@@ -179,21 +158,11 @@ struct _Reference {
    int count;
 };
 
-struct _Waiter {
-   Reference *ref;
-   unsigned int rid;
-   Message_Type type;
-};
-
 struct _File_Watch {
    const char *path;
    Eina_List *entries;
 };
 
-static Eina_List *open_requests = NULL;
-static Eina_List *load_requests = NULL;
-static Eina_List *spload_requests = NULL; // speculative preload requests
-
 static unsigned int _file_id = 0; // id unique number
 static unsigned int _image_id = 0; // id unique number
 static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
@@ -259,79 +228,84 @@ _entry_load_reused(Entry *e)
 #endif
 }
 
+static Msg_Opened *
+_image_opened_msg_create(File_Data *entry, int *size)
+{
+   Msg_Opened *msg;
+
+   msg = calloc(1, sizeof(*msg));
+   msg->base.type = CSERVE2_OPENED;
+   msg->image.w = entry->w;
+   msg->image.h = entry->h;
+   msg->image.frame_count = entry->frame_count;
+   msg->image.loop_count = entry->loop_count;
+   msg->image.loop_hint = entry->loop_hint;
+   msg->image.alpha = entry->alpha;
+
+   *size = sizeof(*msg);
+
+   return msg;
+}
+
 static void
 _image_opened_send(Client *client, File_Data *entry, unsigned int rid)
 {
     int size;
-    Msg_Opened msg;
+    Msg_Opened *msg;
 
     DBG("Sending OPENED reply for entry: %d and RID: %d.", entry->base.id, rid);
     // clear the struct with possible paddings, since it is not aligned.
-    memset(&msg, 0, sizeof(msg));
-    msg.base.rid = rid;
-    msg.base.type = CSERVE2_OPENED;
-    msg.image.w = entry->w;
-    msg.image.h = entry->h;
-    msg.image.frame_count = entry->frame_count;
-    msg.image.loop_count = entry->loop_count;
-    msg.image.loop_hint = entry->loop_hint;
-    msg.image.alpha = entry->alpha;
-
-    size = sizeof(msg);
+
+    msg = _image_opened_msg_create(entry, &size);
+    msg->base.rid = rid;
+
     cserve2_client_send(client, &size, sizeof(size));
-    cserve2_client_send(client, &msg, sizeof(msg));
-    // _cserve2_cache_load_requests_process();
+    cserve2_client_send(client, msg, size);
+
+    free(msg);
 }
 
-static void
-_image_loaded_send(Client *client, Image_Data *entry, unsigned int rid)
+static Msg_Loaded *
+_image_loaded_msg_create(Image_Data *entry, int *size)
 {
-   int size;
+   Msg_Loaded *msg;
    const char *shmpath = cserve2_shm_name_get(entry->shm);
-   Msg_Loaded msg;
    int path_len;
    char *buf;
 
-   DBG("Sending LOADED reply for entry %d and RID: %d.", entry->base.id, rid);
    path_len = strlen(shmpath) + 1;
 
-   memset(&msg, 0, sizeof(msg));
-   msg.base.rid = rid;
-   msg.base.type = CSERVE2_LOADED;
+   *size = sizeof(*msg) + path_len;
+   msg = calloc(1, *size);
+   msg->base.type = CSERVE2_LOADED;
 
-   msg.shm.mmap_offset = cserve2_shm_map_offset_get(entry->shm);
-   msg.shm.use_offset = cserve2_shm_offset_get(entry->shm);
-   msg.shm.mmap_size = cserve2_shm_map_size_get(entry->shm);
-   msg.shm.image_size = cserve2_shm_size_get(entry->shm);
-   msg.alpha_sparse = entry->alpha_sparse;
+   msg->shm.mmap_offset = cserve2_shm_map_offset_get(entry->shm);
+   msg->shm.use_offset = cserve2_shm_offset_get(entry->shm);
+   msg->shm.mmap_size = cserve2_shm_map_size_get(entry->shm);
+   msg->shm.image_size = cserve2_shm_size_get(entry->shm);
+   msg->alpha_sparse = entry->alpha_sparse;
 
-   buf = malloc(sizeof(msg) + path_len);
-
-   memcpy(buf, &msg, sizeof(msg));
-   memcpy(buf + sizeof(msg), shmpath, path_len);
-
-   size = sizeof(msg) + path_len;
-
-   cserve2_client_send(client, &size, sizeof(size));
-   cserve2_client_send(client, buf, size);
+   buf = (char *)msg + sizeof(*msg);
+   memcpy(buf, shmpath, path_len);
 
-   free(buf);
+   return msg;
 }
 
 static void
-_image_preloaded_send(Client *client, unsigned int rid)
+_image_loaded_send(Client *client, Image_Data *entry, unsigned int rid)
 {
    int size;
-   Msg_Preloaded msg;
+   Msg_Loaded *msg;
 
-   DBG("Sending PRELOADED reply for RID: %d.", rid);
-   memset(&msg, 0, sizeof(msg));
-   msg.base.rid = rid;
-   msg.base.type = CSERVE2_PRELOADED;
+   DBG("Sending LOADED reply for entry %d and RID: %d.", entry->base.id, rid);
+
+   msg = _image_loaded_msg_create(entry, &size);
+   msg->base.rid = rid;
 
-   size = sizeof(msg);
    cserve2_client_send(client, &size, sizeof(size));
-   cserve2_client_send(client, &msg, size);
+   cserve2_client_send(client, msg, size);
+
+   free(msg);
 }
 
 static void
@@ -379,41 +353,18 @@ _open_request_build(File_Data *f, int *bufsize)
 }
 
 static void
-_request_failed(Entry *e, Error_Type type)
+_request_free(void *msg, void *data __UNUSED__)
 {
-   Waiter *w;
-   Eina_List *l;
-   Reference *ref;
-
-   DBG("Request for entry %p failed with error %d", e, type);
-   EINA_LIST_FREE(e->request->waiters, w)
-     {
-        cserve2_client_error_send(w->ref->client, w->rid, type);
-
-        w->ref->count--;
-        free(w);
-     }
-
-   EINA_LIST_FOREACH(e->references, l, ref)
-     {
-        Eina_Hash *hash = NULL;
-        if (e->type == CSERVE2_IMAGE_FILE)
-          hash = ref->client->files.referencing;
-        else if (e->type == CSERVE2_IMAGE_DATA)
-          hash = ref->client->images.referencing;
-        else
-          continue;
-
-        eina_hash_del_by_key(hash, &(ref->client_entry_id));
-     }
+   free(msg);
 }
 
-static void
-_open_request_response(File_Data *e, Slave_Msg_Image_Opened *resp)
+static Msg_Opened *
+_open_request_response(File_Data *e, Slave_Msg_Image_Opened *resp, int *size)
 {
-   Waiter *w;
-
    _entry_load_finish(&e->base);
+
+   e->base.request = NULL;
+
    e->w = resp->w;
    e->h = resp->h;
    e->frame_count = resp->frame_count;
@@ -427,19 +378,36 @@ _open_request_response(File_Data *e, Slave_Msg_Image_Opened *resp)
         e->loader_data = eina_stringshare_add(ldata);
      }
 
-   DBG("Finished opening file %d. Notifying %d waiters.", e->base.id,
-       e->base.request->waiters ? eina_list_count(e->base.request->waiters) : 0);
-   EINA_LIST_FREE(e->base.request->waiters, w)
+   return _image_opened_msg_create(e, size);
+}
+
+static void
+_request_failed(Entry *e, Error_Type type __UNUSED__)
+{
+   Eina_List *l;
+   Reference *ref;
+
+   e->request = NULL;
+
+   EINA_LIST_FOREACH(e->references, l, ref)
      {
-        _image_opened_send(w->ref->client, e, w->rid);
-        free(w);
+        Eina_Hash *hash = NULL;
+        if (e->type == CSERVE2_IMAGE_FILE)
+          hash = ref->client->files.referencing;
+        else if (e->type == CSERVE2_IMAGE_DATA)
+          hash = ref->client->images.referencing;
+        else
+          continue;
+
+        eina_hash_del_by_key(hash, &(ref->client_entry_id));
      }
 }
 
-static Request_Funcs _open_funcs = {
-   .msg_create = (Request_Msg_Create)_open_request_build,
-   .response = (Request_Response)_open_request_response,
-   .error = (Request_Error)_request_failed
+static Font_Request_Funcs _open_funcs = {
+   .msg_create = (Font_Request_Msg_Create)_open_request_build,
+   .msg_free = _request_free,
+   .response = (Font_Request_Response)_open_request_response,
+   .error = (Font_Request_Error)_request_failed
 };
 
 static void *
@@ -507,35 +475,25 @@ _load_request_build(Image_Data *i, int *bufsize)
    return buf;
 }
 
-static void
-_load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp)
+static Msg_Loaded *
+_load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size)
 {
-   Waiter *w;
-
    _entry_load_finish(&e->base);
 
+   e->base.request = NULL;
+
    e->alpha_sparse = resp->alpha_sparse;
    if (!e->doload)
      DBG("Entry %d loaded by speculative preload.", e->base.id);
 
-   DBG("Finished loading image %d. Notifying %d waiters.", e->base.id,
-       e->base.request->waiters ? eina_list_count(e->base.request->waiters) : 0);
-   EINA_LIST_FREE(e->base.request->waiters, w)
-     {
-        if (w->type == CSERVE2_LOAD)
-          _image_loaded_send(w->ref->client, e, w->rid);
-        else if (w->type == CSERVE2_PRELOAD)
-          _image_preloaded_send(w->ref->client, w->rid);
-        // else w->type == CSERVE2_SETOPTS --> do nothing
-
-        free(w);
-     }
+   return _image_loaded_msg_create(e, size);
 }
 
-static Request_Funcs _load_funcs = {
-   .msg_create = (Request_Msg_Create)_load_request_build,
-   .response = (Request_Response)_load_request_response,
-   .error = (Request_Error)_request_failed
+static Font_Request_Funcs _load_funcs = {
+   .msg_create = (Font_Request_Msg_Create)_load_request_build,
+   .msg_free = _request_free,
+   .response = (Font_Request_Response)_load_request_response,
+   .error = (Font_Request_Error)_request_failed
 };
 
 static unsigned int
@@ -591,19 +549,7 @@ _image_entry_free(Image_Data *entry)
    File_Data *fentry = entry->file;
 
    if (entry->base.request)
-     {
-        if (entry->base.request->processing)
-          entry->base.request->entry = NULL;
-        else if (!entry->base.request->waiters)
-          {
-             if (entry->doload)
-               load_requests = eina_list_remove(load_requests,
-                                                entry->base.request);
-             else
-               spload_requests = eina_list_remove(spload_requests,
-                                                  entry->base.request);
-          }
-     }
+     cserve2_request_cancel_all(entry->base.request, CSERVE2_REQUEST_CANCEL);
 
    if (entry->unused)
      {
@@ -646,16 +592,7 @@ _file_entry_free(File_Data *entry)
      }
 
    if (entry->base.request)
-     {
-        if (entry->base.request->processing)
-          entry->base.request->entry = NULL;
-        else if (!entry->base.request->waiters)
-          {
-             open_requests = eina_list_remove(open_requests,
-                                              entry->base.request);
-             free(entry->base.request);
-          }
-     }
+     cserve2_request_cancel_all(entry->base.request, CSERVE2_REQUEST_CANCEL);
 
    if ((fw = entry->watcher))
      {
@@ -851,96 +788,6 @@ cserve2_cache_shutdown(void)
    eina_hash_free(font_sources);
 }
 
-static void
-_request_answer_del(Eina_List **requests, Request *req, Client *client, Error_Type err)
-{
-   Eina_List *l, *l_next;
-   Waiter *it;
-
-   DBG("Removing answer requests from entry: %d, client: %d",
-       req->entry->id, client->id);
-
-   EINA_LIST_FOREACH_SAFE(req->waiters, l, l_next, it)
-     {
-        if (it->ref->client->id == client->id)
-          {
-             cserve2_client_error_send(client, it->rid, err);
-             req->waiters = eina_list_remove_list(req->waiters, l);
-             free(it);
-          }
-     }
-
-   // FIXME: Should this be really here? I guess that it should be in the
-   // entry_free_cb function, or entry_reference_del, when there are no more
-   // references
-   if (!req->entry && !req->waiters)
-     {
-        *requests = eina_list_remove(*requests, req);
-        free(req);
-     }
-}
-
-static void
-_request_answer_all_del(Eina_List **requests, Request *req, Error_Type err)
-{
-   Waiter *it;
-
-   DBG("Removing all answer requests from entry: %d", req->entry->id);
-
-   EINA_LIST_FREE(req->waiters, it)
-     {
-        cserve2_client_error_send(it->ref->client, it->rid, err);
-        free(it);
-     }
-
-   *requests = eina_list_remove(*requests, req);
-   free(req);
-}
-
-static void
-_request_answer_add(Request *req, Reference *ref, unsigned int rid, Message_Type type)
-{
-   Waiter *w = malloc(sizeof(*w));
-
-   w->ref = ref;
-   w->rid = rid;
-   w->type = type;
-
-   DBG("Add answer request for entry id: %d, client: %d, rid: %d",
-       req->entry->id, ref->client->id, rid);
-   req->waiters = eina_list_append(req->waiters, w);
-}
-
-static void
-_request_add(Eina_List **requests, Entry *entry, Reference *ref, unsigned int rid, Message_Type type)
-{
-   Request *req;
-
-   // add the request if it doesn't exist yet
-   if (!entry->request)
-     {
-        req = malloc(sizeof(*req));
-        req->entry = entry;
-        req->waiters = NULL;
-        req->processing = EINA_FALSE;
-        entry->request = req;
-        if (type == CSERVE2_OPEN)
-          req->funcs = &_open_funcs;
-        else
-          req->funcs = &_load_funcs;
-        *requests = eina_list_append(*requests, req);
-        DBG("Add request for entry id: %d, client: %d, rid: %d",
-            req->entry->id, ref->client->id, rid);
-     }
-   else
-     req = entry->request;
-
-   if (type != CSERVE2_SETOPTS)
-     _request_answer_add(req, ref, rid, type);
-   else
-     DBG("Adding entry for speculative preload: id=%d", req->entry->id);
-}
-
 static Reference *
 _entry_reference_add(Entry *entry, Client *client, unsigned int client_entry_id)
 {
@@ -957,104 +804,6 @@ _entry_reference_add(Entry *entry, Client *client, unsigned int client_entry_id)
    return ref;
 }
 
-static int
-_cserve2_cache_open_requests_process(int nloaders)
-{
-   Request *req;
-   char *slave_cmd_data;
-   int slave_cmd_size;
-
-   while ((nloaders > 0) && (open_requests))
-     {
-        // remove the first element from the list and process this element
-        req = eina_list_data_get(open_requests);
-        open_requests = eina_list_remove_list(open_requests, open_requests);
-
-        DBG("Processing OPEN request for file entry: %d", req->entry->id);
-
-        slave_cmd_data = req->funcs->msg_create(req->entry, &slave_cmd_size);
-
-        cserve2_slave_cmd_dispatch(req, IMAGE_OPEN, slave_cmd_data,
-                                   slave_cmd_size);
-
-        free(slave_cmd_data);
-
-        req->processing = EINA_TRUE;
-        nloaders--;
-     }
-
-   return nloaders;
-}
-
-static int
-_cserve2_cache_load_requests_list_process(Eina_List **queue, int nloaders)
-{
-   Eina_List *skipped = NULL;
-   Request *req;
-
-   while ((nloaders > 0) && (*queue))
-     {
-        Image_Data *ientry;
-        char *buf;
-        int size;
-
-        // remove the first element from the list and process this element
-        req = eina_list_data_get(*queue);
-        *queue = eina_list_remove_list(*queue, *queue);
-
-        ientry = (Image_Data *)req->entry;
-        if (!ientry->file)
-          {
-             ERR("File entry doesn't exist for entry id %d", req->entry->id);
-             _request_failed(req->entry, CSERVE2_INVALID_CACHE);
-             continue;
-          }
-
-        if (ientry->file->base.request)
-          {
-             /* OPEN still pending, skip this request */
-             skipped = eina_list_append(skipped, req);
-             continue;
-          }
-
-        DBG("Processing LOAD request for image entry: %d", req->entry->id);
-
-        buf = req->funcs->msg_create(req->entry, &size);
-
-        cserve2_slave_cmd_dispatch(req, IMAGE_LOAD, buf, size);
-
-        free(buf);
-
-        req->processing = EINA_TRUE;
-
-        nloaders--;
-     }
-
-   EINA_LIST_FREE(skipped, req)
-      *queue = eina_list_append(*queue, req);
-
-   return nloaders;
-}
-
-static void
-_cserve2_cache_load_requests_process(int nloaders)
-{
-   nloaders = _cserve2_cache_load_requests_list_process(&load_requests,
-                                                        nloaders);
-   _cserve2_cache_load_requests_list_process(&spload_requests, nloaders - 1);
-}
-
-
-void
-cserve2_cache_requests_process(void)
-{
-   int avail_loaders;
-
-   avail_loaders = cserve2_slave_available_get();
-   avail_loaders = _cserve2_cache_open_requests_process(avail_loaders);
-   _cserve2_cache_load_requests_process(avail_loaders);
-}
-
 static void
 _entry_unused_push(Image_Data *e)
 {
@@ -1130,20 +879,15 @@ _entry_free_cb(void *data)
 
    entry = ref->entry;
 
-   if (entry->request && !entry->request->processing)
+   /* XXX: handle the case of requests being processed gracefully */
+   if (entry->request /*&& !entry->request->processing*/)
      {
         if (entry->type == CSERVE2_IMAGE_FILE)
-          _request_answer_del(&open_requests, entry->request, ref->client,
-                              CSERVE2_REQUEST_CANCEL);
+          cserve2_request_cancel(entry->request, ref->client,
+                                 CSERVE2_REQUEST_CANCEL);
         else if (entry->type == CSERVE2_IMAGE_DATA)
-          {
-             if (((Image_Data *)entry)->doload)
-               _request_answer_del(&load_requests, entry->request,
-                                   ref->client, CSERVE2_REQUEST_CANCEL);
-             else
-               _request_answer_del(&spload_requests, entry->request,
-                                   ref->client, CSERVE2_REQUEST_CANCEL);
-          }
+          cserve2_request_cancel(entry->request, ref->client,
+                                 CSERVE2_REQUEST_CANCEL);
      }
 
    _entry_reference_del(entry, ref);
@@ -1253,15 +997,9 @@ _file_changed_cb(const char *path __UNUSED__, Eina_Bool deleted __UNUSED__, void
           {
              _image_id_free(ie);
              eina_hash_set(image_entries, &ie->base.id, NULL);
-             if (ie->base.request && !ie->base.request->processing)
-               {
-                  if (ie->doload)
-                    _request_answer_all_del(&load_requests, ie->base.request,
-                                            CSERVE2_FILE_CHANGED);
-                  else
-                    _request_answer_all_del(&spload_requests, ie->base.request,
-                                            CSERVE2_FILE_CHANGED);
-               }
+             if (ie->base.request /*&& !ie->base.request->processing*/)
+               cserve2_request_cancel_all(ie->base.request,
+                                          CSERVE2_FILE_CHANGED);
              ie->base.request = NULL;
              if (ie->unused)
                _image_entry_free(ie);
@@ -1269,9 +1007,8 @@ _file_changed_cb(const char *path __UNUSED__, Eina_Bool deleted __UNUSED__, void
 
         _file_id_free(e);
         eina_hash_set(file_entries, &e->base.id, NULL);
-        if (e->base.request && !e->base.request->processing)
-          _request_answer_all_del(&open_requests, e->base.request,
-                                  CSERVE2_FILE_CHANGED);
+        if (e->base.request /*&& !e->base.request->processing*/)
+          cserve2_request_cancel_all(e->base.request, CSERVE2_FILE_CHANGED);
         e->base.request = NULL;
         if (!e->images && !e->base.references)
           _file_entry_free(e);
@@ -1853,7 +1590,7 @@ _image_file_entry_stats_cb(const Eina_Hash *hash __UNUSED__, const void *key __U
    msg->images.files_size += sizeof(File_Data) +
       eina_list_count(fd->images) * sizeof(Eina_List *) +
       eina_list_count(fd->base.references) *
-         (sizeof(Request) + sizeof(Eina_List *));
+         (sizeof(Font_Request *) + sizeof(Eina_List *));
 
 #ifdef DEBUG_LOAD_TIME
    // accounting file entries load time
@@ -2144,7 +1881,7 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char
 
         // File already being loaded, just add the request to be replied
         if (entry->base.request)
-          _request_answer_add(entry->base.request, ref, rid, CSERVE2_OPEN);
+          cserve2_request_waiter_add(entry->base.request, rid, client);
         else
           _image_opened_send(client, entry, rid);
         return 0;
@@ -2169,7 +1906,7 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char
         _entry_load_reused(ref->entry);
         eina_hash_add(client->files.referencing, &client_file_id, ref);
         if (entry->base.request)
-          _request_answer_add(entry->base.request, ref, rid, CSERVE2_OPEN);
+          cserve2_request_waiter_add(entry->base.request, rid, client);
         else // File already loaded, otherwise there would be a request
           _image_opened_send(client, entry, rid);
         return 0;
@@ -2202,7 +1939,9 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char
    fw->entries = eina_list_append(fw->entries, entry);
    entry->watcher = fw;
 
-   _request_add(&open_requests, (Entry *)entry, ref, rid, CSERVE2_OPEN);
+   entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_OPEN,
+                                             rid, client, NULL, &_open_funcs,
+                                             entry);
 
    // _open_image_default_set(entry);
 
@@ -2296,8 +2035,9 @@ cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg)
    fentry = entry->file;
    fentry->images = eina_list_append(fentry->images, entry);
 
-   _request_add(&spload_requests, (Entry *)entry, ref, msg->base.rid,
-                CSERVE2_SETOPTS);
+   entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD,
+                                             0, NULL, fentry->base.request,
+                                             &_load_funcs, entry);
    return 0;
 }
 
@@ -2328,7 +2068,8 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned
    // File already being loaded, just add the request to be replied
    if (entry->base.request)
      {
-        _request_answer_add(entry->base.request, ref, rid, CSERVE2_LOAD);
+        cserve2_request_waiter_add(entry->base.request, rid, client);
+        /* do this in *_requests.c. somehow
         if ((!entry->base.request->processing) && (!entry->doload))
           {
              DBG("Removing entry %d from speculative preload and adding "
@@ -2338,11 +2079,16 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned
              load_requests = eina_list_append(load_requests,
                                               entry->base.request);
           }
+          */
      }
    else if (entry->shm)
      _image_loaded_send(client, entry, rid);
    else
-     _request_add(&load_requests, (Entry *)entry, ref, rid, CSERVE2_LOAD);
+     entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD,
+                                               rid, client,
+                                               entry->file->base.request,
+                                               &_load_funcs,
+                                               entry);
 
    entry->doload = EINA_TRUE;
 }
@@ -2374,21 +2120,27 @@ cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsign
    // File already being loaded, just add the request to be replied
    if (entry->base.request)
      {
-        _request_answer_add(entry->base.request, ref, rid, CSERVE2_PRELOAD);
+        cserve2_request_waiter_add(entry->base.request, rid, client);
+        /* do this in *_requests.c. somehow
         if ((!entry->base.request->processing) && (!entry->doload))
           {
              DBG("Removing entry %d from speculative preload and adding "
-                 "to normal (pre)load queue.", entry->base.id);
+                 "to normal load queue.", entry->base.id);
              spload_requests = eina_list_remove(spload_requests,
                                                 entry->base.request);
              load_requests = eina_list_append(load_requests,
                                               entry->base.request);
           }
+          */
      }
    else if (entry->shm)
-     _image_preloaded_send(client, rid);
+     _image_loaded_send(client, entry, rid);
    else
-     _request_add(&load_requests, (Entry *)entry, ref, rid, CSERVE2_PRELOAD);
+     entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD,
+                                               rid, client,
+                                               entry->file->base.request,
+                                               &_load_funcs,
+                                               entry);
 
    entry->doload = EINA_TRUE;
 }
@@ -2576,37 +2328,6 @@ cserve2_cache_font_glyphs_used(Client *client, const char *source, unsigned int
 }
 
 void
-cserve2_cache_requests_response(Slave_Command type, void *msg, void *data)
-{
-   Request *req = data;
-
-   if (!req->entry)
-     {
-        Waiter *w;
-        DBG("Request finished but it has no entry anymore.");
-        EINA_LIST_FREE(req->waiters, w)
-          {
-             cserve2_client_error_send(w->ref->client, w->rid,
-                                       CSERVE2_REQUEST_CANCEL);
-
-             w->ref->count--;
-             free(w);
-          }
-     }
-   else if (type == ERROR)
-     {
-        Error_Type *error = msg;
-        req->funcs->error(req->entry, *error);
-     }
-   else
-     req->funcs->response(req->entry, msg);
-
-   if (req->entry)
-     req->entry->request = NULL;
-   free(req);
-}
-
-void
 cserve2_cache_stats_get(Client *client, unsigned int rid)
 {
    Msg_Stats msg;
index b2a33ac..7368760 100644 (file)
@@ -263,14 +263,6 @@ parse_answer_loaded(const void *buf)
 }
 
 static void
-parse_answer_preloaded(const void *buf)
-{
-   const Msg_Preloaded *msg = buf;
-
-   printf("PRELOADED rid = %d\n", msg->base.rid);
-}
-
-static void
 parse_answer_error(const void *buf)
 {
    const Msg_Error *msg = buf;
@@ -294,9 +286,6 @@ parse_answer(const void *buf)
       case CSERVE2_LOADED:
          parse_answer_loaded(buf);
          break;
-      case CSERVE2_PRELOADED:
-         parse_answer_preloaded(buf);
-         break;
       case CSERVE2_ERROR:
          parse_answer_error(buf);
          break;
@@ -317,7 +306,6 @@ static struct {
    { "LOAD", CSERVE2_LOAD, parse_input_load },
    { "LOADED", CSERVE2_LOADED, NULL },
    { "PRELOAD", CSERVE2_PRELOAD, parse_input_preload },
-   { "PRELOADED", CSERVE2_PRELOADED, NULL },
    { "UNLOAD", CSERVE2_UNLOAD, parse_input_unload },
    { "CLOSE", CSERVE2_CLOSE, parse_input_close },
    { NULL, 0, NULL }
index a9fc1eb..0f4afcb 100644 (file)
 #endif
 #define CSERVE2_BIN_DEFAULT_COLOR EINA_COLOR_BLUE
 
-#define MAX_SLAVES 3
-
-struct _Slave_Worker {
-   EINA_INLIST;
-   void *data;
-   Slave *slave;
-   Eina_Binbuf *ret;
-   int ret_size;
-   Eina_Bool done;
-   Eina_Bool delete_me;
-};
-
-typedef struct _Slave_Worker Slave_Worker;
-
 int _evas_cserve2_bin_log_dom = -1;
 static unsigned int _client_id = 0;
 static Eina_Hash *client_list = NULL;
-static Eina_Inlist *slaves_idle = NULL;
-static Eina_Inlist *slaves_working = NULL;
 
 void
 cserve2_client_error_send(Client *client, unsigned int rid, int error_code)
@@ -66,117 +50,6 @@ _cserve2_client_image_setoptsed(Client *client, unsigned int rid)
 }
 
 static void
-_slave_dead_cb(Slave *s __UNUSED__, void *data)
-{
-   Slave_Worker *sw = data;
-
-   if (sw->delete_me)
-     {
-        DBG("Slave killed by cserve2. Restart routine.");
-        free(sw);
-        return;
-     }
-
-   if (!sw->data)
-     {
-        WRN("Slave died with no pending job, but not requested.");
-        slaves_idle = eina_inlist_remove(slaves_idle, EINA_INLIST_GET(sw));
-        free(sw);
-        return;
-     }
-
-   slaves_working = eina_inlist_remove(slaves_working, EINA_INLIST_GET(sw));
-   if (!sw->done)
-     cserve2_cache_requests_response(ERROR, (Error_Type[]){ CSERVE2_LOADER_DIED }, sw->data);
-   if (sw->ret)
-     eina_binbuf_free(sw->ret);
-   free(sw);
-}
-
-static void
-_slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd, void *msg, void *data)
-{
-   Slave_Worker *sw = data;
-
-   DBG("Received reply command '%d' from slave '%p'", cmd, sw->slave);
-   switch (cmd)
-     {
-      case IMAGE_OPEN:
-      case IMAGE_LOAD:
-         sw->done = EINA_TRUE;
-         break;
-      case ERROR:
-         break;
-      default:
-         ERR("Unrecognized command received from slave: %d", cmd);
-     }
-   cserve2_cache_requests_response(cmd, msg, sw->data);
-   free(msg);
-
-   // slave finishes its work, put it back to idle list
-   sw->data = NULL;
-   slaves_working = eina_inlist_remove(slaves_working, EINA_INLIST_GET(sw));
-
-   if (!sw->delete_me) // if it is being deleted, it shouldn't be in any list
-     slaves_idle = eina_inlist_append(slaves_idle, EINA_INLIST_GET(sw));
-
-   cserve2_cache_requests_process();
-}
-
-int
-cserve2_slave_available_get(void)
-{
-    return MAX_SLAVES - eina_inlist_count(slaves_working);
-}
-
-Eina_Bool
-cserve2_slave_cmd_dispatch(void *data, Slave_Command cmd, const void *msg, int size)
-{
-   Slave_Worker *sw;
-   char *exe;
-
-   DBG("Dispatching command to slave. %d idle slaves, %d working slaves.",
-       eina_inlist_count(slaves_idle), eina_inlist_count(slaves_working));
-
-   // first check if there's an available slave
-   if (slaves_idle)
-     {
-        sw = EINA_INLIST_CONTAINER_GET(slaves_idle, Slave_Worker);
-        slaves_idle = eina_inlist_remove(slaves_idle, slaves_idle);
-        slaves_working = eina_inlist_append(slaves_working,
-                                            EINA_INLIST_GET(sw));
-
-        sw->data = data;
-        sw->done = EINA_FALSE;
-        DBG("Dispatching command '%d' to slave '%p'", cmd, sw->slave);
-        cserve2_slave_send(sw->slave, cmd, msg, size);
-        return EINA_TRUE;
-     }
-
-   // no available slave, start a new one
-   sw = calloc(1, sizeof(Slave_Worker));
-   if (!sw) return EINA_FALSE;
-
-   sw->data = data;
-   exe = getenv("EVAS_CSERVE2_SLAVE");
-   if (!exe) exe = "evas_cserve2_slave";
-   sw->slave = cserve2_slave_run(exe, _slave_read_cb, _slave_dead_cb, sw);
-   if (!sw->slave)
-     {
-        ERR("Could not launch slave process");
-        cserve2_cache_requests_response(ERROR, (Error_Type[]){ CSERVE2_LOADER_EXEC_ERR }, sw->data);
-        free(sw);
-        return EINA_FALSE;
-     }
-   DBG("Dispatching command '%d' to slave '%p'", cmd, sw->slave);
-   cserve2_slave_send(sw->slave, cmd, msg, size);
-
-   slaves_working = eina_inlist_append(slaves_working, EINA_INLIST_GET(sw));
-
-   return EINA_TRUE;
-}
-
-static void
 _cserve2_client_close(Client *client)
 {
    Msg_Close *msg = (Msg_Close *)client->msg.buf;
@@ -207,7 +80,6 @@ _cserve2_client_preload(Client *client)
    INF("Image_ID: %d\n", msg->image_id);
 
    cserve2_cache_image_preload(client, msg->image_id, msg->base.rid);
-   cserve2_cache_requests_process();
 }
 
 static void
@@ -219,7 +91,6 @@ _cserve2_client_load(Client *client)
    INF("Image_ID: %d\n", msg->image_id);
 
    cserve2_cache_image_load(client, msg->image_id, msg->base.rid);
-   cserve2_cache_requests_process();
 }
 
 static void
@@ -257,7 +128,6 @@ _cserve2_client_open(Client *client)
           msg->file_id, path, key);
 
    cserve2_cache_file_open(client, msg->file_id, path, key, msg->base.rid);
-   cserve2_cache_requests_process();
 }
 
 static void
@@ -381,52 +251,6 @@ cserve2_command_run(Client *client, Message_Type type)
      }
 }
 
-static void
-_slave_quit_send(Slave_Worker *sw)
-{
-   cserve2_slave_send(sw->slave, SLAVE_QUIT, NULL, 0);
-}
-
-static void
-_slaves_restart(void)
-{
-   Slave_Worker *list, *sw;
-
-   while (slaves_idle) // remove idle workers from idle list
-     {
-        sw = EINA_INLIST_CONTAINER_GET(slaves_idle, Slave_Worker);
-        slaves_idle = eina_inlist_remove(slaves_idle, slaves_idle);
-        sw->delete_me = EINA_TRUE;
-        _slave_quit_send(sw);
-     }
-
-   // working workers will be removed from the working list when they
-   // finish processing their jobs
-   list = EINA_INLIST_CONTAINER_GET(slaves_working, Slave_Worker);
-   EINA_INLIST_FOREACH(list, sw)
-     {
-        sw->delete_me = EINA_TRUE;
-        _slave_quit_send(sw);
-     }
-}
-
-static void
-_timeout_cb(void)
-{
-   static unsigned int slaves_restart = 0;
-
-   slaves_restart++;
-
-   if (slaves_restart == 10)
-     {
-        DBG("kill slaves");
-        _slaves_restart();
-        slaves_restart = 0;
-     }
-
-   cserve2_timeout_cb_set(3000, _timeout_cb);
-}
-
 void
 cserve2_client_accept(int fd)
 {
@@ -518,8 +342,6 @@ main(int argc __UNUSED__, const char *argv[] __UNUSED__)
 
    _clients_setup();
 
-   cserve2_timeout_cb_set(3000, _timeout_cb);
-
    cserve2_main_loop_run();
 
    _clients_finish();
@@ -530,7 +352,6 @@ main(int argc __UNUSED__, const char *argv[] __UNUSED__)
 
    cserve2_requests_shutdown();
 
-   _slaves_restart();
    cserve2_slaves_shutdown();
 
    cserve2_main_loop_finish();
index df7ea19..e72b605 100644 (file)
@@ -38,6 +38,8 @@ static struct _Request_Match
    Slave_Command ctype;
 } _request_match[] =
 {
+   { CSERVE2_REQ_IMAGE_OPEN, SLAVE_IMAGE, IMAGE_OPEN },
+   { CSERVE2_REQ_IMAGE_LOAD, SLAVE_IMAGE, IMAGE_LOAD },
    { CSERVE2_REQ_FONT_LOAD, SLAVE_FONT, FONT_LOAD },
    { CSERVE2_REQ_FONT_GLYPHS_LOAD, SLAVE_FONT, FONT_GLYPHS_LOAD },
    { CSERVE2_REQ_LAST, 0, 0 }
index c44ddc5..fc83a92 100644 (file)
@@ -13,7 +13,6 @@ typedef enum {
    CSERVE2_LOAD,
    CSERVE2_LOADED,
    CSERVE2_PRELOAD,
-   CSERVE2_PRELOADED,
    CSERVE2_UNLOAD,
    CSERVE2_CLOSE,
    CSERVE2_FONT_LOAD,
index b009849..3e891a4 100644 (file)
@@ -335,29 +335,11 @@ _image_opened_cb(void *data, const void *msg_received)
 }
 
 static void
-_image_loaded_cb(void *data, const void *msg_received)
+_loaded_handle(Image_Entry *ie, Msg_Loaded *msg)
 {
-   const Msg_Base *answer = msg_received;
-   const Msg_Loaded *msg = msg_received;
-   Image_Entry *ie = data;
    Data_Entry *dentry = ie->data2;
    const char *shmpath;
 
-   ie->load_rid = 0;
-
-   if (!ie->data2)
-     return;
-
-   if (answer->type == CSERVE2_ERROR)
-     {
-        const Msg_Error *msg_error = msg_received;
-        ERR("Couldn't load image: '%s':'%s'; error: %d",
-            ie->file, ie->key, msg_error->error);
-        free(ie->data2);
-        ie->data2 = NULL;
-        return;
-     }
-
    shmpath = ((const char *)msg) + sizeof(*msg);
 
    // dentry->shm.path = strdup(shmpath);
@@ -393,6 +375,31 @@ _image_loaded_cb(void *data, const void *msg_received)
 }
 
 static void
+_image_loaded_cb(void *data, const void *msg_received)
+{
+   const Msg_Base *answer = msg_received;
+   const Msg_Loaded *msg = msg_received;
+   Image_Entry *ie = data;
+
+   ie->load_rid = 0;
+
+   if (!ie->data2)
+     return;
+
+   if (answer->type == CSERVE2_ERROR)
+     {
+        const Msg_Error *msg_error = msg_received;
+        ERR("Couldn't load image: '%s':'%s'; error: %d",
+            ie->file, ie->key, msg_error->error);
+        free(ie->data2);
+        ie->data2 = NULL;
+        return;
+     }
+
+   _loaded_handle(ie, msg);
+}
+
+static void
 _image_preloaded_cb(void *data, const void *msg_received)
 {
    const Msg_Base *answer = msg_received;
@@ -412,6 +419,8 @@ _image_preloaded_cb(void *data, const void *msg_received)
         return;
      }
 
+   _loaded_handle(ie, msg_received);
+
    if (dentry && (dentry->preloaded_cb))
      {
         dentry->preloaded_cb(data, EINA_TRUE);