vala r2430 - in trunk: . gobject



Author: ryanl
Date: Wed Feb 11 16:03:53 2009
New Revision: 2430
URL: http://svn.gnome.org/viewvc/vala?rev=2430&view=rev

Log:
2009-02-11  Ryan Lortie  <desrt desrt ca>

        Bug 571263 â make yielding functions dispatch results to mainloop

        * gobject/valaccodemethodmodule.vala:
        * valagasyncmodule.vala:

        Create simple async result from _async entry function and use it when
        doing return; throw; or at the end of the function.  Fix return 
        statements for the async case.  Dispatch via idle handler in the case
        that we are returning without having yielded.



Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodemethodmodule.vala
   trunk/gobject/valagasyncmodule.vala

Modified: trunk/gobject/valaccodemethodmodule.vala
==============================================================================
--- trunk/gobject/valaccodemethodmodule.vala	(original)
+++ trunk/gobject/valaccodemethodmodule.vala	Wed Feb 11 16:03:53 2009
@@ -111,6 +111,35 @@
 		}
 	}
 
+	public CCodeStatement complete_async () {
+		var complete_block = new CCodeBlock ();
+
+		var direct_block = new CCodeBlock ();
+		var direct_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
+		var async_result_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result");
+		direct_call.add_argument (async_result_expr);
+		direct_block.add_statement (new CCodeExpressionStatement (direct_call));
+
+		var idle_block = new CCodeBlock ();
+		var idle_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete_in_idle"));
+		idle_call.add_argument (async_result_expr);
+		idle_block.add_statement (new CCodeExpressionStatement (idle_call));
+
+		var state = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state");
+		var zero = new CCodeConstant ("0");
+		var state_is_zero = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, state, zero);
+		var dispatch = new CCodeIfStatement (state_is_zero, idle_block, direct_block);
+		complete_block.add_statement (dispatch);
+
+		var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+		unref.add_argument (async_result_expr);
+		complete_block.add_statement (new CCodeExpressionStatement (unref));
+
+		complete_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+
+		return complete_block;
+	}
+
 	public override void visit_method (Method m) {
 		var old_type_symbol = current_type_symbol;
 		var old_symbol = current_symbol;
@@ -281,23 +310,8 @@
 					// coroutine body
 					cswitch.add_statement (function.block);
 
-					// complete async call by invoking callback
-					var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
-					object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
-					object_creation.add_argument (new CCodeConstant ("0"));
-					object_creation.add_argument (new CCodeConstant ("NULL"));
-
-					var async_result_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
-					async_result_creation.add_argument (object_creation);
-					async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"));
-					async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"));
-					async_result_creation.add_argument (new CCodeIdentifier ("data"));
-
-					var completecall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
-					completecall.add_argument (async_result_creation);
-					cswitch.add_statement (new CCodeExpressionStatement (completecall));
-
-					cswitch.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+					// epilogue
+					cswitch.add_statement (complete_async ());
 
 					co_function.block = new CCodeBlock ();
 					co_function.block.add_statement (cswitch);
@@ -924,3 +938,5 @@
 		}
 	}
 }
+
+// vim:sw=8 noet

Modified: trunk/gobject/valagasyncmodule.vala
==============================================================================
--- trunk/gobject/valagasyncmodule.vala	(original)
+++ trunk/gobject/valagasyncmodule.vala	Wed Feb 11 16:03:53 2009
@@ -44,9 +44,8 @@
 		closure_struct = new CCodeStruct ("_" + dataname);
 
 		closure_struct.add_field ("int", "state");
-		closure_struct.add_field ("GAsyncReadyCallback", "callback");
-		closure_struct.add_field ("gpointer", "user_data");
 		closure_struct.add_field ("GAsyncResult*", "res");
+		closure_struct.add_field ("GSimpleAsyncResult*", "_async_result");
 
 		if (m.binding == MemberBinding.INSTANCE) {
 			var type_sym = (TypeSymbol) m.parent_symbol;
@@ -82,8 +81,25 @@
 		asyncblock.add_statement (datadecl);
 		asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), dataalloc)));
 
-		asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"), new CCodeIdentifier ("callback"))));
-		asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"), new CCodeIdentifier ("user_data"))));
+		var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
+
+		var cl = m.parent_symbol as Class;
+		if (m.binding == MemberBinding.INSTANCE &&
+		    cl != null && cl.is_subtype_of (gobject_type)) {
+			create_result.add_argument (new CCodeIdentifier ("self"));
+		} else {
+			var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
+			object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
+			object_creation.add_argument (new CCodeConstant ("0"));
+			object_creation.add_argument (new CCodeConstant ("NULL"));
+			create_result.add_argument (object_creation);
+		}
+
+		create_result.add_argument (new CCodeIdentifier ("callback"));
+		create_result.add_argument (new CCodeIdentifier ("user_data"));
+		create_result.add_argument (new CCodeIdentifier (m.get_real_cname () + "_async"));
+
+		asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"), create_result)));
 
 		if (m.binding == MemberBinding.INSTANCE) {
 			asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "self"), new CCodeIdentifier ("self"))));
@@ -283,25 +299,11 @@
 		}
 
 		var block = new CCodeBlock ();
-		var cl = current_method.parent_symbol as Class;
-
-		var report_idle = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_report_gerror_in_idle"));
-
-		if (current_method.binding == MemberBinding.INSTANCE &&
-		    cl != null && cl.is_subtype_of (gobject_type)) {
-			report_idle.add_argument (new CCodeIdentifier ("self"));
-		} else {
-			var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
-			object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
-			object_creation.add_argument (new CCodeConstant ("0"));
-			object_creation.add_argument (new CCodeConstant ("NULL"));
-			report_idle.add_argument (object_creation);
-		}
 
-		report_idle.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"));
-		report_idle.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"));
-		report_idle.add_argument (error_expr);
-		block.add_statement (new CCodeExpressionStatement (report_idle));
+		var set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_from_error"));
+		set_error.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"));
+		set_error.add_argument (error_expr);
+		block.add_statement (new CCodeExpressionStatement (set_error));
 
 		var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
 		free_error.add_argument (error_expr);
@@ -311,10 +313,35 @@
 		append_local_free (current_symbol, free_locals, false);
 		block.add_statement (free_locals);
 
-		block.add_statement (new CCodeReturnStatement ());
+		block.add_statement (complete_async ());
 
 		return block;
 	}
+
+	public override void visit_return_statement (ReturnStatement stmt) {
+		if (current_method == null || !current_method.coroutine) {
+			base.visit_return_statement (stmt);
+			return;
+		}
+
+		stmt.accept_children (codegen);
+
+		var result_block = new CCodeBlock ();
+		stmt.ccodenode = result_block;
+
+		if (stmt.return_expression != null) {
+			var result_var = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result");
+			var assign_result = new CCodeAssignment (result_var, (CCodeExpression) stmt.return_expression.ccodenode);
+			result_block.add_statement (new CCodeExpressionStatement (assign_result));
+			create_temp_decl (stmt, stmt.return_expression.temp_vars);
+		}
+
+		var free_locals = new CCodeFragment ();
+		append_local_free (current_symbol, free_locals, false);
+		result_block.add_statement (free_locals);
+
+		result_block.add_statement (complete_async ());
+	}
 }
 
 // vim:sw=8 noet



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]