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:
@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user