Expose some information about active sockets to try to track down leaks.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3898 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		@@ -172,6 +172,7 @@ async function getProcessBlob(blobId, key, options) {
 | 
			
		||||
					},
 | 
			
		||||
					'user': getUser(process, process),
 | 
			
		||||
					'apps': user => getApps(user, process),
 | 
			
		||||
					'getSockets': getSockets,
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
			if (options.api) {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,12 +13,16 @@
 | 
			
		||||
#include "quickjs-libc.h"
 | 
			
		||||
 | 
			
		||||
typedef int promiseid_t;
 | 
			
		||||
typedef struct _socket_t socket_t;
 | 
			
		||||
 | 
			
		||||
static JSClassID _classId;
 | 
			
		||||
static int _count;
 | 
			
		||||
static int _open_count;
 | 
			
		||||
static tf_tls_context_t* _defaultTlsContext;
 | 
			
		||||
 | 
			
		||||
static socket_t** _sockets;
 | 
			
		||||
static int _sockets_count;
 | 
			
		||||
 | 
			
		||||
typedef enum _socket_direction_t {
 | 
			
		||||
	kUndetermined,
 | 
			
		||||
	kAccept,
 | 
			
		||||
@@ -41,6 +45,7 @@ typedef struct _socket_t {
 | 
			
		||||
	JSValue _onConnect;
 | 
			
		||||
	JSValue _onRead;
 | 
			
		||||
	JSValue _onError;
 | 
			
		||||
	uint64_t created_ms;
 | 
			
		||||
} socket_t;
 | 
			
		||||
 | 
			
		||||
static JSValue _socket_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
 | 
			
		||||
@@ -62,6 +67,7 @@ static JSValue _socket_getPeerName(JSContext* context, JSValueConst this_val, in
 | 
			
		||||
static JSValue _socket_getPeerCertificate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
 | 
			
		||||
static JSValue _socket_getNoDelay(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
 | 
			
		||||
static JSValue _socket_setNoDelay(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
 | 
			
		||||
static JSValue _sockets_get(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
 | 
			
		||||
 | 
			
		||||
static void _socket_onClose(uv_handle_t* handle);
 | 
			
		||||
static void _socket_onShutdown(uv_shutdown_t* request, int status);
 | 
			
		||||
@@ -131,6 +137,10 @@ JSValue tf_socket_register(JSContext* context)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "Failed to register Socket.\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	JSValue global = JS_GetGlobalObject(context);
 | 
			
		||||
	JS_SetPropertyStr(context, global, "getSockets", JS_NewCFunction(context, _sockets_get, "getSockets", 0));
 | 
			
		||||
	JS_FreeValue(context, global);
 | 
			
		||||
	return JS_NewCFunction2(context, _socket_create, "Socket", 0, JS_CFUNC_constructor, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -154,6 +164,8 @@ socket_t* _socket_create_internal(JSContext* context)
 | 
			
		||||
{
 | 
			
		||||
	socket_t* socket = tf_malloc(sizeof(socket_t));
 | 
			
		||||
	memset(socket, 0, sizeof(*socket));
 | 
			
		||||
	_sockets = realloc(_sockets, sizeof(socket_t*) * (_sockets_count + 1));
 | 
			
		||||
	_sockets[_sockets_count++] = socket;
 | 
			
		||||
 | 
			
		||||
	socket->_closePromise = -1;
 | 
			
		||||
	socket->_startTlsPromise = -1;
 | 
			
		||||
@@ -164,6 +176,8 @@ socket_t* _socket_create_internal(JSContext* context)
 | 
			
		||||
	socket->_object = object;
 | 
			
		||||
	JS_SetOpaque(object, socket);
 | 
			
		||||
 | 
			
		||||
	socket->created_ms = uv_now(tf_task_get_loop(socket->_task));
 | 
			
		||||
 | 
			
		||||
	socket->_onRead = JS_UNDEFINED;
 | 
			
		||||
	socket->_onError = JS_UNDEFINED;
 | 
			
		||||
	socket->_onConnect = JS_UNDEFINED;
 | 
			
		||||
@@ -230,6 +244,15 @@ void _socket_close_internal(socket_t* socket)
 | 
			
		||||
		JS_IsUndefined(socket->_object))
 | 
			
		||||
	{
 | 
			
		||||
		--_count;
 | 
			
		||||
		for (int i = 0; i < _sockets_count; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (_sockets[i] == socket)
 | 
			
		||||
			{
 | 
			
		||||
				_sockets[i] = _sockets[_sockets_count - 1];
 | 
			
		||||
				--_sockets_count;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		tf_free(socket);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -439,7 +462,7 @@ JSValue _socket_connect(JSContext* context, JSValueConst this_val, int argc, JSV
 | 
			
		||||
	const char* node = JS_ToCString(context, argv[0]);
 | 
			
		||||
	const char* port = JS_ToCString(context, argv[1]);
 | 
			
		||||
 | 
			
		||||
	strncpy(socket->_peerName, node, sizeof(socket->_peerName) - 1);
 | 
			
		||||
	snprintf(socket->_peerName, sizeof(socket->_peerName), "%s", node);
 | 
			
		||||
 | 
			
		||||
	socket_resolve_data_t* data = tf_malloc(sizeof(socket_resolve_data_t));
 | 
			
		||||
	memset(data, 0, sizeof(*data));
 | 
			
		||||
@@ -561,6 +584,12 @@ JSValue _socket_accept(JSContext* context, JSValueConst this_val, int argc, JSVa
 | 
			
		||||
	int status = uv_accept((uv_stream_t*)&socket->_socket, (uv_stream_t*)&client->_socket);
 | 
			
		||||
	if (status == 0)
 | 
			
		||||
	{
 | 
			
		||||
		struct sockaddr_in name = { 0 };
 | 
			
		||||
		int namelen = (int)sizeof(name);
 | 
			
		||||
		if (uv_tcp_getpeername(&client->_socket, (struct sockaddr*)&name, &namelen) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			uv_ip_name((const struct sockaddr*)&name, client->_peerName, sizeof(client->_peerName));
 | 
			
		||||
		}
 | 
			
		||||
		client->_connected = true;
 | 
			
		||||
		tf_task_resolve_promise(socket->_task, promise, client->_object);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1035,3 +1064,20 @@ JSValue _socket_setNoDelay(JSContext* context, JSValueConst this_val, int argc,
 | 
			
		||||
	uv_tcp_nodelay(&socket->_socket, result > 0 ? 1 : 0);
 | 
			
		||||
	return JS_UNDEFINED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue _sockets_get(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
 | 
			
		||||
{
 | 
			
		||||
	JSValue array = JS_NewArray(context);
 | 
			
		||||
	for (int i = 0; i < _sockets_count; i++)
 | 
			
		||||
	{
 | 
			
		||||
		socket_t* s = _sockets[i];
 | 
			
		||||
		JSValue entry = JS_NewObject(context);
 | 
			
		||||
		JS_SetPropertyStr(context, entry, "peer", JS_NewString(context, s->_peerName));
 | 
			
		||||
		JS_SetPropertyStr(context, entry, "listening", JS_NewBool(context, s->_listening));
 | 
			
		||||
		JS_SetPropertyStr(context, entry, "connected", JS_NewBool(context, s->_connected));
 | 
			
		||||
		JS_SetPropertyStr(context, entry, "tls", JS_NewBool(context, s->_tls != NULL));
 | 
			
		||||
		JS_SetPropertyStr(context, entry, "age_seconds", JS_NewFloat64(context, (uv_now(tf_task_get_loop(s->_task)) - s->created_ms) / 1000.f));
 | 
			
		||||
		JS_SetPropertyUint32(context, array, i, entry);
 | 
			
		||||
	}
 | 
			
		||||
	return array;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user