DatabaseCampaign: MySQL / concurrency fixes

According to
<http://dev.mysql.com/doc/refman/5.5/en/c-api-threaded-clients.html>,
a MySQL connection handle must not be used concurrently with an open
result set and mysql_use_result() in one thread
(DatabaseCampaign::run()), and mysql_query() in another
(DatabaseCampaign::collect_result_thread()).  This indeed leads to
crashes when bounding the outgoing job queue (SERVER_OUT_QUEUE_SIZE),
and maybe even more insidous effects in other cases.  The solution is
to create separate connections for both threads.

Additionally, call mysql_library_init() before spawning any threads.

Change-Id: I2981f2fdc67c9a2cbe8781f1a21654418f621aeb
This commit is contained in:
Horst Schirmeier
2013-12-02 19:33:24 +01:00
parent 0907dfb0ae
commit 33b63651ae
4 changed files with 41 additions and 12 deletions

View File

@ -92,6 +92,8 @@ bool DatabaseCampaign::run() {
log_send << "wait for the clients to complete" << std::endl;
campaignmanager.noMoreParameters();
delete db;
#ifndef __puma
collect_thread.join();
#endif
@ -101,12 +103,18 @@ bool DatabaseCampaign::run() {
void DatabaseCampaign::collect_result_thread() {
log_recv << "Started result receive thread" << std::endl;
// create an own DB connection, because we cannot use one concurrently
Database *db_recv = Database::cmdline_connect();
db_connect.set_insert_database_handle(db_recv);
ExperimentData *res;
while ((res = static_cast<ExperimentData *>(campaignmanager.getDone()))) {
db_connect.insert_row(&res->getMessage());
delete res;
}
delete db_recv;
}
bool DatabaseCampaign::run_variant(Database::Variant variant) {