3555 John David Duncan 2011-09-26
Fix for race condition in ndb/memcache S scheduler.
It was possible for an ndb_send_thread to start up and try to use a WorkerConnection that the main thread had not yet initialized.
This should fix http://pb2.no.oracle.com/?template=mysql_show_test_failure&search=yes&push_id=2586144&test_id=2586293&test_run=n_mix&test_suite=ndb_memcache&test_case=basic
modified:
storage/ndb/memcache/src/schedulers/S_sched.cc
storage/ndb/memcache/src/schedulers/S_sched.h
3554 John David Duncan 2011-09-25
work on const-conversion issues found by stricter compiler
modified:
storage/ndb/memcache/include/DataTypeHandler.h
storage/ndb/memcache/src/DataTypeHandler.cc
storage/ndb/memcache/src/Record.cc
=== modified file 'storage/ndb/memcache/src/schedulers/S_sched.cc'
--- a/storage/ndb/memcache/src/schedulers/S_sched.cc 2011-09-22 18:27:10 +0000
+++ b/storage/ndb/memcache/src/schedulers/S_sched.cc 2011-09-26 21:12:27 +0000
@@ -95,6 +95,10 @@ void S::SchedulerGlobal::init(int _nthre
* wc_cell = new WorkerConnection(this, t, c);
}
}
+
+ /* Start the send & poll threads for each connection */
+ for(int i = 0 ; i < nclusters ; i++)
+ clusters[i]->startThreads();
/* Log message for startup */
logger->log(LOG_WARNING, 0, "Scheduler: starting for %d cluster%s; "
@@ -430,7 +434,8 @@ void S::SchedulerWorker::add_stats(const
/* Cluster methods */
S::Cluster::Cluster(SchedulerGlobal *global, int _id) :
cluster_id(_id),
- nreferences(0)
+ nreferences(0),
+ threads_started(false)
{
DEBUG_PRINT("%d", cluster_id);
@@ -478,6 +483,18 @@ S::Cluster::Cluster(SchedulerGlobal *glo
}
+void S::Cluster::startThreads() {
+ /* Threads are started only once and persist across reconfiguration.
+ But, this method will be called again for each reconf. */
+ if(threads_started == false) {
+ for(int i = 0 ; i < nconnections; i++) {
+ connections[i]->startThreads();
+ }
+ threads_started = true;
+ }
+}
+
+
S::Cluster::~Cluster() {
DEBUG_PRINT("Shutting down cluster %d", cluster_id);
for(int i = 0; i < nconnections ; i++) {
@@ -626,14 +643,17 @@ S::Connection::Connection(S::Cluster & _
/* Initialize the queues for sent and resceduled items */
sentqueue = new Queue<NdbInstance>(nInst);
reschedulequeue = new Queue<NdbInstance>(nInst);
-
+}
+
+
+void S::Connection::startThreads() {
/* Start the poll thread */
pthread_create( & poll_thread_id, NULL, run_poll_thread, (void *) this);
-
+
/* Start the send thread */
pthread_create( & send_thread_id, NULL, run_send_thread, (void *) this);
}
-
+
S::Connection::~Connection() {
/* Shut down a connection.
=== modified file 'storage/ndb/memcache/src/schedulers/S_sched.h'
--- a/storage/ndb/memcache/src/schedulers/S_sched.h 2011-09-12 10:05:07 +0000
+++ b/storage/ndb/memcache/src/schedulers/S_sched.h 2011-09-26 21:12:27 +0000
@@ -121,7 +121,9 @@ public:
~Cluster();
void add_stats(const char *, ADD_STAT, const void *);
WorkerConnection ** getWorkerConnectionPtr(int thd) const;
+ void startThreads();
+ bool threads_started;
int cluster_id;
int nconnections;
int nreferences;
@@ -140,6 +142,10 @@ public:
Connection(Cluster &, int connection_id);
~Connection();
void add_stats(const char *, ADD_STAT, const void *);
+ void startThreads();
+
+ /* These are not intended to be part of the public API, but are marked as
+ public so that they can be called from C code in pthread_create(): */
void * run_ndb_send_thread();
void * run_ndb_poll_thread();
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.5-cluster branch (john.duncan:3554 to 3555) | John David Duncan | 28 Sep |