From: Levi Bard Date: Mon, 27 Jul 2009 21:11:30 +0000 (+0200) Subject: Support locks with static fields X-Git-Tag: 0.7.5~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0154b1a6909c76d41b47a6dca011d078da316c14;p=thirdparty%2Fvala.git Support locks with static fields Fixes bug 537461. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index bc6adf415..14b35f376 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -747,16 +747,29 @@ internal class Vala.CCodeBaseModule : CCodeModule { /* stuff meant for all lockable members */ if (m is Lockable && ((Lockable) m).get_lock_used ()) { CCodeExpression l = new CCodeIdentifier ("self"); - l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m)); + CCodeFragment init_fragment = class_init_fragment; + CCodeFragment finalize_fragment = class_finalize_fragment; + + if (m.is_instance_member ()) { + l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m.name)); + init_fragment = instance_init_fragment; + finalize_fragment = instance_finalize_fragment; + } else if (m.is_class_member ()) { + TypeSymbol parent = (TypeSymbol)m.parent_symbol; + l = new CCodeIdentifier ("%s_GET_CLASS_PRIVATE(%s)".printf(parent.get_upper_case_cname (), parent.get_type_id ())); + l = new CCodeMemberAccess.pointer (l, get_symbol_lock_name (m.name)); + } else { + l = new CCodeIdentifier (get_symbol_lock_name ("%s_%s".printf(m.parent_symbol.get_lower_case_cname (), m.name))); + } var initf = new CCodeFunctionCall (new CCodeIdentifier (mutex_type.default_construction_method.get_cname ())); initf.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l)); - instance_init_fragment.append (new CCodeExpressionStatement (initf)); + init_fragment.append (new CCodeExpressionStatement (initf)); - if (instance_finalize_fragment != null) { + if (finalize_fragment != null) { var fc = new CCodeFunctionCall (new CCodeIdentifier ("g_static_rec_mutex_free")); fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l)); - instance_finalize_fragment.append (new CCodeExpressionStatement (fc)); + finalize_fragment.append (new CCodeExpressionStatement (fc)); } } } @@ -816,6 +829,20 @@ internal class Vala.CCodeBaseModule : CCodeModule { } decl_space.add_type_member_declaration (cdecl); + if (f.get_lock_used ()) { + // Declare mutex for static member + var flock = new CCodeDeclaration (mutex_type.get_cname ()); + var flock_decl = new CCodeVariableDeclarator (get_symbol_lock_name (f.get_cname ()), new CCodeConstant ("{0}")); + flock.add_declarator (flock_decl); + + if (f.is_private_symbol ()) { + flock.modifiers = CCodeModifiers.STATIC; + } else { + flock.modifiers = CCodeModifiers.EXTERN; + } + decl_space.add_type_member_declaration (flock); + } + if (f.field_type is ArrayType && !f.no_array_length) { var array_type = (ArrayType) f.field_type; @@ -2494,8 +2521,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { } } - public string get_symbol_lock_name (Symbol sym) { - return "__lock_%s".printf (sym.name); + public string get_symbol_lock_name (string symname) { + return "__lock_%s".printf (symname); } public override void visit_lock_statement (LockStatement stmt) { @@ -2503,15 +2530,26 @@ internal class Vala.CCodeBaseModule : CCodeModule { CCodeExpression l = null; CCodeFunctionCall fc; var inner_node = ((MemberAccess)stmt.resource).inner; + var member = (Member)stmt.resource.symbol_reference; + var parent = (TypeSymbol) stmt.resource.symbol_reference.parent_symbol; - if (inner_node == null) { - l = new CCodeIdentifier ("self"); - } else if (stmt.resource.symbol_reference.parent_symbol != current_type_symbol) { - l = new InstanceCast ((CCodeExpression) inner_node.ccodenode, (TypeSymbol) stmt.resource.symbol_reference.parent_symbol); + if (member.is_instance_member ()) { + if (inner_node == null) { + l = new CCodeIdentifier ("self"); + } else if (stmt.resource.symbol_reference.parent_symbol != current_type_symbol) { + l = new InstanceCast ((CCodeExpression) inner_node.ccodenode, parent); + } else { + l = (CCodeExpression) inner_node.ccodenode; + } + + l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (stmt.resource.symbol_reference.name)); + } else if (member.is_class_member ()) { + l = new CCodeIdentifier ("%s_GET_CLASS_PRIVATE(%s)".printf(parent.get_upper_case_cname (), parent.get_type_id ())); + l = new CCodeMemberAccess.pointer (l, get_symbol_lock_name (stmt.resource.symbol_reference.name)); } else { - l = (CCodeExpression) inner_node.ccodenode; + string lock_name = "%s_%s".printf(parent.get_lower_case_cname (), stmt.resource.symbol_reference.name); + l = new CCodeIdentifier (get_symbol_lock_name (lock_name)); } - l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (stmt.resource.symbol_reference)); fc = new CCodeFunctionCall (new CCodeIdentifier (((Method) mutex_type.scope.lookup ("lock")).get_cname ())); fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l)); diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 7ac0ed2d9..e5bf70e53 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -271,31 +271,33 @@ internal class Vala.GTypeModule : GErrorModule { field_ctype = "volatile " + field_ctype; } - if (f.binding == MemberBinding.INSTANCE && f.access != SymbolAccessibility.PRIVATE) { - generate_type_declaration (f.field_type, decl_space); + if (f.access != SymbolAccessibility.PRIVATE) { + if (f.binding == MemberBinding.INSTANCE) { + generate_type_declaration (f.field_type, decl_space); - instance_struct.add_field (field_ctype, f.get_cname ()); - if (f.field_type is ArrayType && !f.no_array_length) { - // create fields to store array dimensions - var array_type = (ArrayType) f.field_type; - var len_type = int_type.copy (); + instance_struct.add_field (field_ctype, f.get_cname ()); + if (f.field_type is ArrayType && !f.no_array_length) { + // create fields to store array dimensions + var array_type = (ArrayType) f.field_type; + var len_type = int_type.copy (); - for (int dim = 1; dim <= array_type.rank; dim++) { - instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim)); - } + for (int dim = 1; dim <= array_type.rank; dim++) { + instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim)); + } - if (array_type.rank == 1 && f.is_internal_symbol ()) { - instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name)); - } - } else if (f.field_type is DelegateType) { - var delegate_type = (DelegateType) f.field_type; - if (delegate_type.delegate_symbol.has_target) { - // create field to store delegate target - instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name)); + if (array_type.rank == 1 && f.is_internal_symbol ()) { + instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name)); + } + } else if (f.field_type is DelegateType) { + var delegate_type = (DelegateType) f.field_type; + if (delegate_type.delegate_symbol.has_target) { + // create field to store delegate target + instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name)); + } } + } else if (f.binding == MemberBinding.CLASS) { + type_struct.add_field (field_ctype, f.get_cname ()); } - } else if (f.binding == MemberBinding.CLASS && f.access != SymbolAccessibility.PRIVATE) { - type_struct.add_field (field_ctype, f.get_cname ()); } } @@ -331,6 +333,8 @@ internal class Vala.GTypeModule : GErrorModule { } bool is_gtypeinstance = !cl.is_compact; + bool has_instance_locks = false; + bool has_class_locks = false; var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ())); var type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ())); @@ -384,16 +388,25 @@ internal class Vala.GTypeModule : GErrorModule { } if (f.get_lock_used ()) { + has_instance_locks = true; + // add field for mutex + instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f.name)); + } + } else if (f.binding == MemberBinding.CLASS) { + if (f.access == SymbolAccessibility.PRIVATE) { + type_priv_struct.add_field (field_ctype, f.get_cname ()); + } + + if (f.get_lock_used ()) { + has_class_locks = true; // add field for mutex - instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f)); + type_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f.get_cname ())); } - } else if (f.binding == MemberBinding.CLASS && f.access == SymbolAccessibility.PRIVATE) { - type_priv_struct.add_field (field_ctype, f.get_cname ()); } } if (is_gtypeinstance) { - if (cl.has_class_private_fields) { + if (cl.has_class_private_fields || has_class_locks) { decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ())))); var cdecl = new CCodeDeclaration ("GQuark"); cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0"))); @@ -402,13 +415,13 @@ internal class Vala.GTypeModule : GErrorModule { } /* only add the *Private struct if it is not empty, i.e. we actually have private data */ - if (cl.has_private_fields || cl.get_type_parameters ().size > 0) { + if (cl.has_private_fields || cl.get_type_parameters ().size > 0 || has_instance_locks) { decl_space.add_type_definition (instance_priv_struct); var macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_type_id (), cl.get_cname ()); decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro)); } - if (cl.has_class_private_fields) { + if (cl.has_class_private_fields || has_class_locks) { decl_space.add_type_member_declaration (type_priv_struct); var macro = "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl.get_cname(), cl.get_lower_case_cname ()); diff --git a/tests/objects/fields.test b/tests/objects/fields.test index f347fbb1a..7690b6e4b 100644 --- a/tests/objects/fields.test +++ b/tests/objects/fields.test @@ -35,10 +35,18 @@ class Maman.Bar : Foo { public_base_field = 9; public_field = 10; private_field = 11; - private_static_field = 12; - public_static_field = 13; - private_class_field = 14; - public_class_field = 15; + lock (private_static_field) { + private_static_field = 12; + } + lock (public_static_field) { + public_static_field = 13; + } + lock (private_class_field) { + private_class_field = 14; + } + lock (public_class_field) { + public_class_field = 15; + } stdout.printf (" %d %d %d %d %d %d %d", public_base_field, public_field, private_field, private_static_field, public_static_field, private_class_field, public_class_field); diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index aa44c1eae..3ce7399c9 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -133,25 +133,7 @@ public class Vala.MemberAccess : Expression { } public override string to_string () { - bool instance = true; - if (symbol_reference is Field) { - var f = (Field) symbol_reference; - instance = (f.binding == MemberBinding.INSTANCE); - } else if (symbol_reference is Method) { - var m = (Method) symbol_reference; - if (!(m is CreationMethod)) { - instance = (m.binding == MemberBinding.INSTANCE); - } - } else if (symbol_reference is Property) { - var prop = (Property) symbol_reference; - instance = (prop.binding == MemberBinding.INSTANCE); - } else if (symbol_reference is EnumValue) { - instance = false; - } else if (symbol_reference is ErrorCode) { - instance = false; - } - - if (instance) { + if (symbol_reference.is_instance_member ()) { if (inner == null) { return member_name; } else { diff --git a/vala/valasymbol.vala b/vala/valasymbol.vala index 61a1c0ab3..ca54bd6e9 100644 --- a/vala/valasymbol.vala +++ b/vala/valasymbol.vala @@ -313,6 +313,50 @@ public abstract class Vala.Symbol : CodeNode { // if this is a public symbol, it's equally accessible as the parent symbol return parent_symbol.get_top_accessible_scope (is_internal); } + + public virtual bool is_instance_member () { + bool instance = true; + if (this is Field) { + var f = (Field) this; + instance = (f.binding == MemberBinding.INSTANCE); + } else if (this is Method) { + var m = (Method) this; + if (!(m is CreationMethod)) { + instance = (m.binding == MemberBinding.INSTANCE); + } + } else if (this is Property) { + var prop = (Property) this; + instance = (prop.binding == MemberBinding.INSTANCE); + } else if (this is EnumValue) { + instance = false; + } else if (this is ErrorCode) { + instance = false; + } + + return instance; + } + + public virtual bool is_class_member () { + bool isclass = true; + if (this is Field) { + var f = (Field) this; + isclass = (f.binding == MemberBinding.CLASS); + } else if (this is Method) { + var m = (Method) this; + if (!(m is CreationMethod)) { + isclass = (m.binding == MemberBinding.CLASS); + } + } else if (this is Property) { + var prop = (Property) this; + isclass = (prop.binding == MemberBinding.CLASS); + } else if (this is EnumValue) { + isclass = false; + } else if (this is ErrorCode) { + isclass = false; + } + + return isclass; + } } public enum Vala.SymbolAccessibility {