Enlightenment CVS committal

Author  : raster
Project : e17
Module  : libs/ecore

Dir     : e17/libs/ecore/src/lib/ecore_con


Modified Files:
        Ecore_Con.h ecore_con_private.h ecore_con_url.c 


Log Message:


cedrics ecore_cn_url stuff for file downloads

===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/Ecore_Con.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -3 -r1.35 -r1.36
--- Ecore_Con.h 11 Feb 2008 23:24:11 -0000      1.35
+++ Ecore_Con.h 9 Mar 2008 16:43:32 -0000       1.36
@@ -149,8 +149,14 @@
    struct _Ecore_Con_Event_Url_Progress
      {
        Ecore_Con_Url    *url_con;
-       double            total;
-       double            now;
+       struct {
+          double         total;
+          double         now;
+       } down;
+       struct {
+          double         total;
+          double         now;
+       } up;
      };
 
    EAPI extern int ECORE_CON_EVENT_CLIENT_ADD;
@@ -161,8 +167,7 @@
    EAPI extern int ECORE_CON_EVENT_SERVER_DATA;
    EAPI extern int ECORE_CON_EVENT_URL_DATA;
    EAPI extern int ECORE_CON_EVENT_URL_COMPLETE;
-   EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD;
-   EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD;
+   EAPI extern int ECORE_CON_EVENT_URL_PROGRESS;
    
    EAPI int               ecore_con_init(void);
    EAPI int               ecore_con_shutdown(void);
@@ -196,6 +201,8 @@
    EAPI void              ecore_con_url_data_set(Ecore_Con_Url *url_con, void 
*data);
    EAPI void             *ecore_con_url_data_get(Ecore_Con_Url *url_con);
    EAPI int               ecore_con_url_url_set(Ecore_Con_Url *url_con, const 
char *url);
+   EAPI void             ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd);
+   EAPI int              ecore_con_url_received_bytes_get(Ecore_Con_Url 
*url_con);
    EAPI int               ecore_con_url_send(Ecore_Con_Url *url_con, void 
*data, size_t length, char *content_type);
    EAPI void              ecore_con_url_time(Ecore_Con_Url *url_con, 
Ecore_Con_Url_Time condition, time_t tm);
 
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/ecore_con_private.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -3 -r1.22 -r1.23
--- ecore_con_private.h 18 Feb 2008 06:27:26 -0000      1.22
+++ ecore_con_private.h 9 Mar 2008 16:43:32 -0000       1.23
@@ -78,6 +78,11 @@
    void              *data;
 
    Ecore_Fd_Handler  *fd_handler;
+   int               fd;
+   int               flags;
+
+   int               received;
+   int               write_fd;
 
    unsigned char      active : 1;
 };
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/ecore_con_url.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -3 -r1.18 -r1.19
--- ecore_con_url.c     5 Mar 2008 05:15:37 -0000       1.18
+++ ecore_con_url.c     9 Mar 2008 16:43:32 -0000       1.19
@@ -40,6 +40,8 @@
 #include "Ecore_Con.h"
 #include "ecore_con_private.h"
 
+#include <errno.h>
+
 /**
  * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions
  *
@@ -50,8 +52,7 @@
 
 int ECORE_CON_EVENT_URL_DATA = 0;
 int ECORE_CON_EVENT_URL_COMPLETE = 0;
-int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = 0;
-int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = 0;
+int ECORE_CON_EVENT_URL_PROGRESS = 0;
 
 #ifdef HAVE_CURL
 static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
@@ -61,10 +62,11 @@
 static void _ecore_con_event_url_free(void *data __UNUSED__, void *ev);
 static int _ecore_con_url_process_completed_jobs(Ecore_Con_Url 
*url_con_to_match);
 
-static CURLM *curlm = NULL;
-static Ecore_List *_url_con_list = NULL;
-static fd_set _current_fd_set;
-static int init_count = 0;
+static Ecore_Idler     *_fd_idler_handler = NULL;
+static Ecore_List      *_url_con_list = NULL;
+static CURLM           *curlm = NULL;
+static fd_set           _current_fd_set;
+static int              init_count = 0;
 
 struct _Ecore_Con_Url_Event
 {
@@ -114,8 +116,7 @@
      {
        ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
        ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
-       ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = ecore_event_type_new();
-       ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = ecore_event_type_new();
+       ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
      }
 
    if (!_url_con_list)
@@ -168,7 +169,7 @@
        if (!ecore_list_empty_is(_url_con_list))
          {
             Ecore_Con_Url *url_con;
-            while ((url_con = ecore_list_first_remove(_url_con_list)))
+            while ((url_con = ecore_list_first(_url_con_list)))
               {
                  ecore_con_url_destroy(url_con);
               }
@@ -230,6 +231,11 @@
    curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEOUT, 300);
    curl_easy_setopt(url_con->curl_easy, CURLOPT_FOLLOWLOCATION, 1);
 
+   curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate");
+
+   url_con->fd = -1;
+   url_con->write_fd = -1;
+
    return url_con;
 #else
    return NULL;
@@ -237,6 +243,15 @@
 #endif
 }
 
+static int
+_ecore_con_url_compare_cb(const void *data1, const void *data2)
+{
+   const void  *url_con1 = data1;
+   const void  *url_con2 = data2;
+
+   return (url_con1 == url_con2) ? 0 : 1;
+}
+
 /**
  * Frees the Ecore_Con_Url.
  * @return  FIXME: To be documented. 
@@ -255,11 +270,20 @@
 
    ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
    if (url_con->fd_handler)
-     ecore_main_fd_handler_del(url_con->fd_handler);
+     {
+       ecore_main_fd_handler_del(url_con->fd_handler);
+       url_con->fd = -1;
+     }
    if (url_con->curl_easy)
      {
        if (url_con->active)
-         curl_multi_remove_handle(curlm, url_con->curl_easy);
+         {
+            if (ecore_list_find(_url_con_list, _ecore_con_url_compare_cb, 
url_con) == url_con)
+              ecore_list_remove(_url_con_list);
+            url_con->active = 0;
+
+            curl_multi_remove_handle(curlm, url_con->curl_easy);
+         }
        curl_easy_cleanup(url_con->curl_easy);
      }
    curl_slist_free_all(url_con->headers);
@@ -376,6 +400,43 @@
  * @return  FIXME: To be documented.
  * @ingroup Ecore_Con_Url_Group
  */
+EAPI void
+ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd)
+{
+#ifdef HAVE_CURL
+   if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+     {
+       ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_set");
+       return ;
+     }
+   url_con->write_fd = fd;
+#endif   
+}
+
+/**
+ * FIXME: To be documented.
+ * @return  FIXME: To be documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+   if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+     {
+       ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, 
"ecore_con_url_received_bytes_get");
+       return -1;
+     }
+
+   return url_con->received;
+#endif   
+}
+
+/**
+ * FIXME: To be documented.
+ * @return  FIXME: To be documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
 EAPI int
 ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char 
*content_type)
 {
@@ -440,6 +501,57 @@
 }
 
 #ifdef HAVE_CURL
+static int
+_ecore_con_url_suspend_fd_handler(void)
+{
+   Ecore_Con_Url       *url_con;
+   int                  deleted = 0;
+
+   if (!_url_con_list)
+     return 0;
+
+   ecore_list_first_goto(_url_con_list);
+   while ((url_con = ecore_list_current(_url_con_list)))
+     {
+       if (url_con->active && url_con->fd_handler)
+         {
+            ecore_main_fd_handler_del(url_con->fd_handler);
+            url_con->fd_handler = NULL;
+            deleted++;
+         }
+       ecore_list_next(_url_con_list);
+     }
+
+   return deleted;
+}
+
+static int
+_ecore_con_url_restart_fd_handler(void)
+{
+   Ecore_Con_Url       *url_con;
+   int                  activated = 0;
+
+   if (!_url_con_list)
+     return 0;
+
+   ecore_list_first_goto(_url_con_list);
+   while ((url_con = ecore_list_current(_url_con_list)))
+     {
+       if (url_con->fd_handler == NULL
+           && url_con->fd != -1)
+         {
+            url_con->fd_handler = ecore_main_fd_handler_add(url_con->fd,
+                                                            url_con->flags,
+                                                            
_ecore_con_url_fd_handler,
+                                                            NULL, NULL, NULL);
+            activated++;
+         }
+       ecore_list_next(_url_con_list);
+     }
+
+   return activated;
+}
+
 static size_t
 _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
 {
@@ -448,15 +560,50 @@
    size_t real_size = size * nmemb;
 
    url_con = (Ecore_Con_Url *)userp;
-   e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * 
(real_size - 1));
-   if (e)
+
+   if (!url_con) return -1;
+   if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
      {
-       e->url_con = url_con;
-       e->size = real_size;
-       memcpy(e->data, buffer, real_size);
-       ecore_event_add(ECORE_CON_EVENT_URL_DATA, e,
-                       _ecore_con_event_url_free, NULL);
+       ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_cb");
+       return -1;
+     }
+
+   url_con->received += real_size;
+
+   if (url_con->write_fd < 0)
+     {
+       e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * 
(real_size - 1));
+       if (e)
+         {
+            e->url_con = url_con;
+            e->size = real_size;
+            memcpy(e->data, buffer, real_size);
+            ecore_event_add(ECORE_CON_EVENT_URL_DATA, e,
+                            _ecore_con_event_url_free, NULL);
+         }
+     }
+   else
+     {
+       ssize_t count = 0;
+       size_t  total_size = real_size;
+       size_t  offset = 0;
+
+       while (total_size > 0)
+         {
+            count = write(url_con->write_fd, (char*) buffer + offset, 
total_size);
+            if (count < 0)
+              {
+                 if (errno != EAGAIN && errno != EINTR)
+                   return -1;
+              }
+            else
+              {
+                 total_size -= count;
+                 offset += count;
+              }
+         }
      }
+
    return real_size;
 }
 
@@ -479,12 +626,21 @@
 static int
 _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double 
ultotal, double ulnow)
 {
-   Ecore_Con_Url *url_con;
+   Ecore_Con_Event_Url_Progress        *e;
+   Ecore_Con_Url               *url_con;
 
    url_con = clientp;
 
-   ECORE_CON_URL_TRANSMISSION(Download, ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD, 
url_con, dltotal, dlnow);
-   ECORE_CON_URL_TRANSMISSION(Upload, ECORE_CON_EVENT_URL_PROGRESS_UPLOAD, 
url_con, ultotal, ulnow);
+   e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress));
+   if (e)
+     {
+       e->url_con = url_con;
+       e->down.total = dltotal;
+       e->down.now = dlnow;
+       e->up.total = ultotal;
+       e->up.now = ulnow;
+       ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, 
_ecore_con_event_url_free, NULL);
+     }
 
    return 0;
 }
@@ -493,6 +649,7 @@
 _ecore_con_url_perform(Ecore_Con_Url *url_con)
 {
    fd_set read_set, write_set, exc_set;
+   double start;
    int fd_max;
    int fd;
    int flags;
@@ -501,8 +658,10 @@
 
    ecore_list_append(_url_con_list, url_con);
 
+   start = ecore_time_get();
    url_con->active = 1;
    curl_multi_add_handle(curlm, url_con->curl_easy);
+   /* This one can't be stopped, or the download never start. */
    while (curl_multi_perform(curlm, &still_running) == 
CURLM_CALL_MULTI_PERFORM);
 
    completed_immediately =  _ecore_con_url_process_completed_jobs(url_con);
