From: John David Duncan Date: September 26 2011 9:16pm Subject: bzr push into mysql-5.5-cluster branch (john.duncan:3554 to 3555) List-Archive: http://lists.mysql.com/commits/141147 Message-Id: <201109262116.p8QLGJOh017769@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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(nInst); reschedulequeue = new Queue(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).