remove old files

This commit is contained in:
Ryan Dahl 2011-03-29 15:29:32 -07:00
parent 510a5e4a2b
commit 06b00e58cf
2 changed files with 0 additions and 487 deletions

187
ol-old.h
View File

@ -1,187 +0,0 @@
/**
* Overlapped I/O for every operating system.
*/
#ifdef __POSIX__
# include "ol-unix.h"
#else
# include "ol-win.h"
#endif
typedef struct {
int code;
const char* msg;
} ol_err;
/**
* Error codes are not cross-platform, so we have our own.
*/
typedef enum {
OL_SUCCESS = 0,
OL_EPENDING = -1,
OL_EPIPE = -2,
OL_EMEM = -3
} ol_err;
inline const char* ol_err_string(int errorno) {
switch (errorno) {
case OL_SUCCESS:
case OL_EPENDING:
return "";
case OL_EPIPE:
return "EPIPE: Write to non-writable handle";
case OL_EMEM:
return "EMEM: Out of memory!";
default:
assert(0);
return "Unknown error code. Bug.";
}
}
/**
* Do not make assumptions about the order of the elements in this sturct.
* Always use offsetof because the order is platform dependent. Has a char*
* buf and size_t len. That's all you need to know.
*/
struct ol_buf;
typedef enum {
OL_TCP,
OL_TCP6,
OL_NAMED_PIPE,
OL_FILE,
OL_TTY
} ol_handle_type;
typedef void(*)(ol_handle* h, ol_buf *bufs, int bufcnt) ol_read_cb;
typedef void(*)(ol_handle* h) ol_connect_cb;
typedef void(*)(ol_handle* h, ol_handle *peer) ol_accept_cb;
typedef void(*)(ol_handle* h) ol_write_cb;
typedef enum {
OL_READ,
OL_WRITE,
OL_CONNECT,
OL_ACCEPT,
OL_DESTROY
} ol_req_type;
typedef struct {
ol_req_type type;
ol_req_private _;
/* following are rw */
union {
ol_write_cb write_cb;
ol_connect_cb connect_cb;
};
void* data; /* rw */
} ol_req;
ol_handle* ol_handle_new();
ol_handle* ol_open_file(ol_handle* h, ol_req* req, char *filename);
ol_handle* ol_open_named_pipe(ol_handle* h, ol_req* req, char *filename);
ol_handle* ol_open_tty(ol_handle* h, ol_req* req);
struct sockaddr oi_ip4_addr(char*, int port);
/**
* Depth of write buffer in bytes.
*/
size_t ol_buffer_size(ol_handle* h);
/**
* Returns file descriptor associated with the handle. There may be only
* limited numbers of file descriptors allowed by the operating system. On
* Windows this limit is 2048 (see
* _setmaxstdio[http://msdn.microsoft.com/en-us/library/6e3b887c.aspx])
*/
int ol_get_fd(ol_handle* h);
/**
* Returns the type of the handle.
*/
ol_handle_type ol_get_type(ol_handle* h);
/**
* Only works with named pipes and TCP sockets.
*/
int ol_connect(ol_handle* h, ol_req* req, sockaddr* addr, ol_buf* initial_buf);
int ol_accept(ol_handle* h, ol_req* req);
/**
* Send data to handle. User responsible for bufs until callback is made.
* Multiple ol_handle_write() calls may be issued before the previous ones
* complete - data will sent in the correct order.
*
* Returns zero on succuessful write and bytes_sent is filled with the
* number of bytes successfully written. If an asyncrhonous write was
* successfully initiated then OL_EAGAIN is returned.
*/
int ol_write(ol_handle* h, ol_req* req, ol_buf* bufs, int bufcnt);
int ol_write2(ol_handle* h, ol_req* req, const char *string);
int ol_read(ol_handle* h, ol_req* req, ol_buf* bufs, int bufcnt);
/**
* Works on both named pipes and TCP handles. Synchronous.
*/
int ol_listen(ol_handle* h, int backlog);
/**
* See http://msdn.microsoft.com/en-us/library/ms737757(v=VS.85).aspx
*/
int ol_disconnect(ol_handle* h, ol_req* req);
/**
* Immediately closes the handle. If there is data in the send buffer
* it will not be sent.
*/
int ol_close(ol_handle* h);
/**
* Releases memory associated with handle. You MUST call this after
* is made with both 0 arguments.
*/
int ol_free(ol_handle* h);
ol_loop* ol_loop_new();
void ol_associate(ol_loop* loop, ol_handle* handle);
void ol_loop_free(ol_loop* loop);
void ol_run(ol_loop* loop);

