android: Fix some crashes, callstacks, and warnings I'm seeing in the logs.
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build Tilde Friends / Build-All (push) Successful in 16m27s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build Tilde Friends / Build-All (push) Successful in 16m27s
				
			This commit is contained in:
		| @@ -385,8 +385,11 @@ public class TildeFriendsActivity extends Activity { | |||||||
| 			public void onServiceConnected(ComponentName name, IBinder binder) { | 			public void onServiceConnected(ComponentName name, IBinder binder) { | ||||||
| 				Log.w("tildefriends", "onServiceConnected"); | 				Log.w("tildefriends", "onServiceConnected"); | ||||||
| 				Parcel data = Parcel.obtain(); | 				Parcel data = Parcel.obtain(); | ||||||
| 				ParcelFileDescriptor pfd = ParcelFileDescriptor.adoptFd(pipe_fd); | 				try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(pipe_fd)) { | ||||||
| 				data.writeParcelable(pfd, 0); | 					data.writeParcelable(pfd, 0); | ||||||
|  | 				} catch (java.io.IOException e) { | ||||||
|  | 					Log.w("tildefriends", "IOException: " + e); | ||||||
|  | 				} | ||||||
| 				try { | 				try { | ||||||
| 					binder.transact(TildeFriendsSandboxService.START_CALL,  data, null, IBinder.FLAG_ONEWAY); | 					binder.transact(TildeFriendsSandboxService.START_CALL,  data, null, IBinder.FLAG_ONEWAY); | ||||||
| 				} catch (RemoteException e) { | 				} catch (RemoteException e) { | ||||||
|   | |||||||
| @@ -12,6 +12,8 @@ typedef struct _tf_packetstream_t | |||||||
| { | { | ||||||
| 	tf_packetstream_onreceive_t* onreceive; | 	tf_packetstream_onreceive_t* onreceive; | ||||||
| 	void* onreceive_user_data; | 	void* onreceive_user_data; | ||||||
|  | 	tf_packetstream_on_close_t* on_close; | ||||||
|  | 	void* on_close_user_data; | ||||||
| 	uv_pipe_t stream; | 	uv_pipe_t stream; | ||||||
| 	char* buffer; | 	char* buffer; | ||||||
| 	size_t buffer_size; | 	size_t buffer_size; | ||||||
| @@ -30,6 +32,8 @@ void tf_packetstream_destroy(tf_packetstream_t* stream) | |||||||
| { | { | ||||||
| 	stream->onreceive = NULL; | 	stream->onreceive = NULL; | ||||||
| 	stream->onreceive_user_data = NULL; | 	stream->onreceive_user_data = NULL; | ||||||
|  | 	stream->on_close = NULL; | ||||||
|  | 	stream->on_close_user_data = NULL; | ||||||
| 	stream->destroyed = true; | 	stream->destroyed = true; | ||||||
| 	if (stream->buffer) | 	if (stream->buffer) | ||||||
| 	{ | 	{ | ||||||
| @@ -110,6 +114,14 @@ static void _packetstream_on_read(uv_stream_t* handle, ssize_t count, const uv_b | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
|  | 		tf_packetstream_on_close_t* on_close = stream->on_close; | ||||||
|  | 		void* user_data = stream->on_close_user_data; | ||||||
|  | 		stream->on_close = NULL; | ||||||
|  | 		stream->on_close_user_data = NULL; | ||||||
|  | 		if (on_close) | ||||||
|  | 		{ | ||||||
|  | 			on_close(user_data); | ||||||
|  | 		} | ||||||
| 		tf_packetstream_close(stream); | 		tf_packetstream_close(stream); | ||||||
| 	} | 	} | ||||||
| 	tf_free(buffer->base); | 	tf_free(buffer->base); | ||||||
| @@ -150,7 +162,7 @@ void tf_packetstream_send(tf_packetstream_t* stream, int packet_type, const char | |||||||
| 		int result = uv_write(request, (uv_stream_t*)&stream->stream, &write_buffer, 1, _packetstream_on_write); | 		int result = uv_write(request, (uv_stream_t*)&stream->stream, &write_buffer, 1, _packetstream_on_write); | ||||||
| 		if (result) | 		if (result) | ||||||
| 		{ | 		{ | ||||||
| 			tf_printf("uv_write: %s\n", uv_strerror(result)); | 			tf_printf("tf_packetstream_send: uv_write: %s\n", uv_strerror(result)); | ||||||
| 			tf_free(request); | 			tf_free(request); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -162,6 +174,12 @@ void tf_packetstream_set_on_receive(tf_packetstream_t* stream, tf_packetstream_o | |||||||
| 	stream->onreceive_user_data = user_data; | 	stream->onreceive_user_data = user_data; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void tf_packetstream_set_on_close(tf_packetstream_t* stream, tf_packetstream_on_close_t* callback, void* user_data) | ||||||
|  | { | ||||||
|  | 	stream->on_close = callback; | ||||||
|  | 	stream->on_close_user_data = user_data; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void _tf_packetstream_handle_closed(uv_handle_t* handle) | static void _tf_packetstream_handle_closed(uv_handle_t* handle) | ||||||
| { | { | ||||||
| 	tf_packetstream_t* packetstream = handle->data; | 	tf_packetstream_t* packetstream = handle->data; | ||||||
|   | |||||||
| @@ -23,6 +23,12 @@ typedef struct _tf_packetstream_t tf_packetstream_t; | |||||||
| */ | */ | ||||||
| typedef void(tf_packetstream_onreceive_t)(int packet_type, const char* begin, size_t length, void* user_data); | typedef void(tf_packetstream_onreceive_t)(int packet_type, const char* begin, size_t length, void* user_data); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  | ** A function called when a packetstream reads EOF. | ||||||
|  | ** @param user_data User data. | ||||||
|  | */ | ||||||
|  | typedef void(tf_packetstream_on_close_t)(void* user_data); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| ** Create a packet stream. | ** Create a packet stream. | ||||||
| ** @return The packet stream. | ** @return The packet stream. | ||||||
| @@ -58,6 +64,14 @@ void tf_packetstream_send(tf_packetstream_t* stream, int packet_type, const char | |||||||
| */ | */ | ||||||
| void tf_packetstream_set_on_receive(tf_packetstream_t* stream, tf_packetstream_onreceive_t* callback, void* user_data); | void tf_packetstream_set_on_receive(tf_packetstream_t* stream, tf_packetstream_onreceive_t* callback, void* user_data); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  | ** Register a callback for when a stream reads EOF. | ||||||
|  | ** @param stream The packet stream. | ||||||
|  | ** @param callback The callback. | ||||||
|  | ** @param user_data User data to pass to the callback. | ||||||
|  | */ | ||||||
|  | void tf_packetstream_set_on_close(tf_packetstream_t* stream, tf_packetstream_on_close_t* callback, void* user_data); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| ** Close a packet stream. | ** Close a packet stream. | ||||||
| ** @param stream The packet stream. | ** @param stream The packet stream. | ||||||
|   | |||||||
| @@ -62,6 +62,7 @@ static JSValue _taskstub_set_on_print(JSContext* context, JSValueConst this_val, | |||||||
| static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); | ||||||
| static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal); | static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal); | ||||||
| static void _taskstub_finalizer(JSRuntime* runtime, JSValue value); | static void _taskstub_finalizer(JSRuntime* runtime, JSValue value); | ||||||
|  | static void _taskstub_cleanup(tf_taskstub_t* stub); | ||||||
|  |  | ||||||
| static void _tf_taskstub_run_sandbox_thread(void* data) | static void _tf_taskstub_run_sandbox_thread(void* data) | ||||||
| { | { | ||||||
| @@ -74,12 +75,60 @@ static void _tf_taskstub_run_sandbox_thread(void* data) | |||||||
| 	tf_task_destroy(task); | 	tf_task_destroy(task); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void _taskstub_on_handle_close(uv_handle_t* handle) | ||||||
|  | { | ||||||
|  | 	tf_taskstub_t* stub = handle->data; | ||||||
|  | 	tf_task_remove_child(stub->_owner, stub); | ||||||
|  | 	handle->data = NULL; | ||||||
|  | 	_taskstub_cleanup(stub); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void _tf_taskstub_on_exit(tf_taskstub_t* stub, int64_t status, int termination_signal) | ||||||
|  | { | ||||||
|  | 	JSContext* context = tf_task_get_context(stub->_owner); | ||||||
|  | 	if (!JS_IsUndefined(stub->_on_exit)) | ||||||
|  | 	{ | ||||||
|  | 		JSValue ref = JS_DupValue(context, stub->_on_exit); | ||||||
|  | 		JSValue argv[] = { JS_NewInt64(context, status), JS_NewInt32(context, termination_signal) }; | ||||||
|  | 		JSValue result = JS_Call(context, stub->_on_exit, JS_NULL, 2, argv); | ||||||
|  | 		tf_util_report_error(context, result); | ||||||
|  | 		JS_FreeValue(context, result); | ||||||
|  | 		JS_FreeValue(context, argv[0]); | ||||||
|  | 		JS_FreeValue(context, argv[1]); | ||||||
|  | 		JS_FreeValue(context, ref); | ||||||
|  | 	} | ||||||
|  | 	if (stub->_stream) | ||||||
|  | 	{ | ||||||
|  | 		tf_packetstream_destroy(stub->_stream); | ||||||
|  | 		stub->_stream = NULL; | ||||||
|  | 	} | ||||||
|  | 	tf_task_remove_child(stub->_owner, stub); | ||||||
|  | 	if (stub->_process.data) | ||||||
|  | 	{ | ||||||
|  | 		uv_close((uv_handle_t*)&stub->_process, _taskstub_on_handle_close); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		_taskstub_cleanup(stub); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void _tf_taskstub_packetstream_close(void* user_data) | ||||||
|  | { | ||||||
|  | 	tf_taskstub_t* stub = user_data; | ||||||
|  | 	if (!stub->_process.data) | ||||||
|  | 	{ | ||||||
|  | 		_tf_taskstub_on_exit(stub, -1, -1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||||
| { | { | ||||||
| 	tf_task_t* parent = tf_task_get(context); | 	tf_task_t* parent = tf_task_get(context); | ||||||
| 	tf_taskstub_t* stub = tf_malloc(sizeof(tf_taskstub_t)); | 	tf_taskstub_t* stub = tf_malloc(sizeof(tf_taskstub_t)); | ||||||
| 	memset(stub, 0, sizeof(*stub)); | 	memset(stub, 0, sizeof(*stub)); | ||||||
| 	stub->_stream = tf_packetstream_create(); | 	stub->_stream = tf_packetstream_create(); | ||||||
|  | 	tf_packetstream_set_on_close(stub->_stream, _tf_taskstub_packetstream_close, stub); | ||||||
|  |  | ||||||
| 	JSValue taskObject = JS_NewObjectClass(context, _classId); | 	JSValue taskObject = JS_NewObjectClass(context, _classId); | ||||||
| 	JS_SetOpaque(taskObject, stub); | 	JS_SetOpaque(taskObject, stub); | ||||||
| @@ -314,35 +363,10 @@ static void _taskstub_finalizer(JSRuntime* runtime, JSValue value) | |||||||
| 	_taskstub_cleanup(stub); | 	_taskstub_cleanup(stub); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void _taskstub_on_handle_close(uv_handle_t* handle) | static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int termination_signal) | ||||||
| { |  | ||||||
| 	tf_taskstub_t* stub = handle->data; |  | ||||||
| 	tf_task_remove_child(stub->_owner, stub); |  | ||||||
| 	handle->data = NULL; |  | ||||||
| 	_taskstub_cleanup(stub); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal) |  | ||||||
| { | { | ||||||
| 	tf_taskstub_t* stub = process->data; | 	tf_taskstub_t* stub = process->data; | ||||||
| 	JSContext* context = tf_task_get_context(stub->_owner); | 	_tf_taskstub_on_exit(stub, status, termination_signal); | ||||||
| 	if (!JS_IsUndefined(stub->_on_exit)) |  | ||||||
| 	{ |  | ||||||
| 		JSValue ref = JS_DupValue(context, stub->_on_exit); |  | ||||||
| 		JSValue argv[] = { JS_NewInt64(context, status), JS_NewInt32(context, terminationSignal) }; |  | ||||||
| 		JSValue result = JS_Call(context, stub->_on_exit, JS_NULL, 2, argv); |  | ||||||
| 		tf_util_report_error(context, result); |  | ||||||
| 		JS_FreeValue(context, result); |  | ||||||
| 		JS_FreeValue(context, argv[0]); |  | ||||||
| 		JS_FreeValue(context, argv[1]); |  | ||||||
| 		JS_FreeValue(context, ref); |  | ||||||
| 	} |  | ||||||
| 	if (stub->_stream) |  | ||||||
| 	{ |  | ||||||
| 		tf_packetstream_destroy(stub->_stream); |  | ||||||
| 		stub->_stream = NULL; |  | ||||||
| 	} |  | ||||||
| 	uv_close((uv_handle_t*)process, _taskstub_on_handle_close); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static JSValue _taskstub_getExports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | static JSValue _taskstub_getExports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user