Skip to content

Instantly share code, notes, and snippets.

@saghul
Created May 19, 2015 15:02
Show Gist options
  • Save saghul/f58fcda21c84bc81dbab to your computer and use it in GitHub Desktop.
Save saghul/f58fcda21c84bc81dbab to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "glibuv.h"
typedef struct uv_source_s uv_source_t;
struct uv_source_s
{
GSource base;
uv_loop_t *loop;
gpointer tag;
};
static gboolean
uv_source_prepare(GSource *source, gint *timeout)
{
uv_source_t *uv_source = (uv_source_t*)source;
uv_update_time(uv_source->loop);
*timeout = uv_backend_timeout(uv_source->loop);
FALSE;
}
static gboolean
uv_source_check(GSource *source)
{
return TRUE;
}
static gboolean
uv_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
{
uv_source_t *uv_source = (uv_source_t*)source;
uv_run(uv_source->loop, UV_RUN_NOWAIT);
return TRUE;
}
static GSourceFuncs uv_source_funcs =
{
.prepare = uv_source_prepare,
.check = uv_source_check,
.dispatch = uv_source_dispatch,
};
GSource*
g_uv_source_new(uv_loop_t *loop)
{
GSource *source;
uv_source_t *uv_source;
source = g_source_new(&uv_source_funcs, sizeof(uv_source_t));
uv_source = (uv_source_t*)source;
uv_source->loop = loop;
((uv_source_t*) source)->tag = g_source_add_unix_fd(source, uv_backend_fd(loop), G_IO_IN);
return source;
}
#ifndef _G_LIB_UV_H_
#define _G_LIB_UV_H_
#include <glib.h>
#include <uv.h>
GSource* g_uv_source_new(uv_loop_t *loop);
#endif /* _G_LIB_UV_H_ */
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */
#include <stddef.h> /* size_t, ssize_t */
#include <stdint.h>
#include <sys/socket.h> /* sockaddr */
#include <glib.h>
#include <glibuv.h>
static GMainLoop *g_loop;
static uv_loop_t *uv_loop;
//==============================================================================
void handle_close(uv_handle_t *handle)
{
free(handle);
}
void write_cb(uv_write_t *req, int status)
{
free(req);
}
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf)
{
static char buffer[1024];
buf->base = buffer;
buf->len = sizeof(buffer);
}
void echo_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf)
{
uv_write_t *write_req;
uv_buf_t buf_req;
int r;
if (nread < 0)
{
uv_close((uv_handle_t*)stream, handle_close);
return;
}
write_req = malloc(sizeof(uv_write_t));
assert(write_req != NULL);
buf_req = uv_buf_init(buf->base, nread);
r = uv_write(write_req, stream, &buf_req, 1, NULL);
assert(r == 0);
}
void on_new_connection(uv_stream_t *server, int status)
{
static int count = 0;
if (status != 0)
{
fprintf(stderr, "Connection error %s\n", uv_err_name(status));
return;
}
uv_tcp_t *client = malloc(sizeof(uv_tcp_t));
printf("connect: %d\n", ++count);
uv_tcp_init(uv_loop, client);
if (uv_accept(server, (uv_stream_t*) client) == 0)
{
uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read);
}
else
{
uv_close((uv_handle_t*) client, handle_close);
}
}
int main()
{
GSource *source;
struct sockaddr_in bind_addr;
int r;
uv_tcp_t server;
g_loop = g_main_loop_new(NULL, FALSE);
uv_loop = uv_default_loop();
assert(uv_loop != NULL);
r = uv_tcp_init(uv_loop, &server);
assert(r == 0);
r = uv_ip4_addr("0.0.0.0", 7003, &bind_addr);
assert(r == 0);
r = uv_tcp_bind(&server, (struct sockaddr*)&bind_addr, 0);
assert(r == 0);
r = uv_listen((uv_stream_t*) &server, 128, on_new_connection);
assert(r == 0);
g_source_attach(g_uv_source_new(uv_loop), NULL);
g_main_loop_run(g_loop);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment