[prev in list] [next in list] [prev in thread] [next in thread] 

List:       enlightenment-svn
Subject:    E SVN: antognolli trunk/evas/src/bin
From:       "Enlightenment SVN" <no-reply () enlightenment ! org>
Date:       2012-05-31 21:33:59
Message-ID: 20120531213359.AB35511809E () e2 ! enlightenment ! org
[Download RAW message or body]

Log:
evas/cserve2: Add requests and slave workers
   management.
  
  

Author:       antognolli
Date:         2012-05-31 14:33:59 -0700 (Thu, 31 May 2012)
New Revision: 71601
Trac:         http://trac.enlightenment.org/e/changeset/71601

Modified:
  trunk/evas/src/bin/evas_cserve2.h trunk/evas/src/bin/evas_cserve2_requests.c 

Modified: trunk/evas/src/bin/evas_cserve2.h
===================================================================
--- trunk/evas/src/bin/evas_cserve2.h	2012-05-31 21:33:53 UTC (rev 71600)
+++ trunk/evas/src/bin/evas_cserve2.h	2012-05-31 21:33:59 UTC (rev 71601)
@@ -113,12 +113,14 @@
 typedef struct _Slave_Msg_Image_Load Slave_Msg_Image_Load;
 typedef struct _Slave_Msg_Image_Loaded Slave_Msg_Image_Loaded;
 
-typedef void *(*Font_Request_Msg_Create)(Client *c, void *data, int *size);
-typedef void (*Font_Request_Response)(Client *c, void *data, void *resp);
-typedef void (*Font_Request_Error)(Client *c, void *data, Error_Type error);
+typedef void *(*Font_Request_Msg_Create)(void *data, int *size);
+typedef void *(*Font_Request_Msg_Free)(void *data);
+typedef void (*Font_Request_Response)(Client *c, void *data, void *resp, unsigned \
int rid); +typedef void (*Font_Request_Error)(Client *c, void *data, Error_Type \
error, unsigned int rid);  
 struct _Font_Request_Funcs {
    Font_Request_Msg_Create msg_create;
+   Font_Request_Msg_Free msg_free;
    Font_Request_Response response;
    Font_Request_Error error;
 };

Modified: trunk/evas/src/bin/evas_cserve2_requests.c
===================================================================
--- trunk/evas/src/bin/evas_cserve2_requests.c	2012-05-31 21:33:53 UTC (rev 71600)
+++ trunk/evas/src/bin/evas_cserve2_requests.c	2012-05-31 21:33:59 UTC (rev 71601)
@@ -4,15 +4,72 @@
 
 #include "evas_cserve2.h"
 
-struct _Font_Request {
+#define MAX_SLAVES 1
+
+typedef enum
+{
+   SLAVE_IMAGE,
+   SLAVE_FONT,
+   SLAVE_NONE
+} Slave_Type;
+
+struct _Slave_Worker
+{
+   void *data;
+   Slave *slave;
+   Eina_Binbuf *ret;
+   int ret_size;
+   Eina_Bool done;
+   Eina_Bool delete_me;
+};
+
+typedef struct _Slave_Worker Slave_Worker;
+
+/* This struct is used to match font request types to the respective slave
+ * type, and the message type that will be used for that request. The order
+ * of the request types on it is the order in which these requests will
+ * be processed.
+ */
+static struct _Request_Match
+{
+   Font_Request_Type rtype;
+   Slave_Type stype;
+   Message_Type mtype;
+} _request_match[] =
+{
+   { CSERVE2_REQ_FONT_LOAD, SLAVE_FONT, CSERVE2_FONT_LOAD },
+   { CSERVE2_REQ_FONT_GLYPHS_LOAD, SLAVE_FONT, CSERVE2_FONT_GLYPHS_LOAD },
+   { CSERVE2_REQ_LAST, 0 }
+};
+
+static Slave *_create_image_slave(void *data);
+static Slave *_create_font_slave(void *data);
+
+static struct _Worker
+{
+   Slave_Type type;
+   unsigned int max;
+   Eina_List *idle;
+   Eina_List *working;
+   Slave *(*create_slave)(void *data);
+} _workers[] =
+{
+   { SLAVE_IMAGE, 3, NULL, NULL, _create_image_slave },
+   { SLAVE_FONT, 1, NULL, NULL, _create_font_slave },
+};
+
+struct _Font_Request
+{
    Font_Request_Type type;
    void *data;
+   void *msg;
    Eina_List *waiters;
    Eina_Bool processing;
    Font_Request_Funcs *funcs;
 };
 
-struct _Waiter {
+struct _Waiter
+{
    unsigned int rid;
    Client *client;
 };
@@ -78,7 +135,7 @@
              DBG("Removing answer from waiter client: %d, rid: %d",
                  client->id, w->rid);
              if (req->funcs && req->funcs->error)
-               req->funcs->error(client, req->data, err);
+               req->funcs->error(client, req->data, err, w->rid);
              req->waiters = eina_list_remove_list(req->waiters, l);
              free(w);
           }
@@ -90,6 +147,7 @@
      {
         Eina_List **reqlist = &requests[req->type];
         *reqlist = eina_list_remove(*reqlist, req);
+        req->funcs->msg_free(req->msg);
         free(req);
      }
 
@@ -107,11 +165,12 @@
         DBG("Removing answer from waiter client: %d, rid: %d",
             w->client->id, w->rid);
         if (req->funcs && req->funcs->error)
-          req->funcs->error(w->client, req->data, err);
+          req->funcs->error(w->client, req->data, err, w->rid);
         free(w);
      }
 
    requests[req->type] = eina_list_remove(requests[req->type], req);
