evas/cserve2: Refactory slave to inherit from a slave base.

The Slave_Proc now inherits from Slave, which implements all the
communication logic. The Slave_Proc only has specific code for
processes, while a new Slave_Thread should be added soon with code for
slave threads.



SVN revision: 71368
This commit is contained in:
Rafael Antognolli 2012-05-23 20:39:39 +00:00
parent f419175657
commit 796df2896c
3 changed files with 85 additions and 49 deletions

View File

@ -23,7 +23,7 @@
extern int _evas_cserve2_bin_log_dom; extern int _evas_cserve2_bin_log_dom;
typedef struct _Slave_Proc Slave_Proc; typedef struct _Slave Slave;
typedef struct _Shm_Handle Shm_Handle; typedef struct _Shm_Handle Shm_Handle;
typedef enum { typedef enum {
@ -115,8 +115,8 @@ typedef struct _Slave_Msg_Image_Loaded Slave_Msg_Image_Loaded;
typedef void (*Fd_Watch_Cb)(int fd, Fd_Flags flags, void *data); typedef void (*Fd_Watch_Cb)(int fd, Fd_Flags flags, void *data);
typedef void (*Timeout_Cb)(void); /* void* for compat? */ typedef void (*Timeout_Cb)(void); /* void* for compat? */
typedef void (*Main_Loop_Child_Dead_Cb)(int pid, int status); /* void* for compat? */ typedef void (*Main_Loop_Child_Dead_Cb)(int pid, int status); /* void* for compat? */
typedef void (*Slave_Dead_Cb)(Slave_Proc *slave, void *data); typedef void (*Slave_Dead_Cb)(Slave *slave, void *data);
typedef void (*Slave_Read_Cb)(Slave_Proc *slave, Slave_Command cmd, void *msg, void *data); typedef void (*Slave_Read_Cb)(Slave *slave, Slave_Command cmd, void *msg, void *data);
typedef void (*File_Change_Cb)(const char *path, Eina_Bool deleted, void *data); typedef void (*File_Change_Cb)(const char *path, Eina_Bool deleted, void *data);
void cserve2_client_accept(int fd); void cserve2_client_accept(int fd);
@ -147,9 +147,9 @@ Eina_Bool cserve2_slaves_init(void);
void cserve2_slaves_shutdown(void); void cserve2_slaves_shutdown(void);
int cserve2_slave_available_get(void); int cserve2_slave_available_get(void);
Eina_Bool cserve2_slave_cmd_dispatch(void *data, Slave_Command cmd, const void *msg, int size); Eina_Bool cserve2_slave_cmd_dispatch(void *data, Slave_Command cmd, const void *msg, int size);
Slave_Proc *cserve2_slave_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data); Slave *cserve2_slave_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data);
void cserve2_slave_send(Slave_Proc *s, Slave_Command cmd, const char *data, size_t size); void cserve2_slave_send(Slave *s, Slave_Command cmd, const char *data, size_t size);
void cserve2_slave_kill(Slave_Proc *s); void cserve2_slave_kill(Slave *s);
void cserve2_message_handler(int fd, Fd_Flags flags, void *data); void cserve2_message_handler(int fd, Fd_Flags flags, void *data);

View File

