+void client_io_rw(client_t *server)
+{
+ ev_io_stop(gl_loop, &server->io.io);
+ ev_io_set(&server->io.io, server->io.fd, EV_READ | EV_WRITE);
+ ev_io_start(gl_loop, &server->io.io);
+}
+
+void client_io_ro(client_t *server)
+{
+ ev_io_stop(gl_loop, &server->io.io);
+ ev_io_set(&server->io.io, server->io.fd, EV_READ);
+ ev_io_start(gl_loop, &server->io.io);
+}
+
+ssize_t client_read(client_t *client)
+{
+ return buffer_read(&client->ibuf, client->io.fd, -1);
+}
+
+buffer_t *client_input_buffer(client_t *client)
+{
+ return &client->ibuf;
+}
+
+buffer_t *client_output_buffer(client_t *client)
+{
+ return &client->obuf;
+}
+
+void *client_data(client_t *client)
+{
+ return client->data;
+}
+
+
+static void client_cb(EV_P_ struct ev_io *w, int events)
+{
+ client_t *server = (client_t*)w;
+
+ if (events & EV_WRITE && server->obuf.len) {
+ if (buffer_write(&server->obuf, server->io.fd) < 0) {
+ client_release(server);
+ return;
+ }
+ if (!server->obuf.len) {
+ client_io_ro(server);
+ }