forked from cory/tildefriends
		
	Getting closer on lifetime issues.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4798 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										56
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								src/ssb.c
									
									
									
									
									
								
							| @@ -204,7 +204,6 @@ typedef struct _tf_ssb_t | ||||
| 	uv_timer_t broadcast_cleanup_timer; | ||||
| 	uv_timer_t broadcast_timer; | ||||
| 	uv_timer_t trace_timer; | ||||
| 	uv_timer_t settings_timer; | ||||
| 	uv_tcp_t server; | ||||
|  | ||||
| 	uint8_t pub[crypto_sign_PUBLICKEYBYTES]; | ||||
| @@ -357,7 +356,7 @@ static void _tf_ssb_nonce_inc(uint8_t* nonce); | ||||
| static void _tf_ssb_write(tf_ssb_connection_t* connection, void* data, size_t size); | ||||
| static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value); | ||||
| static void _tf_ssb_update_settings(tf_ssb_t* ssb); | ||||
| static void _tf_ssb_start_update_settings(tf_ssb_t* ssb, int delay_ms); | ||||
| static void _tf_ssb_start_update_settings(tf_ssb_t* ssb); | ||||
|  | ||||
| static void _tf_ssb_add_debug_close(tf_ssb_t* ssb, tf_ssb_connection_t* connection, const char* reason) | ||||
| { | ||||
| @@ -2219,7 +2218,7 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, const char* db_path | ||||
|  | ||||
| 	_tf_ssb_update_settings(ssb); | ||||
| 	tf_ssb_rpc_register(ssb); | ||||
| 	_tf_ssb_start_update_settings(ssb, 5000); | ||||
| 	_tf_ssb_start_update_settings(ssb); | ||||
| 	return ssb; | ||||
| } | ||||
|  | ||||
| @@ -2368,6 +2367,7 @@ static void _tf_ssb_on_timer_close(uv_handle_t* handle) | ||||
|  | ||||
| void tf_ssb_destroy(tf_ssb_t* ssb) | ||||
| { | ||||
| 	tf_printf("tf_ssb_destroy\n"); | ||||
| 	tf_ssb_connections_destroy(ssb->connections_tracker); | ||||
| 	ssb->connections_tracker = NULL; | ||||
|  | ||||
| @@ -2401,11 +2401,6 @@ void tf_ssb_destroy(tf_ssb_t* ssb) | ||||
| 		uv_close((uv_handle_t*)&ssb->server, _tf_ssb_on_handle_close); | ||||
| 	} | ||||
|  | ||||
| 	if (ssb->settings_timer.data && !uv_is_closing((uv_handle_t*)&ssb->settings_timer)) | ||||
| 	{ | ||||
| 		uv_close((uv_handle_t*)&ssb->settings_timer, _tf_ssb_on_handle_close); | ||||
| 	} | ||||
|  | ||||
| 	for (int i = 0; i < ssb->timers_count; i++) | ||||
| 	{ | ||||
| 		uv_close((uv_handle_t*)&ssb->timers[i]->timer, _tf_ssb_on_timer_close); | ||||
| @@ -2414,18 +2409,21 @@ void tf_ssb_destroy(tf_ssb_t* ssb) | ||||
| 	tf_free(ssb->timers); | ||||
| 	ssb->timers = NULL; | ||||
|  | ||||
| 	tf_printf("Waiting for closes.\n"); | ||||
|  | ||||
| 	while (ssb->broadcast_listener.data || | ||||
| 		ssb->broadcast_sender.data || | ||||
| 		ssb->broadcast_timer.data || | ||||
| 		ssb->broadcast_cleanup_timer.data || | ||||
| 		ssb->trace_timer.data || | ||||
| 		ssb->settings_timer.data || | ||||
| 		ssb->server.data || | ||||
| 		ssb->ref_count) | ||||
| 	{ | ||||
| 		uv_run(ssb->loop, UV_RUN_ONCE); | ||||
| 	} | ||||
|  | ||||
| 	tf_printf("Waiting for rpc.\n"); | ||||
|  | ||||
| 	while (ssb->rpc) | ||||
| 	{ | ||||
| 		tf_ssb_rpc_callback_node_t* node = ssb->rpc; | ||||
| @@ -2482,6 +2480,25 @@ void tf_ssb_destroy(tf_ssb_t* ssb) | ||||
| 		} | ||||
| 		tf_free(node); | ||||
| 	} | ||||
|  | ||||
| 	tf_printf("rpc=%p conn_changed=%p mess_add=%p blob_want_add=%p broadcast_change=%p\n", | ||||
| 		ssb->rpc, | ||||
| 		ssb->connections_changed, | ||||
| 		ssb->message_added, | ||||
| 		ssb->blob_want_added, | ||||
| 		ssb->broadcasts_changed); | ||||
|  | ||||
| 	tf_printf("Closing connections.\n"); | ||||
| 	tf_ssb_connection_t* connection = ssb->connections; | ||||
| 	while (connection) | ||||
| 	{ | ||||
| 		tf_ssb_connection_t* next = connection->next; | ||||
| 		tf_printf("close %p\n", connection); | ||||
| 		tf_ssb_connection_close(connection); | ||||
| 		connection = next; | ||||
| 	} | ||||
| 	tf_printf("Closed.\n"); | ||||
|  | ||||
| 	if (ssb->loop == &ssb->own_loop) | ||||
| 	{ | ||||
| 		int r = uv_loop_close(ssb->loop); | ||||
| @@ -2490,6 +2507,7 @@ void tf_ssb_destroy(tf_ssb_t* ssb) | ||||
| 			tf_printf("uv_loop_close: %s\n", uv_strerror(r)); | ||||
| 		} | ||||
| 	} | ||||
| 	tf_printf("loop closed\n"); | ||||
| 	if (ssb->own_context) | ||||
| 	{ | ||||
| 		JS_FreeContext(ssb->context); | ||||
| @@ -2515,8 +2533,10 @@ void tf_ssb_destroy(tf_ssb_t* ssb) | ||||
| 		sqlite3_close(ssb->db_readers[i]); | ||||
| 	} | ||||
| 	tf_free(ssb->db_readers); | ||||
| 	tf_printf("destroying mutexes\n"); | ||||
| 	uv_mutex_destroy(&ssb->db_readers_lock); | ||||
| 	uv_mutex_destroy(&ssb->db_writer_lock); | ||||
| 	tf_printf("mutexes destroyed\n"); | ||||
| 	tf_free((void*)ssb->db_path); | ||||
| 	tf_free(ssb->room_name); | ||||
| 	ssb->room_name = NULL; | ||||
| @@ -3893,12 +3913,14 @@ static void _tf_ssb_update_settings_work(uv_work_t* work) | ||||
| static void _tf_ssb_update_settings_after_work(uv_work_t* work, int result) | ||||
| { | ||||
| 	update_settings_t* update = work->data; | ||||
| 	tf_ssb_unref(update->ssb); | ||||
| 	tf_ssb_set_is_room(update->ssb, update->is_room); | ||||
| 	tf_ssb_set_room_name(update->ssb, update->room_name); | ||||
| 	_tf_ssb_start_update_settings(update->ssb); | ||||
| 	tf_free(update); | ||||
| } | ||||
|  | ||||
| static void _tf_ssb_start_update_settings_timer(uv_timer_t* timer) | ||||
| static void _tf_ssb_start_update_settings_timer(tf_ssb_t* ssb, void* user_data) | ||||
| { | ||||
| 	update_settings_t* update = tf_malloc(sizeof(update_settings_t)); | ||||
| 	*update = (update_settings_t) | ||||
| @@ -3907,9 +3929,10 @@ static void _tf_ssb_start_update_settings_timer(uv_timer_t* timer) | ||||
| 		{ | ||||
| 			.data = update, | ||||
| 		}, | ||||
| 		.ssb = timer->data, | ||||
| 		.ssb = ssb, | ||||
| 	}; | ||||
| 	int result = uv_queue_work(tf_ssb_get_loop(timer->data), &update->work, _tf_ssb_update_settings_work, _tf_ssb_update_settings_after_work); | ||||
| 	tf_ssb_ref(ssb); | ||||
| 	int result = uv_queue_work(tf_ssb_get_loop(ssb), &update->work, _tf_ssb_update_settings_work, _tf_ssb_update_settings_after_work); | ||||
| 	if (result) | ||||
| 	{ | ||||
| 		_tf_ssb_update_settings_after_work(&update->work, result); | ||||
| @@ -3927,16 +3950,14 @@ static void _tf_ssb_update_settings(tf_ssb_t* ssb) | ||||
| 		}, | ||||
| 		.ssb = ssb, | ||||
| 	}; | ||||
| 	tf_ssb_ref(ssb); | ||||
| 	_tf_ssb_update_settings_work(&update->work); | ||||
| 	_tf_ssb_update_settings_after_work(&update->work, 0); | ||||
| } | ||||
|  | ||||
| static void _tf_ssb_start_update_settings(tf_ssb_t* ssb, int delay_ms) | ||||
| static void _tf_ssb_start_update_settings(tf_ssb_t* ssb) | ||||
| { | ||||
| 	ssb->settings_timer.data = ssb; | ||||
| 	uv_timer_init(ssb->loop, &ssb->settings_timer); | ||||
| 	uv_timer_start(&ssb->settings_timer, _tf_ssb_start_update_settings_timer, delay_ms, delay_ms); | ||||
| 	uv_unref((uv_handle_t*)&ssb->settings_timer); | ||||
| 	tf_ssb_schedule_work(ssb, 5000, _tf_ssb_start_update_settings_timer, NULL); | ||||
| } | ||||
|  | ||||
| void tf_ssb_set_verbose(tf_ssb_t* ssb, bool verbose) | ||||
| @@ -3976,4 +3997,5 @@ void tf_ssb_schedule_work(tf_ssb_t* ssb, int delay_ms, void (*callback)(tf_ssb_t | ||||
| 	ssb->timers[ssb->timers_count++] = timer; | ||||
| 	uv_timer_init(ssb->loop, &timer->timer); | ||||
| 	uv_timer_start(&timer->timer, _tf_ssb_scheduled_timer, delay_ms, 0); | ||||
| 	uv_unref((uv_handle_t*)&timer->timer); | ||||
| } | ||||
|   | ||||
| @@ -1333,6 +1333,7 @@ static void _tf_ssb_rpc_delete_blobs_work(uv_work_t* work) | ||||
| static void _tf_ssb_rpc_delete_blobs_after_work(uv_work_t* work, int status) | ||||
| { | ||||
| 	delete_blobs_work_t* delete = work->data; | ||||
| 	tf_ssb_unref(delete->ssb); | ||||
| 	tf_free(delete); | ||||
| } | ||||
|  | ||||
| @@ -1340,11 +1341,13 @@ static void _tf_ssb_rpc_start_delete_callback(tf_ssb_t* ssb, void* user_data) | ||||
| { | ||||
| 	delete_blobs_work_t* work = tf_malloc(sizeof(delete_blobs_work_t)); | ||||
| 	*work = (delete_blobs_work_t) { .work = { .data = work}, .ssb = ssb }; | ||||
| 	tf_ssb_ref(ssb); | ||||
| 	int r = uv_queue_work(tf_ssb_get_loop(ssb), &work->work, _tf_ssb_rpc_delete_blobs_work, _tf_ssb_rpc_delete_blobs_after_work); | ||||
| 	if (r) | ||||
| 	{ | ||||
| 		tf_printf("uv_queue_work: %s\n", uv_strerror(r)); | ||||
| 		tf_free(work); | ||||
| 		tf_ssb_unref(ssb); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -301,11 +301,16 @@ void tf_ssb_test_ssb(const tf_test_options_t* options) | ||||
| 	uv_close((uv_handle_t*)&idle0, NULL); | ||||
| 	uv_close((uv_handle_t*)&idle1, NULL); | ||||
|  | ||||
| 	tf_printf("final run\n"); | ||||
| 	uv_run(&loop, UV_RUN_DEFAULT); | ||||
| 	tf_printf("done\n"); | ||||
|  | ||||
| 	tf_printf("destroy 0\n"); | ||||
| 	tf_ssb_destroy(ssb0); | ||||
| 	tf_printf("destroy 1\n"); | ||||
| 	tf_ssb_destroy(ssb1); | ||||
|  | ||||
| 	tf_printf("close\n"); | ||||
| 	uv_loop_close(&loop); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user