View File

@ -1,300 +0,0 @@
#include "ol.h"
ol_loop* ol_loop_new() {
ol_loop* loop = calloc(sizeof(ol_loop), 1);
if (!loop) {
return NULL;
}
loop.evloop = ev_loop_new(0);
if (!loop.evloop) {
return NULL;
}
return loop;
}
void ol_associate(ol_loop* loop, ol_handle* handle) {
assert(!handle->loop);
handle->loop = loop;
}
void ol_run(ol_loop *loop) {
ev_run(loop, 0);
}
ol_handle* ol_tcp_new(int v4, sockaddr* addr, sockaddr_len len,
ol_read_cb read_cb, ol_close_cb close_cb) {
ol_handle *handle = calloc(sizeof(ol_handle), 1);
if (!handle) {
return NULL;
}
handle->read_cb = read_cb;
handle->close_cb = close_cb;
handle->type = v4 ? OL_TCP : OL_TCP6;
int domain = v4 ? AF_INET : AF_INET6;
handle->fd = socket(domain, SOCK_STREAM, 0);
if (handle->fd == -1) {
free(handle);
got_error("socket", err);
return NULL;
}
/* Lose the pesky "Address already in use" error message */
int yes = 1;
int r = setsockopt(handle->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
if (r == -1) {
close(handle->fd);
free(handle);
unhandled_error("setsockopt", r);
return NULL;
}
/* We auto-bind the specified address */
if (addr) {
int r = bind(handle->fd, addr, v4 ? sizeof(sockaddr_in) :
sizeof(sockaddr_in6));
if (r < 0) {
got_error("bind", errno);
close(handle->fd);
free(handle);
return NULL;
}
}
return handle;
}
static void tcp_io(EV_P_ ev_io *w, int revents) {
ol_handle* h = (ol_handle*)w->data;
if (h->connecting) {
tcp_check_connect_status(h);
} else {
}
}
static void tcp_check_connect_status(ol_handle* h) {
assert(h->connecting);
int error;
socklen_t len = sizeof(int);
getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &error, &len);
if (error == 0) {
tcp_connected(h);
} else if (err != EINPROGRESS) {
close(h->fd);
got_error("connect", err);
}
/* EINPROGRESS - unlikely. What to do? */
}
ol_bucket* ol_handle_first_bucket(ol_handle* h) {
ngx_queue_t* element = ngx_queue_head(h);
if (!element) {
return NULL;
}
return ngx_queue_data(element, ol_bucket, write_queue);
}
static void tcp_flush(oi_loop* loop, ol_handle* h) {
ol_bucket* bucket = ol_handle_first_bucket(h);
for (; bucket; bucket = ol_handle_first_bucket(h)) {
io_vec* vec = (io_vec*) bucket->bufs[bucket->current_index];
int remaining_bufcnt = bucket->bufcnt - bucket->current_index;
ssize_t written = writev(h->fd, vec, remaining_bufcnt);
if (written < 0) {
if (err == EAGAIN) {
ev_io_start(loop, &h->write_watcher);
} else {
got_error("writev", err);
}
} else {
/* See how much was written, increase current_index, and update bufs. */
oi_buf current = bucket->bufs[bucket->current_index];
while (bucket->current_index < bucket->bufcnt) {
if (current.len >= written) {
current = bucket->bufs[++bucket->current_index];
} else {
bucket->bufs[bucket->current_index].buf += written;
break;
}
}
}
}
}
static void tcp_connected(ol_handle* h) {
assert(h->connecting);
if (h->connect_cb) {
h->connect_cb(h);
}
h->connecting = 0;
h->connect_cb = NULL;
ev_io_init(&h->read_watcher, tcp_io, h->fd, EV_READ);
ev_io_start(h->loop, &h->read_watcher);
if (ngx_queue_empty(&h->write_queue)) {
ev_io_stop(h->loop, &h->write_watcher);
} else {
/* Now that we're connected let's try to flush. */
tcp_flush(h);
}
}
int ol_connect(ol_handle* h, sockaddr* addr, sockaddr_len addrlen,
ol_buf* buf, ol_connect_cb connect_cb) {
if (h->connecting) {
return got_error("connect", EALREADY);
}
h->connecting = 1;
h->connect_addr = addr;
h->connect_addrlen = addrlen;
if (buf) {
/* We're allowed to ol_write before the socket becomes connected. */
ol_write(h, buf, 1, connect_cb);
} else {
/* Nothing to write. Don't call the callback until we're connected. */
h->connect_cb = connect_cb;
}
int r = connect(h->fd, h->connect_addr, h->connect_addrlen);
if (r != 0) {
if (err == EINPROGRESS) {
/* Wait for fd to become writable. */
h->connecting = 1;
ev_io_init(&h->write_watcher, tcp_io, h->fd, EV_WRITE);
ev_io_start(h->loop, &h->write_watcher);
}
return got_error("connect", err);
}
/* Connected */
tcp_connected(h);
return 0;
}
int ol_get_fd(ol_handle* h) {
return h->fd;
}
ol_bucket* bucket_new(oi_handle* h, oi_buf* bufs, int bufcnt, ol_write_cb cb) {
ol_bucket* bucket = malloc(sizeof(ol_bucket));
if (!bucket) {
got_error("malloc", OL_EMEM);
return NULL;
}
bucket->bufs = bufs;
bucket->bufcnt = bufcnt;
bucket->write_cb = write_cb;
bucket->handle = handle;
ngx_queue_init(&bucket->write_queue);
return bucket;
}
int ol_write(ol_handle* h, ol_buf* bufs, int bufcnt, ol_write_cb cb) {
if (!h->connecting && !h->writable) {
return got_error("write", OL_EPIPE);
}
if (!h->writable) {
/* This happens when writing to a socket which is not connected yet. */
bucket* b = bucket_new(h, buf, bufcnt, cb);
bucket_append(h, b);
return got_error("write", OL_EPENDING);
}
ssize_t written;
/* If the write queue is empty, attempt to write now. */
if (ngx_queue_empty(&h->write_queue)) {
/* The queue is empty. Attempt the writev immediately. */
written = writev(h->fd, (io_vec*)bufs, bufcnt);
if (written >= 0) {
size_t seen = 0;
/* Figure out what's left to be written */
for (int i = 0; i < bufcnt; i++) {
seen += bufs[i].len;
if (seen == written) {
/* We wrote the entire thing. */
return 0;
}
if (seen > written) {
break;
}
}
assert(seen > written);
/* We've made a partial write of the bufs. bufs[i] is the first buf
* that wasn't totally flushed. We must now add
* bufs[i], bufs[i + 1], ..., bufs[bufcnt - 1]
* to the write queue.
*/
}
}
}
int ol_write2(ol_handle* h, char *base, size_t len) {
ol_buf buf;
buf.base = base;
buf.len = len;
return ol_write(h, &buf, 1, NULL);
}
int ol_write3(ol_handle* h, const char *string) {
/* You're doing it wrong if strlen(string) > 1mb. */
return ol_write2(h, string, strnlen(string, 1024 * 1024));
}
struct sockaddr oi_ip4_addr(char *ip, int port) {
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
return addr;
}