From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id EF3C5385AC19; Wed, 24 Aug 2022 07:57:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EF3C5385AC19 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661327849; bh=WkxQAJh1eiO+NPNfy4P/8SAa5iSGtZf0Syt9B6Fl4H0=; h=From:To:Subject:Date:From; b=Y/xOuMHLyV9eVUuh7j3SRVDaUjjiIZHtazrhAEb0hiue7/Xq7BRPe/tR32LUFRcLB EjkMAM7f6OhRcOdltNvAupOmJ29otiSxBtpeJyP5a9b4VNbyAdzX0m2fW3NlOO51cT nMi2TWXaCG+Tn+uTpwSidjeKAKystAC2bLw2BiUM= From: "benni.probst at gmx dot de" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/106732] New: lock cannot be generated in a special case Date: Wed, 24 Aug 2022 07:57:29 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 12.1.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: benni.probst at gmx dot de X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone attachments.created Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D106732 Bug ID: 106732 Summary: lock cannot be generated in a special case Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: benni.probst at gmx dot de Target Milestone: --- Created attachment 53500 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=3D53500&action=3Dedit CLion bug analysis picture when using a recursive mutex and a scoped lock or unique lock or lock guard (does not matter) on the recursive mutex, code cannot be generated even if = it worked in the function above. // // Created by benjamin-elias on 09.05.22. // #include "config_files.h" #include "global_custom_functions.h" #ifndef SCHOOL_PROJECT_DATABASE_CALL_OPS_H #define SCHOOL_PROJECT_DATABASE_CALL_OPS_H class database_call_ops { bool connection_set=3Dfalse; std::recursive_mutex database_mutex{}; pqxx::connection *connection; protected: std::string addr, p, user, pass, datab; //TODO: set up connection and custom database call ops public: std::string schem, tab; protected: bool open=3Dfalse; virtual std::string currentSchema() { const std::lock_guard lock(database_mutex); return schem; } virtual std::string currentTableName() { const std::lock_guard lock(database_mutex); return tab; } [[nodiscard]] bool isOpen(const std::string &table) const { const std::scoped_lock lock(database_mutex); return open and tab=3D=3Dtable; } std::string currentDatabase() { return datab; } bool checkSchemaExists(const std::string &schema) { try{ std::string sql =3D "SELECT EXISTS(SELECT schema_name FROM information_schema.schemata WHERE schema_name =3D '"+schema+"');"; custom_function::replace_string_occurencies(sql," "," "); pqxx::nontransaction n(connection); pqxx::result r(n.exec(sql)); n.commit(); for (pqxx::result::const_iterator c =3D r.begin(); c !=3D r.end= ();) { auto it =3D c; if(++c =3D=3D r.end())[[likely]]{ return it[0].as();} else break; } } catch (std::exception &e){ std::cerr << "checkSchemaExists on " << schema << " failed for = this reason: " << e.what(); } return false; } //returns if schema exists now bool createSchema(const std::string &schema) { if (checkSchemaExists(schema))[[likely]]return true; try{ std::string sql =3D "CREATE SCHEMA IF NOT EXISTS " + schema + " AUTHORIZATION " + user + " ; GRANT ALL ON SCHEMA " + schema + " TO " + data= b + " ; GRANT ALL ON SCHEMA " + schema + " TO public;"; custom_function::replace_string_occurencies(sql," "," "); pqxx::work n(connection); n.exec(sql); n.commit(); } catch (std::exception &e){ std::cerr << "createSchema on " << schema << " failed for this reason: " << e.what(); exit(EXIT_FAILURE); } return checkSchemaExists(schema); } bool deleteSchema(const std::string &schema) { if (!checkSchemaExists(schema))[[unlikely]]{return false;} try{ std::string sql =3D "DROP SCHEMA IF EXISTS "+schema+" CASCADE;"; custom_function::replace_string_occurencies(sql," "," "); pqxx::work n(connection); n.exec(sql); n.commit(); } catch (std::exception &e){ std::cerr << "deleteSchema on " << schema << " failed for this reason: " << e.what(); } return !checkSchemaExists(schema); } bool checkTableExists(const std::string &schema, const std::string &tab= le) { if (!checkSchemaExists(schema))[[unlikely]]{return false;} try{ std::string sql =3D "SELECT EXISTS (SELECT FROM pg_catalog.pg_c= lass c JOIN pg_catalog.pg_namespace n" " ON n.oid =3D c.relnamespace WHERE n.nspname= =3D '"+schema+"' AND c.relname =3D '"+table+ "' AND c.relkind =3D 'r' );"; custom_function::replace_string_occurencies(sql," "," "); pqxx::nontransaction n(connection); pqxx::result r(n.exec(sql)); n.commit(); for (pqxx::result::const_iterator c =3D r.begin(); c !=3D r.end= ();) { auto it =3D c; if(++c =3D=3D r.end())[[likely]]{return it[0].as();} else break; } } catch (std::exception &e){ std::cerr << "checkTableExists on (Schema: " << schema << ", Ta= ble: " << table << ") failed for this reason: " << e.what(); } return false; } std::vector> table_info(const std::string &schema, const std::string &table) { std::vector> out; try{ //table_name, column_name, data_type if(!checkTableExists(schema,table))[[unlikely]]{return out;} std::string sql =3D "SELECT column_name, data_type FROM information_schema.columns WHERE table_schema like '"+schema+"%' AND table_= name like '"+table+"%' ;"; custom_function::replace_string_occurencies(sql," "," "); pqxx::nontransaction n(connection); pqxx::result r(n.exec(sql)); n.commit(); for (pqxx::result::const_iterator c =3D r.begin(); c !=3D r.end= ();) { =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 out.emplace_back(c[0].as(),c[1].as()); if(++c =3D=3D r.end())[[unlikely]]{return out;} } } catch (std::exception &e){ std::cerr << "table_info on (Schema: " << schema << ", Table: "= << table << ") failed for this reason: " << e.what(); return out; } return out; } bool deleteTable(const std::string &schema, const std::string &table) { if (!checkTableExists(schema,table))[[unlikely]]{return false;} try{ std::string sql =3D "DROP TABLE IF EXISTS "+schema+"."+table+";= "; custom_function::replace_string_occurencies(sql," "," "); pqxx::work n(connection); n.exec(sql); n.commit(); } catch (std::exception &e){ std::cerr << "deleteTable on (Schema: " << schema << ", Table: = " << table << ") failed for this reason: " << e.what(); } return !checkTableExists(schema,table); } private: /* * this is a variadic function to transform requested types into string literals that tell the SQL database * to generate tables with certain data types */ template std::string createTableRecursiveVariadicDefinition(T1 &&arg1, T2 &&arg2= , T3 &&arg3, Args &&... args) { std::string out; if constexpr(String){ if (boost::ifind_first(std::forward(arg2), std::string("character varying")) or boost::ifind_first(std::forward(arg2), std::string("varchar")) or boost::ifind_first(std::forward(arg2), std::string("character")) or boost::ifind_first(std::forward(arg2), std::string("cha= r")) or boost::ifind_first(std::forward(arg2), std::string("tex= t")) or boost::ifind_first(std::forward(arg2), std::string("bytea")) or boost::ifind_first(std::forward(arg2), std::string("smallint")) or boost::ifind_first(std::forward(arg2), std::string("integer")) or boost::ifind_first(std::forward(arg2), std::string("bigint")) or boost::ifind_first(std::forward(arg2), std::string("decimal")) or boost::ifind_first(std::forward(arg2), std::string("numeric")) or boost::ifind_first(std::forward(arg2), std::string("rea= l")) or boost::ifind_first(std::forward(arg2), std::string("dou= ble precision")) or boost::ifind_first(std::forward(arg2), std::string("smallserial")) or boost::ifind_first(std::forward(arg2), std::string("serial")) or boost::ifind_first(std::forward(arg2), std::string("bigserial")) or boost::ifind_first(std::forward(arg2), std::string("money")) or boost::ifind_first(std::forward(arg2), std::string("timestamp")) or boost::ifind_first(std::forward(arg2), std::string("TIMESTAMPTZ")) or boost::ifind_first(std::forward(arg2), std::string("dat= e")) or boost::ifind_first(std::forward(arg2), std::string("a_var")) or boost::ifind_first(std::forward(arg2), std::string("interval")) or boost::ifind_first(std::forward(arg2), std::string("boolean")) or boost::ifind_first(std::forward(arg2), std::string("point")) or boost::ifind_first(std::forward(arg2), std::string("lin= e")) or boost::ifind_first(std::forward(arg2), std::string("lse= g")) or boost::ifind_first(std::forward(arg2), std::string("box= ")) or boost::ifind_first(std::forward(arg2), std::string("pat= h")) or boost::ifind_first(std::forward(arg2), std::string("polygon")) or boost::ifind_first(std::forward(arg2), std::string("circle")) or boost::ifind_first(std::forward(arg2), std::string("cid= r")) or boost::ifind_first(std::forward(arg2), std::string("ine= t")) or boost::ifind_first(std::forward(arg2), std::string("macaddr")) or boost::ifind_first(std::forward(arg2), std::string("tsvector")) or boost::ifind_first(std::forward(arg2), std::string("tsquery")) or boost::ifind_first(std::forward(arg2), std::string("any= ")) or boost::ifind_first(std::forward(arg2), std::string("anyelement")) or boost::ifind_first(std::forward(arg2), std::string("anyarray")) or boost::ifind_first(std::forward(arg2), std::string("anynonarray")) or boost::ifind_first(std::forward(arg2), std::string("anyenum")) or boost::ifind_first(std::forward(arg2), std::string("anyrange")) or boost::ifind_first(std::forward(arg2), std::string("cstring")) or boost::ifind_first(std::forward(arg2), std::string("internal")) or boost::ifind_first(std::forward(arg2), std::string("language_handler")) or boost::ifind_first(std::forward(arg2), std::string("fdw_handler")) or boost::ifind_first(std::forward(arg2), std::string("record")) or boost::ifind_first(std::forward(arg2), std::string("trigger")) or boost::ifind_first(std::forward(arg2), std::string("voi= d")) ){ out+=3D(std::string) std::forward(arg1)+" "+(std::strin= g) std::forward(arg2)+" "+(std::string) std::forward(arg3); } else{ if constexpr(sizeof...(args)=3D=3D0){ out+=3D(std::string) std::forward(arg1)+" "+(std::s= tring) std::forward(arg2)+" "+(std::string) std::forward(arg3); } else{ out+=3D(std::string) std::forward(arg1)+" text "+(std::string) std::forward(arg3); } } } else{ if constexpr(std::is_same_v::type,unsig= ned char> or std::is_same_v::type,unsig= ned short> or std::is_same_v::type,char>= or std::is_same_v::type,short> ){ out+=3D(std::string) std::forward(arg1)+" smallint "+(std::string) std::forward(arg3); } if constexpr(std::is_same_v::type,unsig= ned int> or std::is_same_v::type,int> ){ out+=3D(std::string) std::forward(arg1)+" integer "+(std::string) std::forward(arg3); } if constexpr(std::is_same_v::type,unsig= ned long int> or std::is_same_v::type,unsig= ned long long int> or std::is_same_v::type,long = int> or std::is_same_v::type,long = long int> ){ out+=3D(std::string) std::forward(arg1)+" bigint "+(std::string) std::forward(arg3); } if constexpr(std::is_same_v::type,float= >){ out+=3D(std::string) std::forward(arg1)+" real "+(std::string) std::forward(arg3); } if constexpr(std::is_same_v::type,doubl= e> or std::is_same_v::type,long double> ){ out+=3D(std::string) std::forward(arg1)+" double precis= ion "+(std::string) std::forward(arg3); } if constexpr(std::is_same_v::type,bool>= ){ out+=3D(std::string) std::forward(arg1)+" boolean "+(std::string) std::forward(arg3); } } if constexpr(sizeof...(args)=3D=3D0){ return out; } else{ return out+", "+createTableRecursiveVariadicDefinition(args...); } } public: bool connect(const std::string &database) { if(connection.is_open())[[likely]]{ std::cout << "Database " << database << " was already open."; return true; } INFO << "Connecting on Database " << database; for (char i =3D 0; i < 3; i++) { try { std::string out =3D "user=3D" + user + " password=3D" + pass + " host= =3D" + addr + " port=3D" + p + " dbname=3Dpostgres" + " target_settion_attrs=3Dread-wri= te"; connection =3D pqxx::connection(out); if (connection.is_open())[[likely]]{ std::cout << "Opened database successfully: " << this->datab; datab =3D database; return true; } else { CUSTOM_THROW(1,"Can't open database") } } catch (const std::exception &e) { std::cerr << "connect on Database " << database << " failed= for this reason: " << e.what(); std::system("service postgresql restart"); std::cout << "Restart of database done!"; } } if(!connection.is_open())[[likely]]{ std::cerr << "Database " << database << " could finally not be connected to!"; exit(EXIT_FAILURE); } return false; } void disconnect() { connection.close(); } //this function creates a table and will also create the schema if it d= oes not exist template bool createTable(const std::string &schema, const std::string &table, c= onst std::string &pre_options, const std::string &options, Args &&... args) { if(!checkSchemaExists(schema))[[unlikely]]{ if(!createSchema(schema))[[unlikely]]{ std::cerr << "The following schema could not be created: " = << schema; exit(EXIT_FAILURE); } } if(checkTableExists(schema,table))[[likely]]{return false;} std::string sql =3D "CREATE "+pre_options+" TABLE "+options+" "+schema+"."+table+" ( "+createTableRecursiveVariadicDefinition(args...)+" ) ;"; while(boost::algorithm::contains(sql," ")){ custom_function::replace_string_occurencies(sql," "," "); } try{ pqxx::work n(connection); n.exec(sql); n.commit(); } catch (std::exception &e){ std::cerr << "createTable on (SQL command: " << sql << ") failed for this reason: " << e.what(); exit(EXIT_FAILURE); } return checkTableExists(schema,table); } /* * automatically open table and create scheme or table if it does not exists */ template bool openTable(const std::string &database, const std::string &schema, const std::string &table,Args &&...args) { if(!connect(database))[[unlikely]]{ std::cerr << "Could not connect to database and clName: " << database << " at " << schema << "." << table << " !!!"; std::exit(EXIT_FAILURE); } schem=3Dschema; tab=3Dtable; if (checkTableExists(schema,table))[[likely]]{ open =3D true; return open; } else{ open=3Dthis->createTable(schema,table,args...); if (!open){ std::cerr << "Cannot create tabel for open request (databas= e: "<< database << ", schema: " << schema << ", table: "<< table << ")"; return open; } return open; } } //check if the block can be reader bool check_block_exists(const std::string& identifier) { std::string sql =3D "SELECT identifier FROM " + schem + "." + tab += " WHERE identifier =3D decodeInit('"+ identifier + "', 'hex');"; custom_function::replace_string_occurencies(sql," "," "); pqxx::nontransaction nf(connection); pqxx::result rf(nf.exec(sql)); nf.commit(); if (rf.empty()) { return false; } return rf[0][0].as()=3D=3Didentifier; } //get the value of the sha id, so basically retrieve/return block std::string read_block(const std::string& identifier) { if(!check_block_exists(identifier))[[unlikely]]{ std::cerr << "The block "+identifier+"was not found on the database." << std::endl; std::exit(EXIT_FAILURE); } std::string sql =3D "SELECT identifier,block FROM " + schem + "." += tab + " WHERE identifier =3D decodeInit('" + identifier + "', 'hex');"; custom_function::replace_string_occurencies(sql," "," "); pqxx::nontransaction nf(connection); pqxx::result rf(nf.exec(sql)); nf.commit(); if(rf.size()>1){ std::cerr << "The block hash "+identifier+"was found multiple t= imes on the database." << std::endl; } return rf[0][1].as(); } //write block by setting a string to the sha_id bool write_block(const std::string& identifier, const std::string& bloc= k) { if(check_block_exists(identifier))[[unlikely]]{ std::cerr << "The block "+identifier+"was found on the database= and will be updated." << std::endl; } std::string sql =3D "INSERT INTO " + this->schem + "." + this->tab + " (identifier,block) VALUES (decodeInit('" + identifier +"', 'hex'), decodeInit('" + block +"', 'hex')) ON CONFLICT (identifier) DO UPDATE SET b= lock =3D excluded.block ;"; custom_function::replace_string_occurencies(sql," "," "); pqxx::work n2(connection); n2.exec(sql); n2.commit(); return true; } //auto create block table explicit database_call_ops(const std::string &db_config_file) {//: postgresSQL(db_config_file) { try{ std::filesystem::path config(db_config_file); config_files configuration =3D config_files(config); unsigned char count=3D0; for(auto &r:configuration.read()){ switch(count){ case 0:addr=3Dr;break; case 1:p=3Dr;break; case 2:user=3Dr;break; case 3:pass=3Dr;break; case 4:datab=3Dr;break; case 5:schem=3Dr;break; default:tab=3Dr;break; } count++; } std::cout << "Successfully reader Database configuration file at postgreSQL \'" << config.c_str() << "\' module." ; } catch (std::exception &e){ try{ std::fstream file; file.exceptions(std::ofstream::failbit | std::ofstream::badbit); file.open(db_config_file, std::ios_base::binary); (void) file.write(std::string().c_str(), 0); file.close(); std::cerr<<"Could not configure Database, because there was= a file error (check please) at postgreSQL \'config_database\' (address: "+add= r+", port: "+p+", user: "+user+", password: "+pass+") error: " << e.what(); std::cout<<"Created a new database config file at the spot = you chose. Hopefully this was not by accident so you should not forget to delete the file at the wrong spot."; } catch(std::exception& e){ std::cerr<<"Could not configure Database, because there was= a file error (check please) at postgreSQL \'config_database\' (address: "+add= r+", port: "+p+", user: "+user+", password: "+pass+") error: " << e.what(); std::exit(EXIT_FAILURE); } } if (!this->openTable(datab, schem, tab, "", "IF NOT EXISTS", "id", (unsigned long long int) 0, "GENERATED ALWAYS AS IDENTITY", "identifier", "bytea", "UNIQUE NOT NULL", "block", "bytea", "NOT NULL", "", "", "PRIMARY KEY(id)" )) { std::cerr << "Database table could not be created or opened!"; std::exit(EXIT_FAILURE); } } }; #endif //SCHOOL_PROJECT_DATABASE_CALL_OPS_H=