evas/cserve2: Slave thread is only a simple callback.
authorantognolli <antognolli@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 31 May 2012 21:33:43 +0000 (21:33 +0000)
committerantognolli <antognolli@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 31 May 2012 21:33:43 +0000 (21:33 +0000)
The implementation of the slave doesn't need to care about reading
commands and sending answers. It just receives the arguments for its job
and returns the processed data.

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

src/bin/evas_cserve2.h
src/bin/evas_cserve2_slaves.c

index ce0fbbc..f7becaa 100644 (file)
@@ -118,7 +118,7 @@ typedef void (*Timeout_Cb)(void); /* void* for compat? */
 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 *(*Slave_Thread_Cb)(Slave_Thread_Data *sd, Slave_Command cmd, const void *cmddata, void *userdata);
 typedef void (*File_Change_Cb)(const char *path, Eina_Bool deleted, void *data);
 
 void cserve2_client_accept(int fd);
index 7f60b69..050f47b 100644 (file)
@@ -57,6 +57,8 @@ struct _Slave_Thread_Data {
    int read_fd;
    Slave_Thread_Cb cb;
    void *cb_data;
+   const void *cmddata;
+   void *cmdanswer;
 };
 
 static Eina_List *slave_procs;
@@ -195,7 +197,7 @@ _slave_read_clear(Slave *s)
 }
 
 static void
-_slave_read_cb(int fd, Fd_Flags flags, void *data)
+_slave_proc_read_cb(int fd, Fd_Flags flags, void *data)
 {
    Slave *s = data;
    Eina_Bool done = EINA_FALSE;
@@ -248,6 +250,27 @@ _slave_read_cb(int fd, Fd_Flags flags, void *data)
      }
 }
 
+static void
+_slave_thread_read_cb(int fd, Fd_Flags flags, void *data)
+{
+   Slave_Thread *s = data;
+   Slave_Thread_Data *sd = s->tdata;
+
+   if (!(flags & FD_READ))
+     return;
+
+   Slave_Command cmd;
+   ssize_t ret;
+
+   ret = read(fd, (char *)&cmd, sizeof(cmd));
+   if (ret < (int)sizeof(int))
+     {
+        return;
+     }
+
+   s->base.read_cb((Slave *)s, cmd, sd->cmdanswer, (void *)s->base.data);
+}
+
 Eina_Bool
 cserve2_slaves_init(void)
 {
@@ -410,7 +433,7 @@ _cserve2_slave_proc_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb de
    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);
+   cserve2_fd_watch_add(sb->read_fd, FD_READ, _slave_proc_read_cb, sb);
 
    close(child[0]);
    close(parent[1]);
@@ -429,9 +452,35 @@ cserve2_slave_run(const char *name, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb
 static void *
 _slave_thread_cb(void *data)
 {
+   ssize_t n;
+   Slave_Command cmd;
+
    Slave_Thread_Data *sd = data;
 
-   sd->cb(sd, sd->cb_data);
+   n = read(sd->read_fd, &cmd, sizeof(cmd));
+   while (n != 0)
+     {
+        /* EINTR means we were interrupted by a signal before anything
+         * was sent, and if we are back here it means that signal was
+         * not meant for us to die. Any other error here is fatal and
+         * should result in the slave terminating.
+         */
+        if (errno == EINTR)
+          continue;
+
+        if (n != sizeof(cmd))
+          {
+             ERR("Slave thread read invalid size of command from server: %d",
+                 n);
+             continue;
+          }
+        sd->cmdanswer = sd->cb(sd, cmd, sd->cmddata, sd->cb_data);
+        write(sd->write_fd, &cmd, sizeof(cmd));
+
+        n = read(sd->read_fd, &cmd, sizeof(cmd));
+     }
+
+   ERR("Pipe was closed on the side. Slave thread exiting...");
 
    return NULL;
 }
@@ -482,13 +531,7 @@ cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Rea
 
    /* 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;
@@ -519,7 +562,7 @@ cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Rea
    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);
+   cserve2_fd_watch_add(sb->read_fd, FD_READ, _slave_thread_read_cb, sb);
 
    slave_threads = eina_list_append(slave_threads, s);
 
@@ -548,7 +591,7 @@ _slave_send_aux(Slave *s, const char *data, size_t size)
 }
 
 void
-cserve2_slave_send(Slave *s, Slave_Command cmd, const char *data, size_t size)
+_cserve2_slave_proc_send(Slave *s, Slave_Command cmd, const char *data, size_t size)
 {
    int ints[2];
 
@@ -559,6 +602,23 @@ cserve2_slave_send(Slave *s, Slave_Command cmd, const char *data, size_t size)
      _slave_send_aux(s, (char *)data, size);
 }
 
+void
+_cserve2_slave_thread_send(Slave_Thread *s, Slave_Command cmd, const char *data)
+{
+   s->tdata->cmddata = data;
+
+   _slave_send_aux((Slave *)s, (char *)&cmd, sizeof(cmd));
+}
+
+void
+cserve2_slave_send(Slave *s, Slave_Command cmd, const char *data, size_t size)
+{
+   if (s->type == SLAVE_PROCESS)
+     _cserve2_slave_proc_send(s, cmd, data, size);
+   else
+     _cserve2_slave_thread_send((Slave_Thread *)s, cmd, data);
+}
+
 static void
 _cserve2_slave_proc_kill(Slave_Proc *s)
 {