|
|
|
@ -14,20 +14,38 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static ssize_t __fd_write(void *, const void *, size_t); |
|
|
|
static ssize_t __fd_read(void *, void *, size_t); |
|
|
|
|
|
|
|
struct streambuf *streambuf_new(struct poller *p, int fd) { |
|
|
|
static const struct streambuf_funcs __fd_funcs = { |
|
|
|
.write = __fd_write, |
|
|
|
.read = __fd_read, |
|
|
|
}; |
|
|
|
|
|
|
|
static ssize_t __fd_write(void *fd, const void *b, size_t s) { |
|
|
|
return write(GPOINTER_TO_INT(fd), b, s); |
|
|
|
} |
|
|
|
static ssize_t __fd_read(void *fd, void *b, size_t s) { |
|
|
|
return read(GPOINTER_TO_INT(fd), b, s); |
|
|
|
} |
|
|
|
|
|
|
|
struct streambuf *streambuf_new_ptr(struct poller *p, void *fd_ptr, const struct streambuf_funcs *funcs) { |
|
|
|
struct streambuf *b; |
|
|
|
|
|
|
|
b = g_slice_alloc0(sizeof(*b)); |
|
|
|
|
|
|
|
mutex_init(&b->lock); |
|
|
|
b->buf = g_string_new(""); |
|
|
|
b->fd = fd; |
|
|
|
b->fd_ptr = fd_ptr; |
|
|
|
b->poller = p; |
|
|
|
b->active = rtpe_now.tv_sec; |
|
|
|
b->funcs = funcs; |
|
|
|
|
|
|
|
return b; |
|
|
|
} |
|
|
|
struct streambuf *streambuf_new(struct poller *p, int fd) { |
|
|
|
return streambuf_new_ptr(p, GINT_TO_POINTER(fd), &__fd_funcs); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void streambuf_destroy(struct streambuf *b) { |
|
|
|
@ -47,7 +65,7 @@ int streambuf_writeable(struct streambuf *b) { |
|
|
|
break; |
|
|
|
|
|
|
|
out = (b->buf->len > 1024) ? 1024 : b->buf->len; |
|
|
|
ret = write(b->fd, b->buf->str, out); |
|
|
|
ret = b->funcs->write(b->fd_ptr, b->buf->str, out); |
|
|
|
|
|
|
|
if (ret < 0) { |
|
|
|
if (errno == EINTR) |
|
|
|
@ -65,7 +83,7 @@ int streambuf_writeable(struct streambuf *b) { |
|
|
|
} |
|
|
|
|
|
|
|
if (ret != out) { |
|
|
|
poller_blocked(b->poller, b->fd); |
|
|
|
poller_blocked(b->poller, b->fd_ptr); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -81,7 +99,7 @@ int streambuf_readable(struct streambuf *b) { |
|
|
|
mutex_lock(&b->lock); |
|
|
|
|
|
|
|
for (;;) { |
|
|
|
ret = read(b->fd, buf, 1024); |
|
|
|
ret = b->funcs->read(b->fd_ptr, buf, 1024); |
|
|
|
|
|
|
|
if (ret == 0) { |
|
|
|
// don't discard already read data in the buffer |
|
|
|
@ -188,18 +206,18 @@ void streambuf_write(struct streambuf *b, const char *s, unsigned int len) { |
|
|
|
|
|
|
|
mutex_lock(&b->lock); |
|
|
|
|
|
|
|
while (len && !poller_isblocked(b->poller, b->fd)) { |
|
|
|
while (len && !poller_isblocked(b->poller, b->fd_ptr)) { |
|
|
|
out = (len > 1024) ? 1024 : len; |
|
|
|
ret = write(b->fd, s, out); |
|
|
|
ret = b->funcs->write(b->fd_ptr, s, out); |
|
|
|
|
|
|
|
if (ret < 0) { |
|
|
|
if (errno == EINTR) |
|
|
|
continue; |
|
|
|
if (errno != EAGAIN && errno != EWOULDBLOCK) { |
|
|
|
poller_error(b->poller, b->fd); |
|
|
|
poller_error(b->poller, b->fd_ptr); |
|
|
|
break; |
|
|
|
} |
|
|
|
poller_blocked(b->poller, b->fd); |
|
|
|
poller_blocked(b->poller, b->fd_ptr); |
|
|
|
break; |
|
|
|
} |
|
|
|
if (ret == 0) |
|
|
|
@ -211,7 +229,7 @@ void streambuf_write(struct streambuf *b, const char *s, unsigned int len) { |
|
|
|
} |
|
|
|
|
|
|
|
if (b->buf->len > 5242880) |
|
|
|
poller_error(b->poller, b->fd); |
|
|
|
poller_error(b->poller, b->fd_ptr); |
|
|
|
else if (len) |
|
|
|
g_string_append_len(b->buf, s, len); |
|
|
|
|
|
|
|
|