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;
|
||||
|
||||
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 (*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 (*File_Change_Cb)(const char *path, Eina_Bool deleted, void *data);
|
||||
|
||||
void cserve2_client_accept(int fd);
|
||||
|
@ -148,6 +150,7 @@ void cserve2_slaves_shutdown(void);
|
|||
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);
|
||||
|
||||
|
|
|
@ -42,9 +42,26 @@ struct _Slave_Proc
|
|||
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)
|
||||
|
@ -89,6 +106,21 @@ _slave_proc_free(Slave_Proc *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
|
||||
_slave_proc_dead_cb(int pid, int status __UNUSED__)
|
||||
{
|
||||
|
@ -220,26 +252,44 @@ Eina_Bool
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue