Skip to content

Instantly share code, notes, and snippets.

@fancycode
Created September 10, 2012 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fancycode/3691934 to your computer and use it in GitHub Desktop.
Save fancycode/3691934 to your computer and use it in GitHub Desktop.
Sample usage of indirect bufferevent
/**
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