forked from cory/tildefriends
		
	Another linked list bites the dust.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3928 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		@@ -174,9 +174,9 @@ void* tf_resize_vec(void* ptr, size_t size)
 | 
			
		||||
		memcpy(&alloc_size, alloc_ptr, sizeof(size_t));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (alloc_size >= 16 * size + sizeof(size_t))
 | 
			
		||||
	if ((alloc_size >= 16 * size + sizeof(size_t)) || !size)
 | 
			
		||||
	{
 | 
			
		||||
		/* If we've dropped significantly in size, resize down. */
 | 
			
		||||
		/* If we've dropped significantly in size or are freeing, resize down. */
 | 
			
		||||
		return tf_realloc(ptr, size);
 | 
			
		||||
	}
 | 
			
		||||
	else if (alloc_size >= size + sizeof(size_t))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										104
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								src/ssb.c
									
									
									
									
									
								
							@@ -64,14 +64,15 @@ typedef struct _tf_ssb_broadcast_t tf_ssb_broadcast_t;
 | 
			
		||||
typedef struct _tf_ssb_connection_t tf_ssb_connection_t;
 | 
			
		||||
typedef struct _tf_ssb_request_t tf_ssb_request_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_request_t {
 | 
			
		||||
	tf_ssb_request_t* next;
 | 
			
		||||
typedef struct _tf_ssb_request_t
 | 
			
		||||
{
 | 
			
		||||
	int32_t request_number;
 | 
			
		||||
	tf_ssb_rpc_callback_t* callback;
 | 
			
		||||
	void* user_data;
 | 
			
		||||
} tf_ssb_request_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_broadcast_t {
 | 
			
		||||
typedef struct _tf_ssb_broadcast_t
 | 
			
		||||
{
 | 
			
		||||
	tf_ssb_broadcast_t* next;
 | 
			
		||||
	time_t ctime;
 | 
			
		||||
	time_t mtime;
 | 
			
		||||
@@ -81,7 +82,8 @@ typedef struct _tf_ssb_broadcast_t {
 | 
			
		||||
} tf_ssb_broadcast_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_rpc_callback_node_t tf_ssb_rpc_callback_node_t;
 | 
			
		||||
typedef struct _tf_ssb_rpc_callback_node_t {
 | 
			
		||||
typedef struct _tf_ssb_rpc_callback_node_t
 | 
			
		||||
{
 | 
			
		||||
	const char** name;
 | 
			
		||||
	tf_ssb_rpc_callback_t* callback;
 | 
			
		||||
	tf_ssb_callback_cleanup_t* cleanup;
 | 
			
		||||
@@ -90,7 +92,8 @@ typedef struct _tf_ssb_rpc_callback_node_t {
 | 
			
		||||
} tf_ssb_rpc_callback_node_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_connections_changed_callback_node_t tf_ssb_connections_changed_callback_node_t;
 | 
			
		||||
typedef struct _tf_ssb_connections_changed_callback_node_t {
 | 
			
		||||
typedef struct _tf_ssb_connections_changed_callback_node_t
 | 
			
		||||
{
 | 
			
		||||
	tf_ssb_connections_changed_callback_t* callback;
 | 
			
		||||
	tf_ssb_callback_cleanup_t* cleanup;
 | 
			
		||||
	void* user_data;
 | 
			
		||||
@@ -98,7 +101,8 @@ typedef struct _tf_ssb_connections_changed_callback_node_t {
 | 
			
		||||
} tf_ssb_connections_changed_callback_node_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_message_added_callback_node_t tf_ssb_message_added_callback_node_t;
 | 
			
		||||
typedef struct _tf_ssb_message_added_callback_node_t {
 | 
			
		||||
typedef struct _tf_ssb_message_added_callback_node_t
 | 
			
		||||
{
 | 
			
		||||
	tf_ssb_message_added_callback_t* callback;
 | 
			
		||||
	tf_ssb_callback_cleanup_t* cleanup;
 | 
			
		||||
	void* user_data;
 | 
			
		||||
@@ -106,7 +110,8 @@ typedef struct _tf_ssb_message_added_callback_node_t {
 | 
			
		||||
} tf_ssb_message_added_callback_node_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_blob_want_added_callback_node_t tf_ssb_blob_want_added_callback_node_t;
 | 
			
		||||
typedef struct _tf_ssb_blob_want_added_callback_node_t {
 | 
			
		||||
typedef struct _tf_ssb_blob_want_added_callback_node_t
 | 
			
		||||
{
 | 
			
		||||
	tf_ssb_blob_want_added_callback_t* callback;
 | 
			
		||||
	tf_ssb_callback_cleanup_t* cleanup;
 | 
			
		||||
	void* user_data;
 | 
			
		||||
@@ -114,14 +119,16 @@ typedef struct _tf_ssb_blob_want_added_callback_node_t {
 | 
			
		||||
} tf_ssb_blob_want_added_callback_node_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_broadcasts_changed_callback_node_t tf_ssb_broadcasts_changed_callback_node_t;
 | 
			
		||||
typedef struct _tf_ssb_broadcasts_changed_callback_node_t {
 | 
			
		||||
typedef struct _tf_ssb_broadcasts_changed_callback_node_t
 | 
			
		||||
{
 | 
			
		||||
	tf_ssb_broadcasts_changed_callback_t* callback;
 | 
			
		||||
	tf_ssb_callback_cleanup_t* cleanup;
 | 
			
		||||
	void* user_data;
 | 
			
		||||
	tf_ssb_broadcasts_changed_callback_node_t* next;
 | 
			
		||||
} tf_ssb_broadcasts_changed_callback_node_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_t {
 | 
			
		||||
typedef struct _tf_ssb_t
 | 
			
		||||
{
 | 
			
		||||
	bool own_context;
 | 
			
		||||
	JSRuntime* runtime;
 | 
			
		||||
	JSContext* context;
 | 
			
		||||
@@ -174,7 +181,8 @@ typedef struct _tf_ssb_t {
 | 
			
		||||
	int broadcasts_changed_count;
 | 
			
		||||
} tf_ssb_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _tf_ssb_connection_t {
 | 
			
		||||
typedef struct _tf_ssb_connection_t
 | 
			
		||||
{
 | 
			
		||||
	tf_ssb_t* ssb;
 | 
			
		||||
	uv_tcp_t tcp;
 | 
			
		||||
	uv_connect_t connect;
 | 
			
		||||
@@ -215,6 +223,7 @@ typedef struct _tf_ssb_connection_t {
 | 
			
		||||
 | 
			
		||||
	tf_ssb_connection_t* next;
 | 
			
		||||
	tf_ssb_request_t* requests;
 | 
			
		||||
	int requests_count;
 | 
			
		||||
	const char* destroy_reason;
 | 
			
		||||
} tf_ssb_connection_t;
 | 
			
		||||
 | 
			
		||||
@@ -402,26 +411,33 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection,
 | 
			
		||||
	tf_free(message_enc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _request_compare(const void* a, const void* b)
 | 
			
		||||
{
 | 
			
		||||
	int32_t ai = *(const int32_t*)a;
 | 
			
		||||
	const tf_ssb_request_t* br = (const tf_ssb_request_t*)b;
 | 
			
		||||
	return ai < br->request_number ? -1 : br->request_number < ai ? 1 : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool _tf_ssb_connection_get_request_callback(tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t** out_callback, void** out_user_data)
 | 
			
		||||
{
 | 
			
		||||
	bool found = false;
 | 
			
		||||
	for (tf_ssb_request_t* it = connection->requests; it; it = it->next)
 | 
			
		||||
	if (!connection->requests)
 | 
			
		||||
	{
 | 
			
		||||
		if (it->request_number == request_number)
 | 
			
		||||
		{
 | 
			
		||||
			if (out_callback)
 | 
			
		||||
			{
 | 
			
		||||
				*out_callback = it->callback;
 | 
			
		||||
			}
 | 
			
		||||
			if (out_user_data)
 | 
			
		||||
			{
 | 
			
		||||
				*out_user_data = it->user_data;
 | 
			
		||||
			}
 | 
			
		||||
			found = true;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	return found;
 | 
			
		||||
	tf_ssb_request_t* request = bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare);
 | 
			
		||||
	if (request)
 | 
			
		||||
	{
 | 
			
		||||
		if (out_callback)
 | 
			
		||||
		{
 | 
			
		||||
			*out_callback = request->callback;
 | 
			
		||||
		}
 | 
			
		||||
		if (out_user_data)
 | 
			
		||||
		{
 | 
			
		||||
			*out_user_data = request->user_data;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t* callback, void* user_data)
 | 
			
		||||
@@ -429,36 +445,41 @@ void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t requ
 | 
			
		||||
	if (_tf_ssb_connection_get_request_callback(connection, request_number, NULL, NULL))
 | 
			
		||||
	{
 | 
			
		||||
		/* TODO: This leaks the callback. */
 | 
			
		||||
		printf("Adding a request %d that is already registered.\n", request_number);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	tf_ssb_request_t* request = tf_malloc(sizeof(tf_ssb_request_t));
 | 
			
		||||
	*request = (tf_ssb_request_t)
 | 
			
		||||
	tf_ssb_request_t request =
 | 
			
		||||
	{
 | 
			
		||||
		.next = connection->requests,
 | 
			
		||||
		.request_number = request_number,
 | 
			
		||||
		.callback = callback,
 | 
			
		||||
		.user_data = user_data,
 | 
			
		||||
	};
 | 
			
		||||
	connection->requests = request;
 | 
			
		||||
	int index = tf_util_insert_index(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare);
 | 
			
		||||
	connection->requests = tf_resize_vec(connection->requests, sizeof(tf_ssb_request_t) * (connection->requests_count + 1));
 | 
			
		||||
	if (connection->requests_count - index)
 | 
			
		||||
	{
 | 
			
		||||
		memmove(connection->requests + index + 1, connection->requests + index, sizeof(tf_ssb_request_t) * (connection->requests_count - index));
 | 
			
		||||
	}
 | 
			
		||||
	connection->requests[index] = request;
 | 
			
		||||
	connection->requests_count++;
 | 
			
		||||
 | 
			
		||||
	connection->ssb->request_count++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t request_number)
 | 
			
		||||
{
 | 
			
		||||
	for (tf_ssb_request_t** it = &connection->requests; *it; it = &(*it)->next)
 | 
			
		||||
	tf_ssb_request_t* request = bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare);
 | 
			
		||||
	if (request)
 | 
			
		||||
	{
 | 
			
		||||
		if ((*it)->request_number == request_number)
 | 
			
		||||
		if (request->user_data)
 | 
			
		||||
		{
 | 
			
		||||
			tf_ssb_request_t* found = *it;
 | 
			
		||||
			if (found->user_data)
 | 
			
		||||
			{
 | 
			
		||||
				JS_FreeValue(tf_ssb_connection_get_context(connection), JS_MKPTR(JS_TAG_OBJECT, found->user_data));
 | 
			
		||||
			}
 | 
			
		||||
			*it = found->next;
 | 
			
		||||
			tf_free(found);
 | 
			
		||||
			connection->ssb->request_count--;
 | 
			
		||||
			break;
 | 
			
		||||
			JS_FreeValue(tf_ssb_connection_get_context(connection), JS_MKPTR(JS_TAG_OBJECT, request->user_data));
 | 
			
		||||
		}
 | 
			
		||||
		int index = request - connection->requests;
 | 
			
		||||
		memmove(request, request + 1, sizeof(tf_ssb_request_t) * (connection->requests_count - index - 1));
 | 
			
		||||
		connection->requests_count--;
 | 
			
		||||
		connection->requests = tf_resize_vec(connection->requests, sizeof(tf_ssb_request_t) * connection->requests_count);
 | 
			
		||||
		connection->ssb->request_count--;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1342,6 +1363,7 @@ void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* rea
 | 
			
		||||
	}
 | 
			
		||||
	while (connection->requests)
 | 
			
		||||
	{
 | 
			
		||||
		printf("%d %d\n", connection->requests_count, connection->requests->request_number);
 | 
			
		||||
		_tf_ssb_connection_remove_request(connection, connection->requests->request_number);
 | 
			
		||||
	}
 | 
			
		||||
	if (!JS_IsUndefined(connection->object))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								src/task.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/task.c
									
									
									
									
									
								
							@@ -602,30 +602,6 @@ static JSValue _tf_task_version(JSContext* context, JSValueConst this_val, int a
 | 
			
		||||
	return JS_NewString(task->_context, k_version);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _insert_index(const void* key, const void* base, size_t count, size_t size, int (*compare)(const void*, const void*))
 | 
			
		||||
{
 | 
			
		||||
	int lower = 0;
 | 
			
		||||
	int upper = count;
 | 
			
		||||
	while (lower < upper && lower < (int)count)
 | 
			
		||||
	{
 | 
			
		||||
		int guess = (lower + upper) / 2;
 | 
			
		||||
		int result = compare(key, ((char*)base) + size * guess);
 | 
			
		||||
		if (result < 0)
 | 
			
		||||
		{
 | 
			
		||||
			upper = guess;
 | 
			
		||||
		}
 | 
			
		||||
		else if (result > 0)
 | 
			
		||||
		{
 | 
			
		||||
			lower = guess + 1;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			return guess;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	return lower;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exportid_t tf_task_export_function(tf_task_t* task, tf_taskstub_t* to, JSValue function)
 | 
			
		||||
{
 | 
			
		||||
	export_record_t* export = NULL;
 | 
			
		||||
@@ -654,7 +630,7 @@ exportid_t tf_task_export_function(tf_task_t* task, tf_taskstub_t* to, JSValue f
 | 
			
		||||
			._function = JS_DupValue(task->_context, function),
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		int index = _insert_index(&id, task->_exports, task->_export_count, sizeof(export_record_t*), _export_compare);
 | 
			
		||||
		int index = tf_util_insert_index(&id, task->_exports, task->_export_count, sizeof(export_record_t*), _export_compare);
 | 
			
		||||
		task->_exports = tf_resize_vec(task->_exports, sizeof(export_record_t*) * (task->_export_count + 1));
 | 
			
		||||
		if (task->_export_count - index)
 | 
			
		||||
		{
 | 
			
		||||
@@ -1021,7 +997,7 @@ JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise)
 | 
			
		||||
		.values = { JS_NULL, JS_NULL },
 | 
			
		||||
	};
 | 
			
		||||
	JSValue result = JS_NewPromiseCapability(task->_context, promise.values);
 | 
			
		||||
	int index = _insert_index((void*)(intptr_t)promiseId, task->_promises, task->_promise_count, sizeof(promise_t), _promise_compare);
 | 
			
		||||
	int index = tf_util_insert_index((void*)(intptr_t)promiseId, task->_promises, task->_promise_count, sizeof(promise_t), _promise_compare);
 | 
			
		||||
	task->_promises = tf_resize_vec(task->_promises, sizeof(promise_t) * (task->_promise_count + 1));
 | 
			
		||||
	if (task->_promise_count - index)
 | 
			
		||||
	{
 | 
			
		||||
@@ -1540,7 +1516,7 @@ JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_
 | 
			
		||||
		._useCount = 1,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	int index = _insert_index(import, task->_imports, task->_import_count, sizeof(import_record_t*), _import_compare);
 | 
			
		||||
	int index = tf_util_insert_index(import, task->_imports, task->_import_count, sizeof(import_record_t*), _import_compare);
 | 
			
		||||
	task->_imports = tf_resize_vec(task->_imports, sizeof(import_record_t*) * (task->_import_count + 1));
 | 
			
		||||
	if (task->_import_count - index)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -214,3 +214,28 @@ int tf_util_get_length(JSContext* context, JSValue value)
 | 
			
		||||
	JS_FreeValue(context, length);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int tf_util_insert_index(const void* key, const void* base, size_t count, size_t size, int (*compare)(const void*, const void*))
 | 
			
		||||
{
 | 
			
		||||
	int lower = 0;
 | 
			
		||||
	int upper = count;
 | 
			
		||||
	while (lower < upper && lower < (int)count)
 | 
			
		||||
	{
 | 
			
		||||
		int guess = (lower + upper) / 2;
 | 
			
		||||
		int result = compare(key, ((char*)base) + size * guess);
 | 
			
		||||
		if (result < 0)
 | 
			
		||||
		{
 | 
			
		||||
			upper = guess;
 | 
			
		||||
		}
 | 
			
		||||
		else if (result > 0)
 | 
			
		||||
		{
 | 
			
		||||
			lower = guess + 1;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			return guess;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	return lower;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,3 +10,4 @@ uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValue
 | 
			
		||||
JSValue tf_util_try_get_typed_array_buffer(JSContext* context, JSValueConst obj, size_t* pbyte_offset, size_t* pbyte_length, size_t* pbytes_per_element);
 | 
			
		||||
bool tf_util_report_error(JSContext* context, JSValue value);
 | 
			
		||||
int tf_util_get_length(JSContext* context, JSValue value);
 | 
			
		||||
int tf_util_insert_index(const void* key, const void* base, size_t count, size_t size, int (*compare)(const void*, const void*));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user