+   req->funcs->msg_free(req->msg);
    free(req);
 }
 
@@ -128,3 +187,161 @@
    DBG("Shutting down requests.");
    free(requests);
 }
+
+static void
+_image_slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd __UNUSED__, void *msg \
__UNUSED__, void *data __UNUSED__) +{
+}
+
+static void
+_image_slave_dead_cb(Slave *s __UNUSED__, void *data __UNUSED__)
+{
+}
+
+static Slave *
+_create_image_slave(void *data)
+{
+   char *exe;
+   Slave *slave;
+
+   exe = getenv("EVAS_CSERVE2_SLAVE");
+   if (!exe) exe = "evas_cserve2_slave";
+
+   slave = cserve2_slave_run(exe, _image_slave_read_cb,
+                             _image_slave_dead_cb, data);
+
+   return slave;
+}
+
+static Slave *
+_create_font_slave(void *data __UNUSED__)
+{
+   return NULL;
+}
+
+static Slave_Worker *
+_slave_for_request_create(Slave_Type type)
+{
+   Slave_Worker *sw;
+   Slave *slave;
+
+   sw = calloc(1, sizeof(Slave_Worker));
+   if (!sw) return NULL;
+
+   slave = _workers[type].create_slave(sw);
+   if (!slave)
+     {
+        ERR("Could not launch slave process");
+        free(sw);
+        return NULL;
+     }
+
+   sw->slave = slave;
+   _workers[type].idle = eina_list_append(_workers[type].idle, sw);
+
+   return sw;
+}
+
+static Eina_Bool
+_cserve2_request_dispatch(Slave_Worker *sw, Message_Type mtype, Font_Request *req)
+{
+   int size;
+   char *slave_msg = req->funcs->msg_create(req->data, &size);
+
+   if (!slave_msg)
+     {
+        ERR("Could not create slave message for request type %d.", req->type);
+        return EINA_FALSE;
+     }
+
+   req->msg = slave_msg;
+   sw->data = req;
+   cserve2_slave_send(sw->slave, mtype, slave_msg, size);
+   req->processing = EINA_TRUE;
+
+   return EINA_TRUE;
+}
+
+static void
+_cserve2_request_failed(Font_Request *req, Error_Type type)
+{
+   Waiter *w;
+
+   EINA_LIST_FREE(req->waiters, w)
+     {
+        req->funcs->error(w->client, req->data, type, w->rid);
+        free(w);
+     }
+
+   req->funcs->msg_free(req->msg);
+   free(req);
+}
+
+void
+cserve2_requests_process(void)
+{
+    int rtype, j;
+
+    for (rtype = 0; rtype < CSERVE2_REQ_LAST; rtype++)
+      {
+         Slave_Type type = SLAVE_NONE;
+         Message_Type mtype;
+         unsigned int max_workers;
+         Eina_List **idle, **working;
+
+         for (j = 0; _request_match[j].rtype != CSERVE2_REQ_LAST; j++)
+           {
+              if (_request_match[j].rtype == j)
+                {
+                   type = _request_match[j].stype;
+                   mtype = _request_match[j].mtype;
+                   break;
+                }
+           }
+
+         if (type == SLAVE_NONE)
+           continue;
+
+         if (!requests[rtype])
+           continue;
+
+         /* Now we have the worker type to use (image or font), and the list
+          * of requests to process. Just process as many requests as we can.
+          */
+         max_workers = _workers[type].max;
+         idle = &_workers[type].idle;
+         working = &_workers[type].working;
+
+         while (requests[j] &&
+                (eina_list_count(*working) < max_workers))
+           {
+              Slave_Worker *sw;
+              Font_Request *req = eina_list_data_get(requests[rtype]);
+              requests[rtype] = eina_list_remove_list(requests[rtype],
+                                                      requests[rtype]);
+
+              if (!(*idle))
+                sw = _slave_for_request_create(type);
+
+              if (!(*idle))
+                {
+                   ERR("No idle slave available to process request type %d.",
+                       rtype);
+                   _cserve2_request_failed(req, CSERVE2_GENERIC);
+                   continue;
+                }
+
+              sw = eina_list_data_get(*idle);
+              if (!_cserve2_request_dispatch(sw, mtype, req))
+                {
+                   ERR("Could not dispatch request.");
+                   _cserve2_request_failed(req, CSERVE2_GENERIC);
+                   continue;
+                }
+
+              *idle = eina_list_remove_list(*idle, *idle);
+              *working = eina_list_append(*working, sw);
+
+           }
+      }
+}


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
enlightenment-svn mailing list
enlightenment-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-svn


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic