Files
2014-09-12 01:11:41 +02:00

141 lines
3.2 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include "ucore/iomux.h"
#define BUFLEN (4098*66)
struct Copy {
struct IOMuxFD in;
struct IOMuxFD out;
char buffer[BUFLEN];
size_t w_idx;
size_t r_idx;
int out_running;
};
void in_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
{
struct Copy *copy_ctx = fd->cookie_ptr;
size_t left = BUFLEN - copy_ctx->w_idx;
ssize_t rc;
left /= 2;
if (left == 0)
left++;
rc = read(fd->fd, &copy_ctx->buffer[copy_ctx->w_idx], left);
if (rc <= 0) {
if (rc == -1 && errno == EAGAIN) {
return;
} else if (rc == -1) {
perror("read");
}
iomux_unregister_fd(mux, fd);
return;
}
copy_ctx->w_idx += rc;
if (!copy_ctx->out_running) {
copy_ctx->out.what = MUX_EV_WRITE;
iomux_register_fd(mux, &copy_ctx->out);
copy_ctx->out_running = 1;
}
if (copy_ctx->w_idx == BUFLEN) {
iomux_unregister_fd(mux, fd);
}
}
void out_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
{
struct Copy *copy_ctx = fd->cookie_ptr;
ssize_t rc;
size_t len = copy_ctx->w_idx - copy_ctx->r_idx;
rc = write(1, &copy_ctx->buffer[copy_ctx->r_idx], len);
if (rc <= 0) {
if (rc == -1 && errno == EAGAIN) {
return;
} else {
perror("write");
iomux_unregister_fd(mux, &copy_ctx->in);
}
iomux_unregister_fd(mux, fd);
copy_ctx->out_running = 0;
} else {
copy_ctx->r_idx += rc;
if (copy_ctx->r_idx == copy_ctx->w_idx) {
iomux_unregister_fd(mux, fd);
copy_ctx->out_running = 0;
if (copy_ctx->w_idx == BUFLEN) {
copy_ctx->w_idx = 0;
copy_ctx->r_idx = 0;
iomux_register_fd(mux, &copy_ctx->in);
}
}
}
}
int set_nonblocking(int fd)
{
int flags = fcntl(fd,F_GETFL,NULL);
if (flags < 0 ) {
return flags;
}
return fcntl(fd,F_SETFL,flags | O_NONBLOCK);
}
void timer_cb(struct UCTimers *timers, struct UCTimer *timer)
{
fprintf(stderr, "Timer %d fired\n", timer->cookie_int);
struct UCTimer *t = calloc(1, sizeof *t);
t->callback = timer_cb;
t->cookie_int = timer->cookie_int + 1;
uc_timers_add(timers, t, 5,5);
t = calloc(1, sizeof *t);
t->callback = timer_cb;
t->cookie_int = timer->cookie_int + 2;
uc_timers_add(timers, t, 5,4);
}
int main(int argc, char *argv[])
{
struct Copy copy_ctx = {
.in = {
.fd = 0,
.what = MUX_EV_READ,
.callback = in_cb,
.cookie_ptr = &copy_ctx,
},
.out = {
.fd = 1,
.callback = out_cb,
.cookie_ptr = &copy_ctx,
}
};
struct UCTimer timer = {
.callback = timer_cb,
};
set_nonblocking(0);
set_nonblocking(1);
struct IOMux *mux = iomux_create(IOMUX_TYPE_EPOLL);
iomux_register_fd(mux, &copy_ctx.in);
uc_timers_add(iomux_get_timers(mux), &timer, 5, 0);
iomux_run(mux);
return 0;
}