summaryrefslogtreecommitdiffstats
path: root/contrib/src/evws
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-12-20 00:56:45 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-12-20 00:56:45 (GMT)
commit0388c7ac478187ff8d264b6e0275a4c4a43796b9 (patch)
tree7e62439ebf72b6369ee7b1daa370e6251c06b7e0 /contrib/src/evws
parent22e22bfd0965e01fea041e053873d352387805f6 (diff)
downloaduscxml-0388c7ac478187ff8d264b6e0275a4c4a43796b9.zip
uscxml-0388c7ac478187ff8d264b6e0275a4c4a43796b9.tar.gz
uscxml-0388c7ac478187ff8d264b6e0275a4c4a43796b9.tar.bz2
Performance and bugfix for WebSockets
Diffstat (limited to 'contrib/src/evws')
-rw-r--r--contrib/src/evws/evws.c112
1 files changed, 60 insertions, 52 deletions
diff --git a/contrib/src/evws/evws.c b/contrib/src/evws/evws.c
index b39bc03..5dbd8e9 100644
--- a/contrib/src/evws/evws.c
+++ b/contrib/src/evws/evws.c
@@ -66,11 +66,11 @@ struct evws *evws_new(struct event_base *base) {
ret_obj->base = base;
ret_obj->listener = NULL;
- ret_obj->connections.tqh_first = NULL;
- ret_obj->connections.tqh_last = &(ret_obj->connections.tqh_first);
-
- ret_obj->callbacks.tqh_first = NULL;
- ret_obj->callbacks.tqh_last = &(ret_obj->callbacks.tqh_first);
+ (&ret_obj->connections)->tqh_first = NULL;
+ (&ret_obj->connections)->tqh_last = &((&ret_obj->connections)->tqh_first);
+
+ (&ret_obj->callbacks)->tqh_first = NULL;
+ (&ret_obj->callbacks)->tqh_last = &((&ret_obj->callbacks)->tqh_first);
return ret_obj;
}
@@ -89,16 +89,22 @@ evutil_socket_t evws_bind_socket(struct evws * ws, unsigned short port) {
sin.sin_addr.s_addr = htonl(0);
sin.sin_port = htons(port);
- if(!(ws->listener = evconnlistener_new_bind(ws->base, cb_accept, ws, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_THREADSAFE, -1, (struct sockaddr*)&sin, sizeof(sin)))) {
+ if(!(ws->listener = evconnlistener_new_bind(ws->base,
+ cb_accept,
+ ws,
+ LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_THREADSAFE,
+ -1,
+ (struct sockaddr*)&sin, sizeof(sin)))
+ ) {
return 0;
}
return evconnlistener_get_fd(ws->listener);
}
int evws_set_cb(struct evws * ws, const char * uri, cb_frame_type message_cb, cb_type connect_cb, void * arg) {
- struct evws_cb *ws_cb;
+ struct evws_cb *ws_cb = NULL;
- for (ws_cb = ws->callbacks.tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) {
+ for (ws_cb = (&ws->callbacks)->tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) {
if (strcmp(ws_cb->uri, uri) == 0)
return (-1);
}
@@ -114,9 +120,9 @@ int evws_set_cb(struct evws * ws, const char * uri, cb_frame_type message_cb, cb
// TAILQ_INSERT_TAIL
ws_cb->next.tqe_next = NULL;
- ws_cb->next.tqe_prev = ws->callbacks.tqh_last;
- ws->callbacks.tqh_last = &ws_cb;
- ws->callbacks.tqh_last = &ws_cb->next.tqe_next;
+ ws_cb->next.tqe_prev = (&ws->callbacks)->tqh_last;
+ *(&ws->callbacks)->tqh_last = ws_cb;
+ (&ws->callbacks)->tqh_last = &(ws_cb->next.tqe_next);
return (0);
}
@@ -131,7 +137,7 @@ cb_frame_type evws_set_gencb(struct evws *ws, cb_frame_type cb, void * arg) {
// Broadcast data to all buffers associated with pattern
void evws_broadcast(struct evws *ws, const char *uri, enum evws_opcode opcode, const char *data, uint64_t length) {
struct evws_connection *ws_connection;
- for (ws_connection = ws->connections.tqh_first; ws_connection; ws_connection = ws_connection->next.tqe_next) {
+ for ((ws_connection) = (&ws->connections)->tqh_first; ws_connection; ws_connection = ws_connection->next.tqe_next) {
if (strcmp(ws_connection->uri, uri) == 0)
evws_send_data(ws_connection, opcode, data, length);
}
@@ -140,15 +146,12 @@ void evws_broadcast(struct evws *ws, const char *uri, enum evws_opcode opcode, c
// Error callback
static void cb_error(struct bufferevent *bev, short what, void *ctx) {
struct evws_connection *conn = ctx;
-
- //TAILQ_REMOVE
- if (conn->next.tqe_next != NULL)
+ if (conn->next.tqe_next != NULL) {
conn->next.tqe_next->next.tqe_prev = conn->next.tqe_prev;
- else {
- conn->ws->connections.tqh_last = conn->next.tqe_prev;
+ } else {
+ (&(conn->ws->connections))->tqh_last = conn->next.tqe_prev;
}
- conn->next.tqe_prev = &conn->next.tqe_next;
-
+ *(conn)->next.tqe_prev = conn->next.tqe_next;
evws_connection_free(conn);
}
@@ -224,11 +227,12 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) {
origin = strdup(svalue);
}
header = evws_header_new(skey, svalue);
- //TAILQ_INSERT_TAIL
+
+ // TAILQ_INSERT_TAIL
header->next.tqe_next = NULL;
- header->next.tqe_prev = ws_conn->headers.tqh_last;
- ws_conn->headers.tqh_last = &header;
- ws_conn->headers.tqh_last = &header->next.tqe_next;
+ header->next.tqe_prev = (&ws_conn->headers)->tqh_last;
+ *(&ws_conn->headers)->tqh_last = header;
+ (&ws_conn->headers)->tqh_last = &(header->next.tqe_next);
free(line);
}
@@ -236,6 +240,9 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) {
break;
};
+ if (key == NULL)
+ return;
+
// -- SHA1
SHA1Reset(&sha1);
@@ -280,24 +287,24 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) {
"\r\n",
chksumBase64
);
- bufferevent_setcb(ws_conn->bufev, cb_read_frame, NULL, cb_error, ws_conn);
-
- //TAILQ_INSERT_TAIL(&(ws_conn->ws->connections), ws_conn, next);
+ bufferevent_setcb(ws_conn->bufev, cb_read_frame, ((void*)0), cb_error, ws_conn);
+
ws_conn->next.tqe_next = NULL;
- ws_conn->next.tqe_prev = ws_conn->ws->connections.tqh_last;
- ws_conn->ws->connections.tqh_last = &ws_conn;
- ws_conn->ws->connections.tqh_last = &ws_conn->next.tqe_next;
+ ws_conn->next.tqe_prev = (&(ws_conn->ws->connections))->tqh_last;
+ *(&(ws_conn->ws->connections))->tqh_last = ws_conn;
+ (&(ws_conn->ws->connections))->tqh_last = &(ws_conn->next.tqe_next);
{
struct evws_cb *ws_cb;
- for (ws_cb = ws_conn->ws->callbacks.tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) {
+ for (ws_cb = ((&ws_conn->ws->callbacks))->tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) {
if (strcmp(ws_cb->uri, ws_conn->uri) == 0) {
- if(ws_cb->conn_cb != NULL)
- ws_cb->conn_cb(ws_conn, NULL, 0, ws_cb->cb_arg);
+ if(ws_cb->conn_cb != ((void*)0))
+ ws_cb->conn_cb(ws_conn, ((void*)0), 0, ws_cb->cb_arg);
return;
}
}
}
+
}
int evws_parse_header_line(char *line, char **skey, char **svalue)
@@ -317,7 +324,7 @@ void cb_read_frame(struct bufferevent *bev, void *arg)
{
struct evws_connection *conn = arg;
struct evws *ws = conn->ws;
- char readbuf[1024];
+ char readbuf[2048]; // make sure a MTU fits
int size = 0;
struct evbuffer *buffer = bufferevent_get_input(bev);
while ((size = evbuffer_remove(buffer, readbuf, sizeof(readbuf))) > 0) {
@@ -414,11 +421,12 @@ NEXT_FRAME:
if (conn->frame->payload_read == conn->frame->size) {
// done reading this frame - invoke callbacks
struct evws_cb *ws_cb;
- for (ws_cb = ws->callbacks.tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) {
+ // TAILQ_FOREACH
+ for (ws_cb = ((&ws->callbacks))->tqh_first; ws_cb; ws_cb = (ws_cb->next.tqe_next)) {
if (strcmp(ws_cb->uri, conn->uri) == 0) {
- if(ws_cb->msg_cb != NULL)
+ if(ws_cb->msg_cb != ((void*)0))
ws_cb->msg_cb(conn, conn->frame, ws_cb->cb_arg);
- continue;
+ return;
}
}
ws->gencb(conn, conn->frame, ws->gencb_arg);
@@ -484,27 +492,28 @@ struct evws_connection* evws_connection_new(struct evws *ws, evutil_socket_t fd)
struct evws_connection* conn = calloc(1, sizeof(struct evws_connection));
conn->ws = ws;
conn->fd = fd;
- conn->uri = NULL;
-
+ conn->uri = ((void*)0);
+
conn->bufev = bufferevent_socket_new(ws->base, fd, BEV_OPT_CLOSE_ON_FREE);
conn->state = 0;
- conn->frame = NULL;
+ conn->frame = ((void*)0);
+
+ (&conn->headers)->tqh_first = NULL;
+ (&conn->headers)->tqh_last = &(((&conn->headers))->tqh_first);
- conn->headers.tqh_first = NULL;
- conn->headers.tqh_last = &(conn->headers.tqh_first);
-
return conn;
}
void evws_connection_free(struct evws_connection *conn) {
struct evws_header *header;
bufferevent_free(conn->bufev);
- if(conn->uri != NULL)
+ if(conn->uri != ((void*)0))
free(conn->uri);
-
- for (header = conn->headers.tqh_first; header; header = header->next.tqe_next) {
+
+ for (header = (&conn->headers)->tqh_first; header; header = header->next.tqe_next) {
evws_header_free(header);
}
+
free(conn);
}
@@ -530,19 +539,18 @@ struct evws_header *evws_header_new(char *key, char *value)
void evws_header_free(struct evws_header *header) {
if(header->key != NULL)
free(header->key);
- // @Note: segfault when freeing value, some strange value
if(header->value != NULL)
free(header->value);
free(header);
}
char *evws_find_header(const struct wsheadersq *q, const char *key) {
- struct evws_header *header;
- char * ret = NULL;
- for (header = q->tqh_first; header; header = header->next.tqe_next) {
-
- if(strcmp(header->key, key) == 0) {
- ret = header->value;
+ struct evws_header *hdr;
+ char * ret = ((void*)0);
+
+ for (hdr = q->tqh_first; hdr; hdr = hdr->next.tqe_next) {
+ if(strcmp(hdr->key, key) == 0) {
+ ret = hdr->value;
break;
}
}