@@ -527,9 +686,12 @@
                  if (flags)
                    {
                       FD_SET(fd, &_current_fd_set);
+                      url_con->fd = fd;
+                      url_con->flags = flags;
                       url_con->fd_handler = ecore_main_fd_handler_add(fd, 
flags,
                                                                       
_ecore_con_url_fd_handler,
                                                                       NULL, 
NULL, NULL);
+                      break;
                    }
               }
          }
@@ -538,6 +700,7 @@
             /* Failed to set up an fd_handler */
             curl_multi_remove_handle(curlm, url_con->curl_easy);
             url_con->active = 0;
+            url_con->fd = -1;
             return 0;
          }
      }
@@ -546,14 +709,41 @@
 }
 
 static int
+_ecore_con_url_idler_handler(void *data)
+{
+   double      start;
+   int         done = 1;
+   int         still_running;
+
+   start = ecore_time_get();
+   while (curl_multi_perform(curlm, &still_running) == 
CURLM_CALL_MULTI_PERFORM)
+     /* make this 1/20th of a second to keep interactivity high */
+     if ((ecore_time_get() - start) > 0.2)
+       {
+         done = 0;
+         break;
+       }
+
+   _ecore_con_url_process_completed_jobs(NULL);
+
+   if (done)
+     {
+       _ecore_con_url_restart_fd_handler();
+       _fd_idler_handler = NULL;
+       return 0;
+     }
+
+   return 1;
+}
+
+static int
 _ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler 
__UNUSED__)
 {
-   int still_running;
+   _ecore_con_url_suspend_fd_handler();
 
-   /* FIXME: Can this run for a long time? Maybe limit how long it can run */
-   while (curl_multi_perform(curlm, &still_running) == 
CURLM_CALL_MULTI_PERFORM);
+   if (_fd_idler_handler == NULL)
+     _fd_idler_handler = ecore_idler_add(_ecore_con_url_idler_handler, NULL);
 
-   _ecore_con_url_process_completed_jobs(NULL);
    return 1;
 }
 
@@ -580,11 +770,12 @@
                  if (url_con_to_match && (url_con == url_con_to_match)) {
                       job_matched = 1;
                  }
-                 if (url_con->fd_handler)
+                 if (url_con->fd != -1)
                    {
-                      FD_CLR(ecore_main_fd_handler_fd_get(url_con->fd_handler),
-                             &_current_fd_set);
-                      ecore_main_fd_handler_del(url_con->fd_handler);
+                      FD_CLR(url_con->fd, &_current_fd_set);
+                      if (url_con->fd_handler)
+                        ecore_main_fd_handler_del(url_con->fd_handler);
+                      url_con->fd = -1;
                       url_con->fd_handler = NULL;
                    }
                  ecore_list_remove(_url_con_list);



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to