cleaning up mio_dev_thr_t code
This commit is contained in:
parent
9c95db02e5
commit
c441abdbfb
@ -30,6 +30,7 @@
|
|||||||
#include <mio-sck.h>
|
#include <mio-sck.h>
|
||||||
#include <mio-pro.h>
|
#include <mio-pro.h>
|
||||||
#include <mio-pipe.h>
|
#include <mio-pipe.h>
|
||||||
|
#include <mio-thr.h>
|
||||||
#include <mio-dns.h>
|
#include <mio-dns.h>
|
||||||
#include <mio-nwif.h>
|
#include <mio-nwif.h>
|
||||||
#include <mio-http.h>
|
#include <mio-http.h>
|
||||||
@ -638,6 +639,36 @@ static void pipe_on_close (mio_dev_pipe_t* dev, mio_dev_pipe_sid_t sid)
|
|||||||
{
|
{
|
||||||
MIO_INFO1 (dev->mio, "PIPE[%d] CLOSED \n", (int)sid);
|
MIO_INFO1 (dev->mio, "PIPE[%d] CLOSED \n", (int)sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int thr_on_read (mio_dev_thr_t* dev, const void* data, mio_iolen_t dlen)
|
||||||
|
{
|
||||||
|
MIO_INFO3 (dev->mio, "THR READ FROM THR - %d bytes - [%.*s]\n", (int)dlen, (int)dlen, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thr_on_write (mio_dev_thr_t* dev, mio_iolen_t wrlen, void* wrctx)
|
||||||
|
{
|
||||||
|
MIO_INFO1 (dev->mio, "THR WRITTEN TO THR - %d bytes\n", (int)wrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void thr_on_close (mio_dev_thr_t* dev, mio_dev_thr_sid_t sid)
|
||||||
|
{
|
||||||
|
MIO_INFO1 (dev->mio, "THR[%d] CLOSED \n", (int)sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void thr_func (mio_dev_thr_t* dev, mio_dev_thr_iopair_t* iop, void* cx)
|
||||||
|
{
|
||||||
|
mio_bch_t buf[5];
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
while ((n = read(iop->rfd, buf, MIO_COUNTOF(buf)))> 0) write (iop->wfd, buf, n);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
sleep (1);
|
||||||
|
write (iop->wfd, "THR LOOPING", 11);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
static void on_dnc_resolve(mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum_t status, const void* data, mio_oow_t dlen)
|
static void on_dnc_resolve(mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum_t status, const void* data, mio_oow_t dlen)
|
||||||
@ -1213,8 +1244,21 @@ if (!mio_svc_dnc_resolve(dnc, "google.com", MIO_DNS_RRT_SOA, MIO_SVC_DNC_RESOLVE
|
|||||||
mi.on_read = pipe_on_read;
|
mi.on_read = pipe_on_read;
|
||||||
mi.on_write = pipe_on_write;
|
mi.on_write = pipe_on_write;
|
||||||
mi.on_close = pipe_on_close;
|
mi.on_close = pipe_on_close;
|
||||||
pp = mio_dev_pipe_make (mio, 0, &mi);
|
pp = mio_dev_pipe_make(mio, 0, &mi);
|
||||||
mio_dev_pipe_write (pp, "hello, world", 12, MIO_NULL);
|
mio_dev_pipe_write (pp, "this is good", 12, MIO_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
mio_dev_thr_t* tt;
|
||||||
|
mio_dev_thr_make_t mi;
|
||||||
|
mi.thr_func = thr_func;
|
||||||
|
mi.thr_ctx = MIO_NULL;
|
||||||
|
mi.on_read = thr_on_read;
|
||||||
|
mi.on_write = thr_on_write;
|
||||||
|
mi.on_close = thr_on_close;
|
||||||
|
tt = mio_dev_thr_make(mio, 0, &mi);
|
||||||
|
mio_dev_thr_write (tt, "hello, world", 12, MIO_NULL);
|
||||||
|
mio_dev_thr_write (tt, MIO_NULL, 0, MIO_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
mio_loop (mio);
|
mio_loop (mio);
|
||||||
|
@ -1652,111 +1652,6 @@ mio_bch_t* mio_svc_htts_dupmergepaths (mio_svc_htts_t* htts, const mio_bch_t* ba
|
|||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
typedef void (*mio_svc_htts_rsrc_cgi_t) (
|
|
||||||
int rfd,
|
|
||||||
int wfd
|
|
||||||
);
|
|
||||||
|
|
||||||
struct mio_svc_htts_rsrc_cgi_peer_t
|
|
||||||
{
|
|
||||||
int rfd;
|
|
||||||
int wfd;
|
|
||||||
};
|
|
||||||
typedef struct mio_svc_htts_rsrc_cgi_peer_t mio_svc_htts_rsrc_cgi_peer_t;
|
|
||||||
|
|
||||||
enum mio_svc_htts_rsrc_cgi_type_t
|
|
||||||
{
|
|
||||||
MIO_SVC_HTTS_RSRC_CGI_TYPE_FUNC,
|
|
||||||
MIO_SVC_HTTS_RSRC_CGI_TYPE_PROC
|
|
||||||
};
|
|
||||||
typedef enum mio_svc_htts_rsrc_cgi_type_t mio_svc_htts_rsrc_cgi_type_t;
|
|
||||||
|
|
||||||
struct rsrc_cgi_xtn_t
|
|
||||||
{
|
|
||||||
mio_svc_htts_rsrc_cgi_type_t type;
|
|
||||||
int rfd;
|
|
||||||
int wfd;
|
|
||||||
|
|
||||||
mio_svc_htts_rsrc_cgi_t handler;
|
|
||||||
pthread_t thr;
|
|
||||||
mio_svc_htts_rsrc_cgi_peer_t peer;
|
|
||||||
};
|
|
||||||
typedef struct rsrc_cgi_xtn_t rsrc_cgi_xtn_t;
|
|
||||||
|
|
||||||
static void rsrc_cgi_on_kill (mio_svc_htts_rsrc_t* rsrc)
|
|
||||||
{
|
|
||||||
rsrc_cgi_xtn_t* cgi = (rsrc_cgi_xtn_t*)mio_svc_htts_rsrc_getxtn(rsrc);
|
|
||||||
|
|
||||||
close (cgi->rfd); cgi->rfd = -1;
|
|
||||||
close (cgi->wfd); cgi->wfd = -1;
|
|
||||||
|
|
||||||
switch (cgi->type)
|
|
||||||
{
|
|
||||||
case MIO_SVC_HTTS_RSRC_CGI_TYPE_FUNC:
|
|
||||||
/* TODO: check cgi->thr is valid.
|
|
||||||
* non-blocking way? if alive, kill gracefully?? */
|
|
||||||
pthread_join (cgi->thr, MIO_NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MIO_SVC_HTTS_RSRC_CGI_TYPE_PROC:
|
|
||||||
/* TODO:
|
|
||||||
waitpid with no wait
|
|
||||||
still alive kill
|
|
||||||
waitpid with no wait.
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* cgi_thr_func (void* ctx)
|
|
||||||
{
|
|
||||||
rsrc_cgi_xtn_t* func = (rsrc_cgi_xtn_t*)ctx;
|
|
||||||
func->handler (func->peer.rfd, func->peer.wfd);
|
|
||||||
close (func->peer.rfd); func->peer.rfd = -1;
|
|
||||||
close (func->peer.wfd); func->peer.wfd = -1;
|
|
||||||
return MIO_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mio_svc_htts_sendcgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_svc_htts_rsrc_cgi_t handler, mio_htre_t* req)
|
|
||||||
{
|
|
||||||
mio_svc_htts_rsrc_t* rsrc = MIO_NULL;
|
|
||||||
rsrc_cgi_xtn_t* cgi = MIO_NULL;
|
|
||||||
int pfd[2];
|
|
||||||
|
|
||||||
rsrc = mio_svc_htts_rsrc_make(htts, csck, rsrc_cgi_on_kill, MIO_SIZEOF(*cgi));
|
|
||||||
if (MIO_UNLIKELY(!rsrc)) goto oops;
|
|
||||||
|
|
||||||
cgi = mio_svc_htts_rsrc_getxtn(rsrc);
|
|
||||||
cgi->type = MIO_SVC_HTTS_RSRC_CGI_TYPE_FUNC;
|
|
||||||
cgi->handler = handler;
|
|
||||||
cgi->rfd = -1;
|
|
||||||
cgi->wfd = -1;
|
|
||||||
cgi->peer.rfd = -1;
|
|
||||||
cgi->peer.wfd = -1;
|
|
||||||
|
|
||||||
if (pipe(pfd) == -1) goto oops;
|
|
||||||
cgi->peer.rfd = pfd[0];
|
|
||||||
cgi->wfd = pfd[1];
|
|
||||||
|
|
||||||
if (pipe(pfd) == -1) goto oops;
|
|
||||||
cgi->rfd = pfd[0];
|
|
||||||
cgi->peer.wfd = pfd[1];
|
|
||||||
|
|
||||||
if (pthread_create(&cgi->thr, MIO_NULL, cgi_thr_func, cgi) != 0) goto oops;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
oops:
|
|
||||||
if (cgi)
|
|
||||||
{
|
|
||||||
if (cgi->peer.rfd >= 0) { close (cgi->peer.rfd); cgi->peer.rfd = -1; }
|
|
||||||
if (cgi->peer.wfd >= 0) { close (cgi->peer.wfd); cgi->peer.wfd = -1; }
|
|
||||||
if (cgi->rfd >= 0) { close (cgi->rfd); cgi->rfd = -1; }
|
|
||||||
if (cgi->wfd >= 0) { close (cgi->wfd); cgi->wfd = -1; }
|
|
||||||
}
|
|
||||||
if (rsrc) mio_svc_htts_rsrc_kill (rsrc);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
int mio_svc_htts_sendrsrc (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_svc_htts_rsrc_t* rsrc, int status_code, mio_http_method_t method, const mio_http_version_t* version, int keepalive)
|
int mio_svc_htts_sendrsrc (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_svc_htts_rsrc_t* rsrc, int status_code, mio_http_method_t method, const mio_http_version_t* version, int keepalive)
|
||||||
|
@ -57,23 +57,30 @@ typedef void (*mio_dev_thr_on_close_t) (
|
|||||||
mio_dev_thr_sid_t sid
|
mio_dev_thr_sid_t sid
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef int (*mio_dev_thr_func_t) (
|
struct mio_dev_thr_iopair_t
|
||||||
mio_dev_thr_t* dev,
|
{
|
||||||
mio_syshnd_t rfd,
|
mio_syshnd_t rfd;
|
||||||
mio_syshnd_t wfd,
|
mio_syshnd_t wfd;
|
||||||
void* ctx
|
};
|
||||||
|
typedef struct mio_dev_thr_iopair_t mio_dev_thr_iopair_t;
|
||||||
|
|
||||||
|
typedef void (*mio_dev_thr_func_t) (
|
||||||
|
mio_t* mio,
|
||||||
|
mio_dev_thr_iopair_t* iop,
|
||||||
|
void* ctx
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef struct mio_dev_thr_info_t mio_dev_thr_info_t;
|
||||||
|
|
||||||
struct mio_dev_thr_t
|
struct mio_dev_thr_t
|
||||||
{
|
{
|
||||||
MIO_DEV_HEADER;
|
MIO_DEV_HEADER;
|
||||||
|
|
||||||
int flags;
|
|
||||||
mio_syshnd_t thr_fd[2];
|
|
||||||
mio_dev_thr_slave_t* slave[2];
|
mio_dev_thr_slave_t* slave[2];
|
||||||
int slave_count;
|
int slave_count;
|
||||||
|
|
||||||
mio_dev_thr_func_t thr_func;
|
mio_dev_thr_info_t* thr_info;
|
||||||
|
|
||||||
mio_dev_thr_on_read_t on_read;
|
mio_dev_thr_on_read_t on_read;
|
||||||
mio_dev_thr_on_write_t on_write;
|
mio_dev_thr_on_write_t on_write;
|
||||||
mio_dev_thr_on_close_t on_close;
|
mio_dev_thr_on_close_t on_close;
|
||||||
@ -87,18 +94,11 @@ struct mio_dev_thr_slave_t
|
|||||||
mio_dev_thr_t* master; /* parent device */
|
mio_dev_thr_t* master; /* parent device */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mio_dev_thr_make_flag_t
|
|
||||||
{
|
|
||||||
MIO_DEV_THR_WRITEIN = (1 << 0),
|
|
||||||
MIO_DEV_THR_READOUT = (1 << 1),
|
|
||||||
};
|
|
||||||
typedef enum mio_dev_thr_make_flag_t mio_dev_thr_make_flag_t;
|
|
||||||
|
|
||||||
typedef struct mio_dev_thr_make_t mio_dev_thr_make_t;
|
typedef struct mio_dev_thr_make_t mio_dev_thr_make_t;
|
||||||
struct mio_dev_thr_make_t
|
struct mio_dev_thr_make_t
|
||||||
{
|
{
|
||||||
int flags; /**< bitwise-ORed of mio_dev_thr_make_flag_t enumerators */
|
|
||||||
mio_dev_thr_func_t thr_func;
|
mio_dev_thr_func_t thr_func;
|
||||||
|
void* thr_ctx;
|
||||||
mio_dev_thr_on_write_t on_write; /* mandatory */
|
mio_dev_thr_on_write_t on_write; /* mandatory */
|
||||||
mio_dev_thr_on_read_t on_read; /* mandatory */
|
mio_dev_thr_on_read_t on_read; /* mandatory */
|
||||||
mio_dev_thr_on_close_t on_close; /* optional */
|
mio_dev_thr_on_close_t on_close; /* optional */
|
||||||
|
261
mio/lib/thr.c
261
mio/lib/thr.c
@ -48,23 +48,57 @@ static mio_dev_thr_slave_t* make_slave (mio_t* mio, slave_info_t* si);
|
|||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
struct thr_info_t
|
struct mio_dev_thr_info_t
|
||||||
{
|
{
|
||||||
mio_dev_thr_t* dev;
|
mio_t* mio;
|
||||||
mio_dev_thr_func_t thr_func;
|
mio_dev_thr_func_t thr_func;
|
||||||
mio_syshnd_t rfd;
|
mio_dev_thr_iopair_t thr_iop;
|
||||||
mio_syshnd_t wfd;
|
void* thr_ctx;
|
||||||
|
pthread_t thr_hnd;
|
||||||
|
int thr_done;
|
||||||
|
mio_tmridx_t cleanup_tmridx;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct thr_info_t thr_info_t;
|
typedef struct mio_dev_thr_info_t mio_dev_thr_info_t;
|
||||||
|
|
||||||
|
|
||||||
|
static void free_thr_info (mio_t* mio, mio_dev_thr_info_t* ti)
|
||||||
|
{
|
||||||
|
if (ti->thr_iop.rfd != MIO_SYSHND_INVALID)
|
||||||
|
{
|
||||||
|
close (ti->thr_iop.rfd);
|
||||||
|
ti->thr_iop.rfd = MIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
if (ti->thr_iop.wfd != MIO_SYSHND_INVALID)
|
||||||
|
{
|
||||||
|
close (ti->thr_iop.wfd);
|
||||||
|
ti->thr_iop.wfd = MIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
mio_freemem (mio, ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mark_thr_done (void* ctx)
|
||||||
|
{
|
||||||
|
mio_dev_thr_info_t* ti = (mio_dev_thr_info_t*)ctx;
|
||||||
|
printf ("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ\n");
|
||||||
|
ti->thr_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void* run_thr_func (void* ctx)
|
static void* run_thr_func (void* ctx)
|
||||||
{
|
{
|
||||||
thr_info_t* ti = (thr_info_t*)ctx;
|
mio_dev_thr_info_t* ti = (mio_dev_thr_info_t*)ctx;
|
||||||
//ti->thr_func (ti->dev, ti->rfd, ti->wfd, );
|
|
||||||
close (ti->rfd);
|
/* i assume the thread is cancellable, and of the deferred cancellation type by default */
|
||||||
close (ti->wfd);
|
/*int dummy;
|
||||||
mio_freemem (ti->dev->mio, ti);
|
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &dummy);
|
||||||
|
pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &dummy);*/
|
||||||
|
|
||||||
|
pthread_cleanup_push (mark_thr_done, ti);
|
||||||
|
|
||||||
|
ti->thr_func (ti->mio, &ti->thr_iop, ti->thr_ctx);
|
||||||
|
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
pthread_exit (MIO_NULL);
|
pthread_exit (MIO_NULL);
|
||||||
return MIO_NULL;
|
return MIO_NULL;
|
||||||
}
|
}
|
||||||
@ -75,129 +109,80 @@ static int dev_thr_make_master (mio_dev_t* dev, void* ctx)
|
|||||||
mio_dev_thr_t* rdev = (mio_dev_thr_t*)dev;
|
mio_dev_thr_t* rdev = (mio_dev_thr_t*)dev;
|
||||||
mio_dev_thr_make_t* info = (mio_dev_thr_make_t*)ctx;
|
mio_dev_thr_make_t* info = (mio_dev_thr_make_t*)ctx;
|
||||||
mio_syshnd_t pfds[4] = { MIO_SYSHND_INVALID, MIO_SYSHND_INVALID, MIO_SYSHND_INVALID, MIO_SYSHND_INVALID };
|
mio_syshnd_t pfds[4] = { MIO_SYSHND_INVALID, MIO_SYSHND_INVALID, MIO_SYSHND_INVALID, MIO_SYSHND_INVALID };
|
||||||
int i, minidx = -1, maxidx = -1;
|
slave_info_t si;
|
||||||
pid_t pid;
|
int i;
|
||||||
|
|
||||||
if (info->flags & MIO_DEV_THR_WRITEIN)
|
if (pipe(&pfds[0]) == -1 || pipe(&pfds[2]) == -1)
|
||||||
{
|
{
|
||||||
if (pipe(&pfds[0]) == -1)
|
mio_seterrwithsyserr (mio, 0, errno);
|
||||||
{
|
|
||||||
mio_seterrwithsyserr (mio, 0, errno);
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
minidx = 0; maxidx = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->flags & MIO_DEV_THR_READOUT)
|
|
||||||
{
|
|
||||||
if (pipe(&pfds[2]) == -1)
|
|
||||||
{
|
|
||||||
mio_seterrwithsyserr (mio, 0, errno);
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
if (minidx == -1) minidx = 2;
|
|
||||||
maxidx = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxidx == -1)
|
|
||||||
{
|
|
||||||
mio_seterrnum (mio, MIO_EINVAL);
|
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->flags & MIO_DEV_THR_WRITEIN)
|
if (mio_makesyshndasync(mio, pfds[1]) <= -1 ||
|
||||||
{
|
mio_makesyshndasync(mio, pfds[2]) <= -1) goto oops;
|
||||||
/*
|
|
||||||
* 0123
|
|
||||||
* rw--
|
|
||||||
* X
|
|
||||||
* WRITE => 1
|
|
||||||
*/
|
|
||||||
if (mio_makesyshndasync(mio, pfds[1]) <= -1) goto oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->flags & MIO_DEV_THR_READOUT)
|
si.mi = info;
|
||||||
{
|
si.pfd = pfds[1];
|
||||||
/*
|
si.dev_cap = MIO_DEV_CAP_OUT | MIO_DEV_CAP_STREAM;
|
||||||
* 0123
|
si.id = MIO_DEV_THR_IN;
|
||||||
* --rw
|
|
||||||
* X
|
|
||||||
* READ => 2
|
|
||||||
*/
|
|
||||||
if (mio_makesyshndasync(mio, pfds[2]) <= -1) goto oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfds[1] != MIO_SYSHND_INVALID)
|
rdev->slave[MIO_DEV_THR_IN] = make_slave(mio, &si);
|
||||||
{
|
if (!rdev->slave[MIO_DEV_THR_IN]) goto oops;
|
||||||
slave_info_t si;
|
|
||||||
|
|
||||||
si.mi = info;
|
pfds[1] = MIO_SYSHND_INVALID;
|
||||||
si.pfd = pfds[1];
|
rdev->slave_count++;
|
||||||
si.dev_cap = MIO_DEV_CAP_OUT | MIO_DEV_CAP_STREAM;
|
|
||||||
si.id = MIO_DEV_THR_IN;
|
|
||||||
|
|
||||||
rdev->slave[MIO_DEV_THR_IN] = make_slave(mio, &si);
|
si.mi = info;
|
||||||
if (!rdev->slave[MIO_DEV_THR_IN]) goto oops;
|
si.pfd = pfds[2];
|
||||||
|
si.dev_cap = MIO_DEV_CAP_IN | MIO_DEV_CAP_STREAM;
|
||||||
|
si.id = MIO_DEV_THR_OUT;
|
||||||
|
|
||||||
pfds[1] = MIO_SYSHND_INVALID;
|
rdev->slave[MIO_DEV_THR_OUT] = make_slave(mio, &si);
|
||||||
rdev->slave_count++;
|
if (!rdev->slave[MIO_DEV_THR_OUT]) goto oops;
|
||||||
}
|
|
||||||
|
|
||||||
if (pfds[2] != MIO_SYSHND_INVALID)
|
pfds[2] = MIO_SYSHND_INVALID;
|
||||||
{
|
rdev->slave_count++;
|
||||||
slave_info_t si;
|
|
||||||
|
|
||||||
si.mi = info;
|
|
||||||
si.pfd = pfds[2];
|
|
||||||
si.dev_cap = MIO_DEV_CAP_IN | MIO_DEV_CAP_STREAM;
|
|
||||||
si.id = MIO_DEV_THR_OUT;
|
|
||||||
|
|
||||||
rdev->slave[MIO_DEV_THR_OUT] = make_slave(mio, &si);
|
|
||||||
if (!rdev->slave[MIO_DEV_THR_OUT]) goto oops;
|
|
||||||
|
|
||||||
pfds[2] = MIO_SYSHND_INVALID;
|
|
||||||
rdev->slave_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < MIO_COUNTOF(rdev->slave); i++)
|
for (i = 0; i < MIO_COUNTOF(rdev->slave); i++)
|
||||||
{
|
{
|
||||||
if (rdev->slave[i]) rdev->slave[i]->master = rdev;
|
if (rdev->slave[i]) rdev->slave[i]->master = rdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CREATE THREAD. DATA. CREATE THREAD .. */
|
|
||||||
{
|
|
||||||
pthread_t thr;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
thr_info_t* ti;
|
|
||||||
|
|
||||||
ti = mio_callocmem(mio, MIO_SIZEOF(*ti));
|
|
||||||
if (MIO_UNLIKELY(!ti)) goto oops;
|
|
||||||
|
|
||||||
pthread_attr_init (&attr);
|
|
||||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
|
||||||
n = pthread_create(&thr, &attr, info->thr_func, ti);
|
|
||||||
pthread_attr_destroy (&attr);
|
|
||||||
if (n != 0)
|
|
||||||
{
|
|
||||||
mio_freemem (mio, ti);
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rdev->dev_cap = MIO_DEV_CAP_VIRTUAL; /* the master device doesn't perform I/O */
|
rdev->dev_cap = MIO_DEV_CAP_VIRTUAL; /* the master device doesn't perform I/O */
|
||||||
rdev->flags = info->flags;
|
|
||||||
rdev->thr_func = info->thr_func;
|
|
||||||
rdev->on_read = info->on_read;
|
rdev->on_read = info->on_read;
|
||||||
rdev->on_write = info->on_write;
|
rdev->on_write = info->on_write;
|
||||||
rdev->on_close = info->on_close;
|
rdev->on_close = info->on_close;
|
||||||
rdev->thr_fd[0] = pfds[0];
|
|
||||||
rdev->thr_fd[1] = pfds[3];
|
/* ---------------------------------------------------------- */
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
mio_dev_thr_info_t* ti;
|
||||||
|
|
||||||
|
ti = mio_callocmem(mio, MIO_SIZEOF(*ti));
|
||||||
|
if (MIO_UNLIKELY(!ti)) goto oops;
|
||||||
|
|
||||||
|
ti->mio = mio;
|
||||||
|
ti->thr_iop.rfd = pfds[0];
|
||||||
|
ti->thr_iop.wfd = pfds[3];
|
||||||
|
ti->thr_func = info->thr_func;
|
||||||
|
ti->thr_ctx = info->thr_ctx;
|
||||||
|
|
||||||
|
rdev->thr_info = ti;
|
||||||
|
n = pthread_create(&ti->thr_hnd, MIO_NULL, run_thr_func, ti);
|
||||||
|
if (n != 0)
|
||||||
|
{
|
||||||
|
rdev->thr_info = MIO_NULL;
|
||||||
|
mio_freemem (mio, ti);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
for (i = minidx; i < maxidx; i++)
|
for (i = 0; i < MIO_COUNTOF(pfds); i++)
|
||||||
{
|
{
|
||||||
if (pfds[i] != MIO_SYSHND_INVALID) close (pfds[i]);
|
if (pfds[i] != MIO_SYSHND_INVALID) close (pfds[i]);
|
||||||
}
|
}
|
||||||
@ -230,12 +215,27 @@ static int dev_thr_make_slave (mio_dev_t* dev, void* ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_and_free_thr_info (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* job)
|
||||||
|
{
|
||||||
|
mio_dev_thr_info_t* ti = (mio_dev_thr_info_t*)job->ctx;
|
||||||
|
if (ti->thr_done)
|
||||||
|
{
|
||||||
|
free_thr_info (mio, ti);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int dev_thr_kill_master (mio_dev_t* dev, int force)
|
static int dev_thr_kill_master (mio_dev_t* dev, int force)
|
||||||
{
|
{
|
||||||
mio_t* mio = dev->mio;
|
mio_t* mio = dev->mio;
|
||||||
mio_dev_thr_t* rdev = (mio_dev_thr_t*)dev;
|
mio_dev_thr_t* rdev = (mio_dev_thr_t*)dev;
|
||||||
int i, status;
|
mio_dev_thr_info_t* ti;
|
||||||
pid_t wpid;
|
int i;
|
||||||
|
|
||||||
|
ti = rdev->thr_info;
|
||||||
|
pthread_cancel (ti->thr_hnd);
|
||||||
|
|
||||||
if (rdev->slave_count > 0)
|
if (rdev->slave_count > 0)
|
||||||
{
|
{
|
||||||
@ -256,7 +256,38 @@ static int dev_thr_kill_master (mio_dev_t* dev, int force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: may have to kill thread... */
|
if (ti->thr_done)
|
||||||
|
{
|
||||||
|
printf ("THREAD DONE>...111\n");
|
||||||
|
pthread_detach (ti->thr_hnd); /* pthread_join() may be blocking. */
|
||||||
|
free_thr_info (mio, ti);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mio_tmrjob_t tmrjob;
|
||||||
|
MIO_MEMSET (&tmrjob, 0, MIO_SIZEOF(tmrjob));
|
||||||
|
tmrjob.ctx = ti;
|
||||||
|
mio_gettime (mio, &tmrjob.when);
|
||||||
|
tmrjob.when.sec++;
|
||||||
|
tmrjob.handler = check_and_free_thr_info;
|
||||||
|
tmrjob.idxptr = &ti->cleanup_tmridx;
|
||||||
|
|
||||||
|
if (ti->thr_done)
|
||||||
|
{
|
||||||
|
printf ("THREAD DONE>...222\n");
|
||||||
|
pthread_detach (ti->thr_hnd); /* pthread_join() may be blocking. */
|
||||||
|
free_thr_info (mio, ti);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("THREAD NOT DONE>...222\n");
|
||||||
|
//ti->cleanup_tmridx = mio_instmrjob(mio, &tmrjob);
|
||||||
|
pthread_join (ti->thr_hnd, MIO_NULL); /* pthread_join() may be blocking. */
|
||||||
|
mio_freemem (mio, ti);
|
||||||
|
//mio_instmrjob (mio,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rdev->thr_info = MIO_NULL;
|
||||||
|
|
||||||
if (rdev->on_close) rdev->on_close (rdev, MIO_DEV_THR_MASTER);
|
if (rdev->on_close) rdev->on_close (rdev, MIO_DEV_THR_MASTER);
|
||||||
return 0;
|
return 0;
|
||||||
@ -633,8 +664,6 @@ void mio_dev_thr_halt (mio_dev_thr_t* dev)
|
|||||||
|
|
||||||
int mio_dev_thr_read (mio_dev_thr_t* dev, int enabled)
|
int mio_dev_thr_read (mio_dev_thr_t* dev, int enabled)
|
||||||
{
|
{
|
||||||
mio_t* mio = dev->mio;
|
|
||||||
|
|
||||||
if (dev->slave[MIO_DEV_THR_OUT])
|
if (dev->slave[MIO_DEV_THR_OUT])
|
||||||
{
|
{
|
||||||
return mio_dev_read((mio_dev_t*)dev->slave[MIO_DEV_THR_OUT], enabled);
|
return mio_dev_read((mio_dev_t*)dev->slave[MIO_DEV_THR_OUT], enabled);
|
||||||
@ -648,15 +677,13 @@ int mio_dev_thr_read (mio_dev_thr_t* dev, int enabled)
|
|||||||
|
|
||||||
int mio_dev_thr_timedread (mio_dev_thr_t* dev, int enabled, const mio_ntime_t* tmout)
|
int mio_dev_thr_timedread (mio_dev_thr_t* dev, int enabled, const mio_ntime_t* tmout)
|
||||||
{
|
{
|
||||||
mio_t* mio = dev->mio;
|
|
||||||
|
|
||||||
if (dev->slave[MIO_DEV_THR_OUT])
|
if (dev->slave[MIO_DEV_THR_OUT])
|
||||||
{
|
{
|
||||||
return mio_dev_timedread((mio_dev_t*)dev->slave[MIO_DEV_THR_OUT], enabled, tmout);
|
return mio_dev_timedread((mio_dev_t*)dev->slave[MIO_DEV_THR_OUT], enabled, tmout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mio_seterrnum (mio, MIO_ENOCAPA); /* TODO: is it the right error number? */
|
mio_seterrnum (dev->mio, MIO_ENOCAPA); /* TODO: is it the right error number? */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user