mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
4.8 KiB
218 lines
4.8 KiB
#include <ev.h>
|
|
#include <pthread.h>
|
|
#include <netdb.h>
|
|
#include <oi.h>
|
|
|
|
#ifndef oi_async_h
|
|
#define oi_async_h
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct oi_async oi_async;
|
|
typedef struct oi_task oi_task;
|
|
|
|
struct oi_async {
|
|
/* private */
|
|
ev_async watcher;
|
|
struct ev_loop *loop;
|
|
|
|
oi_queue finished_tasks;
|
|
oi_queue new_tasks;
|
|
|
|
/* public */
|
|
void *data;
|
|
};
|
|
|
|
typedef void (*oi_task_int_cb)(oi_task *, int result);
|
|
typedef void (*oi_task_uint_cb)(oi_task *, unsigned int result);
|
|
typedef void (*oi_task_ssize_cb)(oi_task *, ssize_t result);
|
|
|
|
struct oi_task {
|
|
/* private */
|
|
oi_async *async;
|
|
oi_queue queue;
|
|
int type;
|
|
union {
|
|
|
|
struct {
|
|
const char *pathname;
|
|
int flags;
|
|
mode_t mode;
|
|
oi_task_int_cb cb;
|
|
int result;
|
|
} open;
|
|
|
|
struct {
|
|
int fd;
|
|
void *buf;
|
|
size_t count;
|
|
oi_task_ssize_cb cb;
|
|
ssize_t result;
|
|
} read;
|
|
|
|
struct {
|
|
int fd;
|
|
const void *buf;
|
|
size_t count;
|
|
oi_task_ssize_cb cb;
|
|
ssize_t result;
|
|
} write;
|
|
|
|
struct {
|
|
int fd;
|
|
oi_task_int_cb cb;
|
|
int result;
|
|
} close;
|
|
|
|
struct {
|
|
unsigned int seconds;
|
|
oi_task_uint_cb cb;
|
|
unsigned int result;
|
|
} sleep;
|
|
|
|
struct {
|
|
int out_fd;
|
|
int in_fd;
|
|
off_t offset;
|
|
size_t count;
|
|
oi_task_ssize_cb cb;
|
|
ssize_t result;
|
|
} eio__sendfile;
|
|
|
|
struct {
|
|
const char *nodename; /* restrict ? */
|
|
const char *servname; /* restrict ? */
|
|
struct addrinfo *hints;
|
|
struct addrinfo **res; /* restrict ? */
|
|
oi_task_int_cb cb;
|
|
int result;
|
|
} getaddrinfo;
|
|
|
|
struct {
|
|
const char *path;
|
|
struct stat *buf;
|
|
oi_task_int_cb cb;
|
|
int result;
|
|
} lstat;
|
|
|
|
} params;
|
|
|
|
/* read-only */
|
|
volatile unsigned active:1;
|
|
int errorno;
|
|
|
|
/* public */
|
|
void *data;
|
|
};
|
|
|
|
void oi_async_init (oi_async *);
|
|
void oi_async_attach (struct ev_loop *loop, oi_async *);
|
|
void oi_async_detach (oi_async *);
|
|
void oi_async_submit (oi_async *, oi_task *);
|
|
|
|
/* To submit a task for async processing
|
|
* (0) allocate memory for your task
|
|
* (1) initialize the task with one of the functions below
|
|
* (2) optionally set the task->data pointer
|
|
* (3) oi_async_submit() the task
|
|
*/
|
|
|
|
enum { OI_TASK_OPEN
|
|
, OI_TASK_READ
|
|
, OI_TASK_WRITE
|
|
, OI_TASK_CLOSE
|
|
, OI_TASK_SLEEP
|
|
, OI_TASK_SENDFILE
|
|
, OI_TASK_GETADDRINFO
|
|
, OI_TASK_LSTAT
|
|
};
|
|
|
|
#define oi_task_init_common(task, _type) do {\
|
|
(task)->active = 0;\
|
|
(task)->async = NULL;\
|
|
(task)->type = _type;\
|
|
} while(0)
|
|
|
|
static inline void
|
|
oi_task_init_open(oi_task *t, oi_task_int_cb cb, const char *pathname, int flags, mode_t mode)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_OPEN);
|
|
t->params.open.cb = cb;
|
|
t->params.open.pathname = pathname;
|
|
t->params.open.flags = flags;
|
|
t->params.open.mode = mode;
|
|
}
|
|
|
|
static inline void
|
|
oi_task_init_read(oi_task *t, oi_task_ssize_cb cb, int fd, void *buf, size_t count)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_READ);
|
|
t->params.read.cb = cb;
|
|
t->params.read.fd = fd;
|
|
t->params.read.buf = buf;
|
|
t->params.read.count = count;
|
|
}
|
|
|
|
static inline void
|
|
oi_task_init_write(oi_task *t, oi_task_ssize_cb cb, int fd, const void *buf, size_t count)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_WRITE);
|
|
t->params.write.cb = cb;
|
|
t->params.write.fd = fd;
|
|
t->params.write.buf = buf;
|
|
t->params.write.count = count;
|
|
}
|
|
|
|
static inline void
|
|
oi_task_init_close(oi_task *t, oi_task_int_cb cb, int fd)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_CLOSE);
|
|
t->params.close.cb = cb;
|
|
t->params.close.fd = fd;
|
|
}
|
|
|
|
static inline void
|
|
oi_task_init_sleep(oi_task *t, oi_task_uint_cb cb, unsigned int seconds)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_SLEEP);
|
|
t->params.sleep.cb = cb;
|
|
t->params.sleep.seconds = seconds;
|
|
}
|
|
|
|
static inline void
|
|
oi_task_init_sendfile(oi_task *t, oi_task_ssize_cb cb, int out_fd, int in_fd, off_t offset, size_t count)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_SENDFILE);
|
|
t->params.eio__sendfile.cb = cb;
|
|
t->params.eio__sendfile.out_fd = out_fd;
|
|
t->params.eio__sendfile.in_fd = in_fd;
|
|
t->params.eio__sendfile.offset = offset;
|
|
t->params.eio__sendfile.count = count;
|
|
}
|
|
|
|
static inline void
|
|
oi_task_init_getaddrinfo(oi_task *t, oi_task_int_cb cb, const char *node,
|
|
const char *service, struct addrinfo *hints, struct addrinfo **res)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_GETADDRINFO);
|
|
t->params.getaddrinfo.cb = cb;
|
|
t->params.getaddrinfo.nodename = node;
|
|
t->params.getaddrinfo.servname = service;
|
|
t->params.getaddrinfo.hints = hints;
|
|
t->params.getaddrinfo.res = res;
|
|
}
|
|
|
|
static inline void
|
|
oi_task_init_lstat(oi_task *t, oi_task_int_cb cb, const char *path, struct stat *buf)
|
|
{
|
|
oi_task_init_common(t, OI_TASK_LSTAT);
|
|
t->params.lstat.cb = cb;
|
|
t->params.lstat.path = path;
|
|
t->params.lstat.buf = buf;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* oi_async_h */
|
|
|