@ -18,7 +18,7 @@
struct _Slave_Worker { struct _Slave_Worker {
EINA_INLIST; EINA_INLIST;
void *data; void *data;
Slave_Proc *slave; Slave *slave;
Eina_Binbuf *ret; Eina_Binbuf *ret;
int ret_size; int ret_size;
Eina_Bool done; Eina_Bool done;
@ -73,7 +73,7 @@ _cserve2_client_image_setoptsed(Client *client, unsigned int rid)
} }
static void static void
_slave_dead_cb(Slave_Proc *s __UNUSED__, void *data) _slave_dead_cb(Slave *s __UNUSED__, void *data)
{ {
Slave_Worker *sw = data; Slave_Worker *sw = data;
@ -101,7 +101,7 @@ _slave_dead_cb(Slave_Proc *s __UNUSED__, void *data)
} }
static void static void
_slave_read_cb(Slave_Proc *s __UNUSED__, Slave_Command cmd, void *msg, void *data) _slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd, void *msg, void *data)
{ {
Slave_Worker *sw = data; Slave_Worker *sw = data;

View File

@ -10,10 +10,15 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
struct _Slave_Proc typedef enum
{ {
pid_t pid; SLAVE_PROCESS,
const char *name; SLAVE_THREAD
} Slave_Type;
struct _Slave
{
Slave_Type type;
int write_fd; int write_fd;
int read_fd; int read_fd;
Slave_Read_Cb read_cb; Slave_Read_Cb read_cb;
@ -27,26 +32,34 @@ struct _Slave_Proc
Slave_Command cmd; Slave_Command cmd;
char *buf; char *buf;
} read; } read;
};
struct _Slave_Proc
{
Slave base;
pid_t pid;
const char *name;
Eina_Bool killed : 1; Eina_Bool killed : 1;
}; };
static Eina_List *slaves; typedef struct _Slave_Proc Slave_Proc;
static Eina_List *slave_procs;
static Slave_Proc * static Slave_Proc *
_child_find(pid_t pid) _slave_proc_find(pid_t pid)
{ {
Eina_List *l; Eina_List *l;
Slave_Proc *s; Slave_Proc *s;
EINA_LIST_FOREACH(slaves, l, s) EINA_LIST_FOREACH(slave_procs, l, s)
if (s->pid == pid) if (s->pid == pid)
return s; return s;
return NULL; return NULL;
} }
static void static void
_slave_free(Slave_Proc *s) _slave_free(Slave *s)
{ {
if (s->write_fd) if (s->write_fd)
close(s->write_fd); close(s->write_fd);
@ -64,30 +77,37 @@ _slave_free(Slave_Proc *s)
if (s->dead_cb) if (s->dead_cb)
s->dead_cb(s, (void *)s->data); s->dead_cb(s, (void *)s->data);
}
static void
_slave_proc_free(Slave_Proc *s)
{
_slave_free((Slave *)s);
eina_stringshare_del(s->name); eina_stringshare_del(s->name);
free(s); free(s);
} }
static void static void
_slave_dead_cb(int pid, int status __UNUSED__) _slave_proc_dead_cb(int pid, int status __UNUSED__)
{ {
Slave_Proc *s; Slave_Proc *s;
DBG("Child dead with pid '%d'.", pid); DBG("Child dead with pid '%d'.", pid);
s = _child_find(pid); s = _slave_proc_find(pid);
if (!s) if (!s)
{ {
ERR("Unknown child dead '%d'.", pid); ERR("Unknown child dead '%d'.", pid);
return; return;
} }
slaves = eina_list_remove(slaves, s); slave_procs = eina_list_remove(slave_procs, s);
_slave_free(s); _slave_proc_free(s);
} }
static size_t static size_t
_slave_write(Slave_Proc *s, const char *data, size_t size) _slave_write(Slave *s, const char *data, size_t size)
{ {
size_t sent = 0; size_t sent = 0;
@ -115,7 +135,7 @@ _slave_write(Slave_Proc *s, const char *data, size_t size)
static void static void
_slave_write_cb(int fd __UNUSED__, Fd_Flags flags __UNUSED__, void *data) _slave_write_cb(int fd __UNUSED__, Fd_Flags flags __UNUSED__, void *data)
{ {
Slave_Proc *s = data; Slave *s = data;
size_t sent; size_t sent;
size_t size; size_t size;
const char *str; const char *str;
@ -135,7 +155,7 @@ _slave_write_cb(int fd __UNUSED__, Fd_Flags flags __UNUSED__, void *data)
} }
static void static void
_slave_read_clear(Slave_Proc *s) _slave_read_clear(Slave *s)
{ {
s->read.buf = NULL; s->read.buf = NULL;
s->read.cmd = 0; s->read.cmd = 0;
@ -145,7 +165,7 @@ _slave_read_clear(Slave_Proc *s)
static void static void
_slave_read_cb(int fd, Fd_Flags flags, void *data) _slave_read_cb(int fd, Fd_Flags flags, void *data)
{ {
Slave_Proc *s = data; Slave *s = data;
Eina_Bool done = EINA_FALSE; Eina_Bool done = EINA_FALSE;
/* handle error */ /* handle error */
@ -199,7 +219,7 @@ _slave_read_cb(int fd, Fd_Flags flags, void *data)
Eina_Bool Eina_Bool
cserve2_slaves_init(void) cserve2_slaves_init(void)
{ {
cserve2_on_child_dead_set(_slave_dead_cb); cserve2_on_child_dead_set(_slave_proc_dead_cb);
return EINA_TRUE; return EINA_TRUE;
} }
@ -210,21 +230,21 @@ cserve2_slaves_shutdown(void)
cserve2_on_child_dead_set(NULL); cserve2_on_child_dead_set(NULL);
if (!slaves) if (!slave_procs)
return; return;
DBG("Shutting down slaves subsystem with %d slaves alive!", DBG("Shutting down slaves subsystem with %d slaves alive!",
eina_list_count(slaves)); eina_list_count(slave_procs));
EINA_LIST_FREE(slaves, s) EINA_LIST_FREE(slave_procs, s)
{ {
kill(s->pid, SIGKILL); kill(s->pid, SIGKILL);
_slave_free(s); _slave_proc_free(s);
} }
} }
static const char * static const char *
_slave_path_get(const char *name) _slave_proc_path_get(const char *name)
{ {
char buf[PATH_MAX], cwd[PATH_MAX]; char buf[PATH_MAX], cwd[PATH_MAX];
@ -247,16 +267,17 @@ _slave_path_get(const char *name)
return NULL; return NULL;
} }
Slave_Proc * static Slave *
cserve2_slave_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data) _cserve2_slave_proc_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data)
{ {
Slave_Proc *s; Slave_Proc *s;
Slave *sb;
pid_t pid; pid_t pid;
int child[2], parent[2]; int child[2], parent[2];
int flags; int flags;
const char *name; const char *name;
name = _slave_path_get(exe); name = _slave_proc_path_get(exe);
if (!name) if (!name)
{ {
ERR("Cannot execute slave '%s'. Not found or not executable.", exe); ERR("Cannot execute slave '%s'. Not found or not executable.", exe);
@ -272,6 +293,8 @@ cserve2_slave_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb,
return NULL; return NULL;
} }
sb = (Slave *)s;
if (pipe(child)) if (pipe(child))
{ {
ERR("Could not create pipes for child."); ERR("Could not create pipes for child.");
@ -325,29 +348,36 @@ cserve2_slave_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb,
s->pid = pid; s->pid = pid;
s->name = name; s->name = name;
s->write_fd = child[1]; sb->type = SLAVE_PROCESS;
flags = fcntl(s->write_fd, F_GETFL); sb->write_fd = child[1];
flags = fcntl(sb->write_fd, F_GETFL);
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
fcntl(s->write_fd, F_SETFL, flags); fcntl(sb->write_fd, F_SETFL, flags);
s->read_fd = parent[0]; sb->read_fd = parent[0];
flags = fcntl(s->read_fd, F_GETFL); flags = fcntl(sb->read_fd, F_GETFL);
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
fcntl(s->read_fd, F_SETFL, flags); fcntl(sb->read_fd, F_SETFL, flags);
s->read_cb = read_cb; sb->read_cb = read_cb;
s->dead_cb = dead_cb; sb->dead_cb = dead_cb;
s->data = data; sb->data = data;
cserve2_fd_watch_add(s->read_fd, FD_READ, _slave_read_cb, s); cserve2_fd_watch_add(sb->read_fd, FD_READ, _slave_read_cb, sb);
close(child[0]); close(child[0]);
close(parent[1]); close(parent[1]);
slaves = eina_list_append(slaves, s); slave_procs = eina_list_append(slave_procs, s);
return s; return sb;
}
Slave *
cserve2_slave_run(const char *name, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data)
{
return _cserve2_slave_proc_run(name, read_cb, dead_cb, data);
} }
static void static void
_slave_send_aux(Slave_Proc *s, const char *data, size_t size) _slave_send_aux(Slave *s, const char *data, size_t size)
{ {
size_t sent; size_t sent;
@ -368,7 +398,7 @@ _slave_send_aux(Slave_Proc *s, const char *data, size_t size)
} }
void void
cserve2_slave_send(Slave_Proc *s, Slave_Command cmd, const char *data, size_t size) cserve2_slave_send(Slave *s, Slave_Command cmd, const char *data, size_t size)
{ {
int ints[2]; int ints[2];
@ -379,8 +409,8 @@ cserve2_slave_send(Slave_Proc *s, Slave_Command cmd, const char *data, size_t si
_slave_send_aux(s, (char *)data, size); _slave_send_aux(s, (char *)data, size);
} }
void static void
cserve2_slave_kill(Slave_Proc *s) _cserve2_slave_proc_kill(Slave_Proc *s)
{ {
if (s->killed) if (s->killed)
{ {
@ -392,3 +422,9 @@ cserve2_slave_kill(Slave_Proc *s)
s->killed = EINA_TRUE; s->killed = EINA_TRUE;
kill(s->pid, SIGTERM); kill(s->pid, SIGTERM);
} }
void
cserve2_slave_kill(Slave *s)
{
_cserve2_slave_proc_kill((Slave_Proc *)s);
}