]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Support locks with static fields
authorLevi Bard <taktaktaktaktaktaktaktaktaktak@gmail.com>
Mon, 27 Jul 2009 21:11:30 +0000 (23:11 +0200)
committerJürg Billeter <j@bitron.ch>
Mon, 27 Jul 2009 21:11:30 +0000 (23:11 +0200)
Fixes bug 537461.

codegen/valaccodebasemodule.vala
codegen/valagtypemodule.vala
tests/objects/fields.test
vala/valamemberaccess.vala
vala/valasymbol.vala

index bc6adf4154c95f13a882118db488016a9263d519..14b35f376d5f7165b8713caf83c676c294dcac90 100644 (file)
@@ -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));
index 7ac0ed2d9bbcf9a7d38ea9ffa40027a2012a3265..e5bf70e53e7b7a54714b30fe8f7573d22955b03c 100644 (file)
@@ -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 ());
index f347fbb1a83853ada60f365974ad842dcb966dc9..7690b6e4b20a4ac0d46c8b7ac7f997d680384164 100644 (file)
@@ -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);
index aa44c1eaee2b0269f407a73e4edd5a76a7f7ffad..3ce7399c90bda61486f45b8b95f344b916637d3c 100644 (file)
@@ -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 {
index 61a1c0ab3b0926316ee1f849305f9ac62a47b6de..ca54bd6e9b79868a2acc050a29f389ae9f4097cd 100644 (file)
@@ -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 {