diff --git a/middle-pgsql.cpp b/middle-pgsql.cpp index 8a7974ce0..e1377c3dd 100644 --- a/middle-pgsql.cpp +++ b/middle-pgsql.cpp @@ -1167,32 +1167,40 @@ middle_pgsql_t::~middle_pgsql_t() { } -std::shared_ptr middle_pgsql_t::get_instance() const { - middle_pgsql_t* mid = new middle_pgsql_t(); - mid->out_options = out_options; - mid->append = out_options->append; - mid->mark_pending = mark_pending; - - //NOTE: this is thread safe for use in pending async processing only because - //during that process they are only read from - mid->cache = cache; - mid->persistent_cache = persistent_cache; - - // We use a connection per table to enable the use of COPY */ - for(int i=0; i +middle_pgsql_t::get_query_instance(std::shared_ptr const &from) const +{ + auto *src = dynamic_cast(from.get()); + assert(src); + + // Return a copy of the original, as we need separate database connections. + std::unique_ptr mid(new middle_pgsql_t()); + mid->out_options = src->out_options; + mid->append = src->out_options->append; + mid->mark_pending = src->mark_pending; + + // NOTE: this is thread safe for use in pending async processing only because + // during that process they are only read from + mid->cache = src->cache; + mid->persistent_cache = src->persistent_cache; + + // We use a connection per table to enable the use of COPY + for (int i = 0; i < num_tables; i++) { mid->connect(mid->tables[i]); PGconn* sql_conn = mid->tables[i].sql_conn; - if (tables[i].prepare) { - pgsql_exec(sql_conn, PGRES_COMMAND_OK, "%s", tables[i].prepare); + if (mid->tables[i].prepare) { + pgsql_exec(sql_conn, PGRES_COMMAND_OK, "%s", + mid->tables[i].prepare); } - if (append && tables[i].prepare_intarray) { - pgsql_exec(sql_conn, PGRES_COMMAND_OK, "%s", tables[i].prepare_intarray); + if (mid->append && mid->tables[i].prepare_intarray) { + pgsql_exec(sql_conn, PGRES_COMMAND_OK, "%s", + mid->tables[i].prepare_intarray); } } - return std::shared_ptr(mid); + return std::shared_ptr(mid.release()); } size_t middle_pgsql_t::pending_count() const { diff --git a/middle-pgsql.hpp b/middle-pgsql.hpp index 642fece98..bef949af9 100644 --- a/middle-pgsql.hpp +++ b/middle-pgsql.hpp @@ -79,7 +79,9 @@ struct middle_pgsql_t : public slim_middle_t { struct pg_conn *sql_conn; }; - std::shared_ptr get_instance() const override; + std::shared_ptr + get_query_instance(std::shared_ptr const &mid) const override; + private: void pgsql_stop_one(table_desc *table); diff --git a/middle-ram.cpp b/middle-ram.cpp index 7a56466ba..929f7920b 100644 --- a/middle-ram.cpp +++ b/middle-ram.cpp @@ -198,18 +198,9 @@ idlist_t middle_ram_t::relations_using_way(osmid_t) const "report it at https://github.com/openstreetmap/osm2pgsql/issues"); } -namespace { - -void no_delete(const middle_ram_t *) +std::shared_ptr +middle_ram_t::get_query_instance(std::shared_ptr const &mid) const { - // boost::shared_ptr thinks we are going to delete - // the middle object, but we are not. Heh heh heh. - // So yeah, this is a hack... -} - -} - -std::shared_ptr middle_ram_t::get_instance() const { - //shallow copy here because readonly access is thread safe - return std::shared_ptr(this, no_delete); + // No copy here because readonly access is thread safe. + return std::static_pointer_cast(mid); } diff --git a/middle-ram.hpp b/middle-ram.hpp index 268b60fde..c36480b1d 100644 --- a/middle-ram.hpp +++ b/middle-ram.hpp @@ -115,7 +115,9 @@ struct middle_ram_t : public middle_t { size_t pending_count() const override; - std::shared_ptr get_instance() const override; + std::shared_ptr + get_query_instance(std::shared_ptr const &mid) const override; + private: void release_ways(); diff --git a/middle.hpp b/middle.hpp index 9439d905d..ab2e91851 100644 --- a/middle.hpp +++ b/middle.hpp @@ -73,8 +73,6 @@ struct middle_query_t { * \param way_id ID of the way to check */ virtual idlist_t relations_using_way(osmid_t way_id) const = 0; - - virtual std::shared_ptr get_instance() const = 0; }; /** @@ -108,6 +106,9 @@ struct middle_t : public middle_query_t { virtual size_t pending_count() const = 0; + virtual std::shared_ptr + get_query_instance(std::shared_ptr const &mid) const = 0; + const options_t* out_options; }; diff --git a/osmdata.cpp b/osmdata.cpp index ddc1dd4db..e0a2a23f7 100644 --- a/osmdata.cpp +++ b/osmdata.cpp @@ -188,7 +188,7 @@ namespace { struct pending_threaded_processor : public middle_t::pending_processor { typedef std::vector> output_vec_t; - typedef std::pair, output_vec_t> clone_t; + typedef std::pair, output_vec_t> clone_t; static void do_jobs(output_vec_t const& outputs, pending_queue_t& queue, size_t& ids_done, std::mutex& mutex, int append, bool ways) { while (true) { @@ -232,7 +232,7 @@ struct pending_threaded_processor : public middle_t::pending_processor { } //starts up count threads and works on the queue - pending_threaded_processor(std::shared_ptr mid, + pending_threaded_processor(std::shared_ptr mid, const output_vec_t &outs, size_t thread_count, int append) //note that we cant hint to the stack how large it should be ahead of time @@ -249,7 +249,7 @@ struct pending_threaded_processor : public middle_t::pending_processor { clones.reserve(thread_count); for (size_t i = 0; i < thread_count; ++i) { //clone the middle - std::shared_ptr mid_clone = mid->get_instance(); + auto mid_clone = mid->get_query_instance(mid); //clone the outs output_vec_t out_clones; diff --git a/tests/mockups.hpp b/tests/mockups.hpp index 3a52a4122..b11cfd148 100644 --- a/tests/mockups.hpp +++ b/tests/mockups.hpp @@ -35,9 +35,10 @@ struct dummy_middle_t : public middle_t { idlist_t relations_using_way(osmid_t) const override { return idlist_t(); } - std::shared_ptr get_instance() const override + std::shared_ptr + get_query_instance(std::shared_ptr const &mid) const override { - return std::shared_ptr(); + return std::shared_ptr(); } }; @@ -72,7 +73,11 @@ struct dummy_slim_middle_t : public slim_middle_t { idlist_t relations_using_way(osmid_t) const override { return idlist_t(); } - std::shared_ptr get_instance() const override {return std::shared_ptr();} + std::shared_ptr + get_query_instance(std::shared_ptr const &mid) const override + { + return std::shared_ptr(); + } void nodes_delete(osmid_t) override {}; void node_changed(osmid_t) override {};