Created
May 19, 2015 15:02
-
-
Save saghul/f58fcda21c84bc81dbab to your computer and use it in GitHub Desktop.
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
#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; | |
} |
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
#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_ */ |
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
#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