forked from enlightenment/efl
evas/cserve2: Add threaded slave support.
It's not being used yet, but the font slave will be done using this code. SVN revision: 71598
This commit is contained in:
parent
616873f46d
commit
9a469b778c
|
@ -24,6 +24,7 @@
|
||||||
extern int _evas_cserve2_bin_log_dom;
|
extern int _evas_cserve2_bin_log_dom;
|
||||||
|
|
||||||
typedef struct _Slave Slave;
|
typedef struct _Slave Slave;
|
||||||
|
typedef struct _Slave_Thread_Data Slave_Thread_Data;
|
||||||
typedef struct _Shm_Handle Shm_Handle;
|
typedef struct _Shm_Handle Shm_Handle;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -117,6 +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 (*Main_Loop_Child_Dead_Cb)(int pid, int status); /* void* for compat? */
|
||||||
typedef void (*Slave_Dead_Cb)(Slave *slave, void *data);
|
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_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);
|
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);
|
||||||
|
@ -148,6 +150,7 @@ 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 *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);
|
||||||
|
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_send(Slave *s, Slave_Command cmd, const char *data, size_t size);
|
||||||
void cserve2_slave_kill(Slave *s);
|
void cserve2_slave_kill(Slave *s);
|
||||||
|
|
||||||
|
|
|
@ -42,9 +42,26 @@ struct _Slave_Proc
|
||||||
Eina_Bool killed : 1;
|
Eina_Bool killed : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _Slave_Thread Slave_Thread;
|
||||||
typedef struct _Slave_Proc Slave_Proc;
|
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_procs;
|
||||||
|
static Eina_List *slave_threads;
|
||||||
|
static pthread_attr_t slave_thread_attr;
|
||||||
|
|
||||||
static Slave_Proc *
|
static Slave_Proc *
|
||||||
_slave_proc_find(pid_t pid)
|
_slave_proc_find(pid_t pid)
|
||||||
|
@ -89,6 +106,21 @@ _slave_proc_free(Slave_Proc *s)
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
_slave_proc_dead_cb(int pid, int status __UNUSED__)
|
_slave_proc_dead_cb(int pid, int status __UNUSED__)
|
||||||
{
|
{
|
||||||
|
@ -220,26 +252,44 @@ Eina_Bool
|
||||||
cserve2_slaves_init(void)
|
cserve2_slaves_init(void)
|
||||||
{
|
{
|
||||||
cserve2_on_child_dead_set(_slave_proc_dead_cb);
|
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;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cserve2_slaves_shutdown(void)
|
cserve2_slaves_shutdown(void)
|
||||||
{
|
{
|
||||||
Slave_Proc *s;
|
Slave_Proc *sp;
|
||||||
|
Slave_Thread *st;
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
cserve2_on_child_dead_set(NULL);
|
cserve2_on_child_dead_set(NULL);
|
||||||
|
|
||||||
if (!slave_procs)
|
if (!slave_procs && !slave_threads)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DBG("Shutting down slaves subsystem with %d slaves alive!",
|
DBG("Shutting down slaves subsystem with %d slaves alive!",
|
||||||
eina_list_count(slave_procs));
|
eina_list_count(slave_procs));
|
||||||
|
|
||||||
EINA_LIST_FREE(slave_procs, s)
|
EINA_LIST_FREE(slave_procs, sp)
|
||||||
{
|
{
|
||||||
kill(s->pid, SIGKILL);
|
kill(sp->pid, SIGKILL);
|
||||||
_slave_proc_free(s);
|
_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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +426,106 @@ cserve2_slave_run(const char *name, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb
|
||||||
return _cserve2_slave_proc_run(name, read_cb, dead_cb, data);
|
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
|
static void
|
||||||
_slave_send_aux(Slave *s, const char *data, size_t size)
|
_slave_send_aux(Slave *s, const char *data, size_t size)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue