Initial import of libucore
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "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, ©_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, ©_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, ©_ctx->buffer[copy_ctx->r_idx], len);
|
||||
if(rc <= 0) {
|
||||
if(rc == -1 && errno == EAGAIN) {
|
||||
return;
|
||||
} else {
|
||||
perror("write");
|
||||
iomux_unregister_fd(mux, ©_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, ©_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_timer_add(timers, t, 5,5);
|
||||
t = calloc(1, sizeof *t);
|
||||
t->callback = timer_cb;
|
||||
t->cookie_int = timer->cookie_int + 2;
|
||||
uc_timer_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 = ©_ctx,
|
||||
},
|
||||
.out = {
|
||||
.fd = 1,
|
||||
.callback = out_cb,
|
||||
.cookie_ptr = ©_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, ©_ctx.in);
|
||||
uc_timer_add(iomux_get_timers(mux), &timer, 5, 0);
|
||||
|
||||
iomux_run(mux);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user