Created
September 10, 2012 16:29
-
-
Save fancycode/3691934 to your computer and use it in GitHub Desktop.
Sample usage of indirect bufferevent
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Sample pseudo-code usage of the indirect bufferevent API: | |
https://github.com/fancycode/Libevent/tree/bufferevent_indirect | |
**/ | |
/** External IO loop, runs in separate thread. **/ | |
void external_io_loop() | |
{ | |
while (running) { | |
wait_for_socket_events(all_watched_sockets, &readable, &writable); | |
for (socket in all_watched_sockets) { | |
if (socket->now_connected) | |
bufferevent_indirect_notify_event(socket->bufferevent, BEV_EVENT_CONNECTED); | |
if (socket->has_error) | |
bufferevent_indirect_notify_event(socket->bufferevent, BEV_EVENT_ERROR); | |
what = 0; | |
if (socket in readable) | |
what |= EV_READ; | |
if (socket in writable) | |
what |= EV_WRITE; | |
if (what) | |
bufferevent_indirect_notify_ready(socket->bufferevent, what); | |
} | |
} | |
} | |
int my_read(struct bufferevent *bev, void *indirect, void *data, size_t *size) | |
{ | |
socket = (my_socket_type *) indirect; | |
result = 0; | |
read = socket->read(data, *size); | |
if (socket->read_blocked) | |
result |= BEV_INDIRECT_BLOCKED; | |
if (read > 0) | |
result |= BEV_INDIRECT_MADE_PROGRESS; | |
if (read < 0) | |
result |= BEV_INDIRECT_ERR; | |
*size = read; | |
return result; | |
} | |
int my_write(struct bufferevent *bev, void *indirect, struct evbuffer *data) | |
{ | |
socket = (my_socket_type *) indirect; | |
result = 0; | |
written = socket->write(evbuffer_pullup(data), evbuffer_get_length(data)); | |
evbuffer_drain(data, written); | |
if (socket->write_blocked) | |
result |= BEV_INDIRECT_BLOCKED; | |
if (written > 0) | |
result |= BEV_INDIRECT_MADE_PROGRESS; | |
if (written < 0) | |
result |= BEV_INDIRECT_ERR; | |
return result; | |
} | |
int my_enable(struct bufferevent *bev, void *indirect, short what) | |
{ | |
socket = (my_socket_type *) indirect; | |
socket->start_watch_for(what); | |
return 0; | |
} | |
int my_enable(struct bufferevent *bev, void *indirect, short what) | |
{ | |
socket = (my_socket_type *) indirect; | |
socket->stop_watch_for(what); | |
return 0; | |
} | |
int my_connect(struct bufferevent *bev, void *indirect, struct sockaddr *addr, int socklen) | |
{ | |
socket = (my_socket_type *) indirect; | |
socket->start_connecting(addr, socklen); | |
return 0; | |
} | |
int my_cleanup(struct bufferevent *bev, void *indirect) | |
{ | |
socket = (my_socket_type *) indirect; | |
socket->cleanup(); | |
delete socket; | |
return 0; | |
} | |
static const struct bufferevent_indirect_callbacks my_indirect_callbacks = { | |
my_read, | |
my_write, | |
my_enable, | |
my_disable, | |
my_connect, | |
my_cleanup | |
}; | |
/** Create indirect bufferevent and connect to remote end. **/ | |
void create_and_connect() | |
{ | |
socket = new my_internal_socket_object(); | |
socket->bufferevent = bufferevent_indirect_new(event_base, socket, my_indirect_callbacks, 0); | |
bufferevent_indirect_connect_hostname(socket->bufferevent, NULL, AF_UNSPEC, "remote-server", 1234); | |
// start external io loop and dispatch libevent event base | |
// the indirect bufferevent can now be used just like the other bufferevents | |
// and all io will be delegated to the external api | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment