forked from cory/tildefriends
Needs more work, but several experiments that make things more responsive under load.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3783 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
75
src/ssb.c
75
src/ssb.c
@ -174,6 +174,7 @@ typedef struct _tf_ssb_connection_t {
|
||||
tf_ssb_t* ssb;
|
||||
uv_tcp_t tcp;
|
||||
uv_connect_t connect;
|
||||
uv_async_t async;
|
||||
|
||||
JSValue object;
|
||||
|
||||
@ -1200,14 +1201,6 @@ void tf_ssb_append_message(tf_ssb_t* ssb, JSValue message)
|
||||
|
||||
void tf_ssb_connection_destroy(tf_ssb_connection_t* connection)
|
||||
{
|
||||
free(connection);
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_on_close(uv_handle_t* handle)
|
||||
{
|
||||
tf_ssb_connection_t* connection = handle->data;
|
||||
handle->data = NULL;
|
||||
|
||||
tf_ssb_t* ssb = connection->ssb;
|
||||
for (tf_ssb_connection_t** it = &connection->ssb->connections; *it; it = &(*it)->next)
|
||||
{
|
||||
@ -1216,6 +1209,7 @@ static void _tf_ssb_connection_on_close(uv_handle_t* handle)
|
||||
*it = connection->next;
|
||||
connection->next = NULL;
|
||||
ssb->connections_count--;
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_remove, connection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1223,8 +1217,38 @@ static void _tf_ssb_connection_on_close(uv_handle_t* handle)
|
||||
{
|
||||
_tf_ssb_connection_remove_request(connection, connection->requests->request_number);
|
||||
}
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_remove, connection);
|
||||
JS_FreeValue(ssb->context, connection->object);
|
||||
if (!JS_IsUndefined(connection->object))
|
||||
{
|
||||
JS_FreeValue(ssb->context, connection->object);
|
||||
connection->object = JS_UNDEFINED;
|
||||
}
|
||||
if (connection->async.data && !uv_is_closing((uv_handle_t*)&connection->async))
|
||||
{
|
||||
uv_close((uv_handle_t*)&connection->async, _tf_ssb_connection_on_close);
|
||||
}
|
||||
if (connection->tcp.data && !uv_is_closing((uv_handle_t*)&connection->tcp))
|
||||
{
|
||||
uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close);
|
||||
}
|
||||
if (connection->connect.data && !uv_is_closing((uv_handle_t*)&connection->connect))
|
||||
{
|
||||
uv_close((uv_handle_t*)&connection->connect, _tf_ssb_connection_on_close);
|
||||
}
|
||||
|
||||
if (JS_IsUndefined(connection->object) &&
|
||||
!connection->async.data &&
|
||||
!connection->tcp.data &&
|
||||
!connection->connect.data)
|
||||
{
|
||||
free(connection);
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_on_close(uv_handle_t* handle)
|
||||
{
|
||||
tf_ssb_connection_t* connection = handle->data;
|
||||
handle->data = NULL;
|
||||
tf_ssb_connection_destroy(connection);
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
|
||||
@ -1268,9 +1292,7 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c
|
||||
}
|
||||
break;
|
||||
case k_tf_ssb_state_verified:
|
||||
while (_tf_ssb_connection_box_stream_recv(connection))
|
||||
{
|
||||
}
|
||||
uv_async_send(&connection->async);
|
||||
break;
|
||||
case k_tf_ssb_state_server_wait_hello:
|
||||
{
|
||||
@ -1303,9 +1325,7 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c
|
||||
}
|
||||
break;
|
||||
case k_tf_ssb_state_server_verified:
|
||||
while (_tf_ssb_connection_box_stream_recv(connection))
|
||||
{
|
||||
}
|
||||
uv_async_send(&connection->async);
|
||||
break;
|
||||
case k_tf_ssb_state_closing:
|
||||
break;
|
||||
@ -1777,7 +1797,11 @@ void tf_ssb_run(tf_ssb_t* ssb)
|
||||
static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value)
|
||||
{
|
||||
tf_ssb_connection_t* connection = JS_GetOpaque(value, _connection_class_id);
|
||||
tf_ssb_connection_destroy(connection);
|
||||
if (connection)
|
||||
{
|
||||
connection->object = JS_UNDEFINED;
|
||||
tf_ssb_connection_destroy(connection);
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_send_json_response(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
@ -1818,6 +1842,15 @@ static JSValue _tf_ssb_connection_send_json(JSContext* context, JSValueConst thi
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_process_message_async(uv_async_t* async)
|
||||
{
|
||||
tf_ssb_connection_t* connection = async->data;
|
||||
if (_tf_ssb_connection_box_stream_recv(connection))
|
||||
{
|
||||
uv_async_send(&connection->async);
|
||||
}
|
||||
}
|
||||
|
||||
tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, const struct sockaddr_in* addr, const uint8_t* public_key)
|
||||
{
|
||||
for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next)
|
||||
@ -1847,6 +1880,8 @@ tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, c
|
||||
connection->send_request_number = 1;
|
||||
snprintf(connection->host, sizeof(connection->host), "%s", host);
|
||||
connection->port = ntohs(addr->sin_port);
|
||||
connection->async.data = connection;
|
||||
uv_async_init(ssb->loop, &connection->async, _tf_ssb_connection_process_message_async);
|
||||
|
||||
connection->object = JS_NewObjectClass(ssb->context, _connection_class_id);
|
||||
JS_SetPropertyStr(context, connection->object, "send_json", JS_NewCFunction(context, _tf_ssb_connection_send_json, "send_json", 2));
|
||||
@ -1866,9 +1901,7 @@ tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, c
|
||||
if (result)
|
||||
{
|
||||
printf("uv_tcp_connect(%s): %s\n", host, uv_strerror(result));
|
||||
JS_SetOpaque(connection->object, NULL);
|
||||
JS_FreeValue(ssb->context, connection->object);
|
||||
free(connection);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1938,6 +1971,8 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status)
|
||||
connection->ssb = ssb;
|
||||
connection->tcp.data = connection;
|
||||
connection->send_request_number = 1;
|
||||
connection->async.data = connection;
|
||||
uv_async_init(ssb->loop, &connection->async, _tf_ssb_connection_process_message_async);
|
||||
|
||||
connection->object = JS_NewObjectClass(ssb->context, _connection_class_id);
|
||||
JS_SetPropertyStr(ssb->context, connection->object, "send_json", JS_NewCFunction(ssb->context, _tf_ssb_connection_send_json, "send_json", 2));
|
||||
@ -1946,7 +1981,7 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status)
|
||||
if (uv_tcp_init(ssb->loop, &connection->tcp) != 0)
|
||||
{
|
||||
printf("uv_tcp_init failed\n");
|
||||
free(connection);
|
||||
JS_FreeValue(ssb->context, connection->object);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user