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:
2022-01-22 20:13:14 +00:00
parent 0f03701043
commit b2a552b3e0
9 changed files with 128 additions and 100 deletions

View File

@ -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;
}