[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:37
Message-ID: 20120531213337.AB8C7118096 () e2 ! enlightenment ! org
[Download RAW message or body]

Log:
evas/cserve2: Add threaded slave support.
  It's not being used yet, but the font slave will be done using this
  code.
  
  

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

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

Modified: trunk/evas/src/bin/evas_cserve2.h
===================================================================
--- trunk/evas/src/bin/evas_cserve2.h	2012-05-31 21:13:31 UTC (rev 71597)
+++ trunk/evas/src/bin/evas_cserve2.h	2012-05-31 21:33:37 UTC (rev 71598)
@@ -24,6 +24,7 @@
 extern int _evas_cserve2_bin_log_dom;
 
 typedef struct _Slave Slave;
+typedef struct _Slave_Thread_Data Slave_Thread_Data;
 typedef struct _Shm_Handle Shm_Handle;
 
 typedef enum {
@@ -117,6 +118,7 @@
 typedef void (*Main_Loop_Child_Dead_Cb)(int pid, int status); /* void* for compat? \
*/  typedef void (*Slave_Dead_Cb)(Slave *slave, void *data);
 typedef void (*Slave_Read_Cb)(Slave *slave, Slave_Command cmd, void *msg, void \
*data); +typedef void (*Slave_Thread_Cb)(Slave_Thread_Data *sd, void *data);
 typedef void (*File_Change_Cb)(const char *path, Eina_Bool deleted, void *data);
 
 void cserve2_client_accept(int fd);
@@ -148,6 +150,7 @@
 int cserve2_slave_available_get(void);
 Eina_Bool cserve2_slave_cmd_dispatch(void *data, Slave_Command cmd, const void *msg, \
int size);  Slave *cserve2_slave_run(const char *exe, Slave_Read_Cb read_cb, \
Slave_Dead_Cb dead_cb, const void *data); +Slave \
*cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Read_Cb \
read_cb, Slave_Dead_Cb dead_cb, const void *data);  void cserve2_slave_send(Slave *s, \
Slave_Command cmd, const char *data, size_t size);  void cserve2_slave_kill(Slave \
*s);  

Modified: trunk/evas/src/bin/evas_cserve2_slaves.c
===================================================================
--- trunk/evas/src/bin/evas_cserve2_slaves.c	2012-05-31 21:13:31 UTC (rev 71597)
+++ trunk/evas/src/bin/evas_cserve2_slaves.c	2012-05-31 21:33:37 UTC (rev 71598)
@@ -42,9 +42,26 @@
    Eina_Bool killed : 1;
 };
 
+typedef struct _Slave_Thread Slave_Thread;
 typedef struct _Slave_Proc Slave_Proc;
 
+struct _Slave_Thread
+{
+   Slave base;
+   pthread_t tid;
+   Slave_Thread_Data *tdata;
+};
+
+struct _Slave_Thread_Data {
+   int write_fd;
+   int read_fd;
+   Slave_Thread_Cb cb;
+   void *cb_data;
+};
+
 static Eina_List *slave_procs;
+static Eina_List *slave_threads;
+static pthread_attr_t slave_thread_attr;
 
 static Slave_Proc *
 _slave_proc_find(pid_t pid)
@@ -90,6 +107,21 @@
 }
 
 static void
+_slave_thread_free(Slave_Thread *s)
+{
+   Slave_Thread_Data *sd = s->tdata;
+
+   close(sd->write_fd);
+   close(sd->read_fd);
+
+   free(sd);
+
+   _slave_free((Slave *)s);
+
+   free(s);
+}
+
+static void
 _slave_proc_dead_cb(int pid, int status __UNUSED__)
 {
    Slave_Proc *s;
@@ -220,27 +252,45 @@
 cserve2_slaves_init(void)
 {
    cserve2_on_child_dead_set(_slave_proc_dead_cb);
+
+   if (pthread_attr_init(&slave_thread_attr))
+     {
+        ERR("Could not initialize attributes for thread.");
+        cserve2_on_child_dead_set(NULL);
+        return EINA_FALSE;
+     }
    return EINA_TRUE;
 }
 
 void
 cserve2_slaves_shutdown(void)
 {
-   Slave_Proc *s;
+   Slave_Proc *sp;
+   Slave_Thread *st;
+   Eina_List *l;
 
    cserve2_on_child_dead_set(NULL);
 
-   if (!slave_procs)
+   if (!slave_procs && !slave_threads)
      return;
 
    DBG("Shutting down slaves subsystem with %d slaves alive!",
        eina_list_count(slave_procs));
 
-   EINA_LIST_FREE(slave_procs, s)
+   EINA_LIST_FREE(slave_procs, sp)
      {
-        kill(s->pid, SIGKILL);
-        _slave_proc_free(s);
+        kill(sp->pid, SIGKILL);
+        _slave_proc_free(sp);
      }
+
+   EINA_LIST_FOREACH(slave_threads, l, st)
+      pthread_cancel(st->tid);
+
+   EINA_LIST_FREE(slave_threads, st)
+     {
+        pthread_join(st->tid, NULL);
+        _slave_thread_free(st);
+     }
 }
 
 static const char *
@@ -376,6 +426,106 @@
    return _cserve2_slave_proc_run(name, read_cb, dead_cb, data);
 }
 
+static void *
+_slave_thread_cb(void *data)
+{
+   Slave_Thread_Data *sd = data;
+
+   sd->cb(sd, sd->cb_data);
+
+   return NULL;
+}
+
+Slave *
+cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Read_Cb \
read_cb, Slave_Dead_Cb dead_cb, const void *data) +{
+   Slave_Thread_Data *sd;
+   Slave_Thread *s;
+   Slave *sb;
+   pthread_t tid;
+   int child[2], parent[2];
+   int flags;
+
+   s = calloc(1, sizeof(Slave_Thread));
+   if (!s)
+     {
+        ERR("Could not create Slave_Thread handler.");
+        return NULL;
+     }
+
+   sb = (Slave *)s;
+
+   sd = calloc(1, sizeof(Slave_Thread_Data));
+   if (!sd)
+     {
+        ERR("Could not create Slave_Thread_Data.");
+        return NULL;
+     }
+
+   if (pipe(child))
+     {
+        ERR("Could not create pipes for child.");
+        free(s);
+        free(sd);
+        return NULL;
+     }
+
+   if (pipe(parent))
+     {
+        ERR("Could not create pipes for parent.");
+        free(s);
+        free(sd);
+        close(child[0]);
+        close(child[1]);
+        return NULL;
+     }
+
+   /* Setting data for slave thread */
+   sd->read_fd = child[0];
+   flags = fcntl(sd->read_fd, F_GETFL);
+   flags |= O_NONBLOCK;
+   fcntl(sd->read_fd, F_SETFL, flags);
+   sd->write_fd = parent[1];
+   flags = fcntl(sd->write_fd, F_GETFL);
+   flags |= O_NONBLOCK;
+   fcntl(sd->write_fd, F_SETFL, flags);
+
+   sd->cb = thread_cb;
+   sd->cb_data = thread_data;
+
+   if (pthread_create(&tid, &slave_thread_attr, _slave_thread_cb, sd))
+     {
+        ERR("Could not start slave thread.");
+        free(s);
+        free(sd);
+        close(child[0]);
+        close(child[1]);
+        close(parent[0]);
+        close(parent[1]);
+        return NULL;
+     }
+
+   s->tid = tid;
+   s->tdata = sd;
+   sb->type = SLAVE_THREAD;
+   sb->write_fd = child[1];
+   flags = fcntl(sb->write_fd, F_GETFL);
+   flags |= O_NONBLOCK;
+   fcntl(sb->write_fd, F_SETFL, flags);
+   sb->read_fd = parent[0];
+   flags = fcntl(sb->read_fd, F_GETFL);
+   flags |= O_NONBLOCK;
+   fcntl(sb->read_fd, F_SETFL, flags);
+   sb->read_cb = read_cb;
+   sb->dead_cb = dead_cb;
+   sb->data = data;
+   cserve2_fd_watch_add(sb->read_fd, FD_READ, _slave_read_cb, sb);
+
+   slave_threads = eina_list_append(slave_threads, s);
+
+   return sb;
+}
+
 static void
 _slave_send_aux(Slave *s, const char *data, size_t size)
 {


------------------------------------------------------------------------------
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