List:Commits« Previous MessageNext Message »
From:Jonas Oreland Date:September 28 2011 10:32am
Subject:bzr push into mysql-5.1-telco-7.1 branch (jonas.oreland:4293 to 4294)
View as plain text  
 4294 Jonas Oreland	2011-09-28 [merge]
      ndb - merge 70 to 71

    added:
      storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.cpp
      storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.h
    modified:
      mysql-test/suite/ndb_binlog/t/ndb_binlog_log_transaction_id-master.opt
      mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_trans.cnf
      storage/ndb/include/portlib/NdbMutex.h
      storage/ndb/src/common/portlib/CMakeLists.txt
      storage/ndb/src/common/portlib/Makefile.am
      storage/ndb/src/common/portlib/NdbCondition.c
      storage/ndb/src/common/portlib/NdbMutex.c
      storage/ndb/src/common/portlib/NdbThread.c
      storage/ndb/src/common/util/ndb_init.cpp
      storage/ndb/src/kernel/vm/ArrayPool.hpp
      storage/ndb/src/kernel/vm/Emulator.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/test/ndbapi/testNdbApi.cpp
      storage/ndb/test/ndbapi/testRestartGci.cpp
      storage/ndb/test/ndbapi/test_event.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/tools/hugoJoin.cpp
 4293 Craig L Russell	2011-09-26
      Add support for value handling for jdbc 5.1.17

    added:
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ValueHandlerBatching.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ValueHandlerBindValuesImpl.java
    modified:
      storage/ndb/clusterj/clusterj-jdbc/Makefile.am
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/InterceptorImpl.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/QueryExecutionContextJDBCImpl.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/SQLExecutor.java
      storage/ndb/clusterj/clusterj-jdbc/src/main/java/com/mysql/clusterj/jdbc/ValueHandlerImpl.java
      storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/BatchDeleteQueryAllPrimitivesTest.java
      storage/ndb/clusterj/clusterj-jdbc/src/test/java/jdbctest/BigIntegerTypesTest.java
      storage/ndb/clusterj/clusterj-jdbc/src/test/resources/clusterj.properties
=== modified file 'mysql-test/suite/ndb_binlog/t/ndb_binlog_log_transaction_id-master.opt'
--- a/mysql-test/suite/ndb_binlog/t/ndb_binlog_log_transaction_id-master.opt	2011-09-07 22:50:01 +0000
+++ b/mysql-test/suite/ndb_binlog/t/ndb_binlog_log_transaction_id-master.opt	2011-09-28 09:40:14 +0000
@@ -1 +1 @@
---ndb-log-transaction-id
+--ndb-log-transaction-id --log-bin-use-v1-row-events=false

=== modified file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_trans.cnf'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_trans.cnf	2011-09-07 22:50:01 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_trans.cnf	2011-09-28 09:40:14 +0000
@@ -11,10 +11,14 @@
 # Potential infinite loops are broken by both servers
 # on each cluster having the same server-id
 
+[cluster_config.slave]
+mysqld=,
+
 [mysqld]
 log-slave-updates
 ndb-log-apply-status
 ndb-log-transaction-id
+log-bin-use-v1-row-events=false
 
 [mysqld.1.1]
 server-id= 1

=== modified file 'storage/ndb/include/portlib/NdbMutex.h'
--- a/storage/ndb/include/portlib/NdbMutex.h	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/include/portlib/NdbMutex.h	2011-09-28 10:18:35 +0000
@@ -29,11 +29,12 @@ extern "C" {
 #else
 #include <pthread.h>
 #endif
-#ifndef NDB_MUTEX_STAT
+#if !defined NDB_MUTEX_STAT && !defined NDB_MUTEX_DEADLOCK_DETECTOR
 typedef pthread_mutex_t NdbMutex;
 #else
 typedef struct {
   pthread_mutex_t mutex;
+#ifdef NDB_MUTEX_STAT
   unsigned cnt_lock;
   unsigned cnt_lock_contention;
   unsigned cnt_trylock_ok;
@@ -46,6 +47,10 @@ typedef struct {
   unsigned long long max_hold_time_ns;
   unsigned long long lock_start_time_ns;
   char name[32];
+#endif
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  struct ndb_mutex_state * m_mutex_state;
+#endif
 } NdbMutex;
 #endif
 

=== modified file 'storage/ndb/src/common/portlib/CMakeLists.txt'
--- a/storage/ndb/src/common/portlib/CMakeLists.txt	2011-07-04 16:30:34 +0000
+++ b/storage/ndb/src/common/portlib/CMakeLists.txt	2011-09-28 10:18:35 +0000
@@ -27,7 +27,7 @@ ADD_CONVENIENCE_LIBRARY(ndbportlib
             NdbEnv.c NdbThread.c NdbHost.c NdbTCP.cpp
             NdbMem.c NdbConfig.c NdbTick.c NdbDir.cpp
             ndb_daemon.cc ${EXTRA_SRC}
-            NdbNuma.cpp)
+            NdbNuma.cpp NdbMutex_DeadlockDetector.cpp)
 TARGET_LINK_LIBRARIES(ndbportlib mysys ${LIBSOCKET})
 
 ADD_EXECUTABLE(NdbDir-t

=== modified file 'storage/ndb/src/common/portlib/Makefile.am'
--- a/storage/ndb/src/common/portlib/Makefile.am	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/common/portlib/Makefile.am	2011-09-27 17:28:13 +0000
@@ -21,7 +21,8 @@ libportlib_la_SOURCES = \
 	NdbCondition.c NdbMutex.c NdbTick.c \
 	NdbEnv.c NdbThread.c NdbHost.c NdbTCP.cpp	    \
 	ndb_daemon.cc NdbMem.c \
-	NdbConfig.c NdbDir.cpp ndb_socket.cpp
+	NdbConfig.c NdbDir.cpp ndb_socket.cpp \
+        NdbMutex_DeadlockDetector.cpp
 
 include $(top_srcdir)/storage/ndb/config/common.mk.am
 include $(top_srcdir)/storage/ndb/config/type_util.mk.am

=== modified file 'storage/ndb/src/common/portlib/NdbCondition.c'
--- a/storage/ndb/src/common/portlib/NdbCondition.c	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/src/common/portlib/NdbCondition.c	2011-09-28 10:18:35 +0000
@@ -27,6 +27,10 @@ static int init = 0;
 static int clock_id = CLOCK_REALTIME;
 #endif
 
+#if defined NDB_MUTEX_STAT || defined NDB_MUTEX_DEADLOCK_DETECTOR
+#define NDB_MUTEX_STRUCT
+#endif
+
 void
 NdbCondition_initialize(int need_monotonic)
 {
@@ -129,7 +133,7 @@ NdbCondition_Wait(struct NdbCondition* p
   if (p_cond == NULL || p_mutex == NULL)
     return 1;
   
-#ifdef NDB_MUTEX_STAT
+#ifdef NDB_MUTEX_STRUCT
   result = pthread_cond_wait(&p_cond->cond, &p_mutex->mutex);
 #else
   result = pthread_cond_wait(&p_cond->cond, p_mutex);
@@ -187,17 +191,23 @@ NdbCondition_WaitTimeoutAbs(struct NdbCo
                             const struct timespec * abstime)
 {
 #ifdef NDB_WIN
+  /**
+   * mysys windows wrapper of pthread_cond_timedwait
+   *   does not have a const argument for the timespec
+   */
   struct timespec tmp = *abstime;
-  abstime = &tmp;
+  struct timespec * waitarg = &tmp;
+#else
+  const struct timespec * waitarg = abstime;
 #endif
 
   if (p_cond == NULL || p_mutex == NULL)
     return 1;
 
-#ifdef NDB_MUTEX_STAT
-  return pthread_cond_timedwait(&p_cond->cond, &p_mutex->mutex, abstime);
+#ifdef NDB_MUTEX_STRUCT
+  return pthread_cond_timedwait(&p_cond->cond, &p_mutex->mutex, waitarg);
 #else
-  return pthread_cond_timedwait(&p_cond->cond, p_mutex, abstime);
+  return pthread_cond_timedwait(&p_cond->cond, p_mutex, waitarg);
 #endif
 }
 

=== modified file 'storage/ndb/src/common/portlib/NdbMutex.c'
--- a/storage/ndb/src/common/portlib/NdbMutex.c	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/src/common/portlib/NdbMutex.c	2011-09-28 10:18:35 +0000
@@ -21,10 +21,34 @@
 #include <NdbMutex.h>
 #include <NdbMem.h>
 
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+#include "NdbMutex_DeadlockDetector.h"
+#endif
+
 #ifdef NDB_MUTEX_STAT
 static FILE * statout = 0;
 #endif
 
+#if defined NDB_MUTEX_STAT || defined NDB_MUTEX_DEADLOCK_DETECTOR
+#define NDB_MUTEX_STRUCT
+#endif
+
+void
+NdbMutex_SysInit()
+{
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  NdbMutex_DeadlockDetectorInit();
+#endif
+}
+
+void
+NdbMutex_SysEnd()
+{
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  NdbMutex_DeadlockDetectorEnd();
+#endif
+}
+
 NdbMutex* NdbMutex_Create()
 {
   return NdbMutex_CreateWithName(0);
@@ -59,12 +83,15 @@ int NdbMutex_InitWithName(NdbMutex* pNdb
   int result;
   pthread_mutex_t * p;
   DBUG_ENTER("NdbMutex_Init");
+  (void)name;
 
-#ifdef NDB_MUTEX_STAT
+#ifdef NDB_MUTEX_STRUCT
   bzero(pNdbMutex, sizeof(NdbMutex));
+  p = &pNdbMutex->mutex;
+
+#ifdef NDB_MUTEX_STAT
   pNdbMutex->min_lock_wait_time_ns = ~(Uint64)0;
   pNdbMutex->min_hold_time_ns = ~(Uint64)0;
-  p = &pNdbMutex->mutex;
   if (name == 0)
   {
     snprintf(pNdbMutex->name, sizeof(pNdbMutex->name), "%p",
@@ -79,9 +106,10 @@ int NdbMutex_InitWithName(NdbMutex* pNdb
   {
     statout = stdout;
   }
+#endif
+
 #else
   p = pNdbMutex;
-  (void)name;
 #endif
 
 #if defined(VM_TRACE) && \
@@ -99,6 +127,13 @@ int NdbMutex_InitWithName(NdbMutex* pNdb
 #else
   result = pthread_mutex_init(p, 0);
 #endif
+
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  if (result == 0)
+  {
+    ndb_mutex_created(pNdbMutex);
+  }
+#endif
   DBUG_RETURN(result);
 }
 
@@ -109,7 +144,11 @@ int NdbMutex_Destroy(NdbMutex* p_mutex)
   if (p_mutex == NULL)
     return -1;
 
-#ifdef NDB_MUTEX_STAT
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  ndb_mutex_destoyed(p_mutex);
+#endif
+
+#ifdef NDB_MUTEX_STRUCT
   result = pthread_mutex_destroy(&p_mutex->mutex);
 #else
   result = pthread_mutex_destroy(p_mutex);
@@ -201,11 +240,17 @@ int NdbMutex_Lock(NdbMutex* p_mutex)
     p_mutex->cnt_lock++;
     p_mutex->lock_start_time_ns = stop;
   }
+#elif defined NDB_MUTEX_STRUCT
+  result = pthread_mutex_lock(&p_mutex->mutex);
 #else
   result = pthread_mutex_lock(p_mutex);
 #endif
   assert(result == 0);
 
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  ndb_mutex_locked(p_mutex);
+#endif
+
   return result;
 }
 
@@ -234,11 +279,17 @@ int NdbMutex_Unlock(NdbMutex* p_mutex)
       dumpstat(p_mutex);
     }
   }
+#elif defined NDB_MUTEX_STRUCT
+  result = pthread_mutex_unlock(&p_mutex->mutex);
 #else
   result = pthread_mutex_unlock(p_mutex);
 #endif
   assert(result == 0);
 
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  ndb_mutex_unlocked(p_mutex);
+#endif
+
   return result;
 }
 
@@ -261,11 +312,21 @@ int NdbMutex_Trylock(NdbMutex* p_mutex)
   {
     __sync_fetch_and_add(&p_mutex->cnt_trylock_nok, 1);
   }
+#elif defined NDB_MUTEX_STRUCT
+  result = pthread_mutex_trylock(&p_mutex->mutex);
 #else
   result = pthread_mutex_trylock(p_mutex);
 #endif
   assert(result == 0 || result == EBUSY);
 
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  if (result == 0)
+  {
+    ndb_mutex_try_locked(p_mutex);
+  }
+#endif
+
+
   return result;
 }
 

=== added file 'storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.cpp'
--- a/storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.cpp	2011-09-27 17:28:13 +0000
@@ -0,0 +1,422 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+#include <NdbMutex.h>
+#include <NdbThread.h>
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+
+#include "NdbMutex_DeadlockDetector.h"
+
+#define NDB_THREAD_TLS_SELF NDB_THREAD_TLS_MAX
+
+static NdbMutex g_mutex_no_mutex; // We need a mutex to assign numbers to mutexes...
+static nmdd_mask g_mutex_no_mask = { 0, 0 };
+
+static unsigned alloc_mutex_no();
+static void release_mutex_no(unsigned no);
+
+static NdbMutex* get_element(struct nmdd_mutex_array *, unsigned i);
+static void add_mutex_to_array(struct nmdd_mutex_array *, NdbMutex*);
+static void remove_mutex_from_array(struct nmdd_mutex_array *, NdbMutex*);
+
+static void set_bit(struct nmdd_mask *, unsigned no);
+static void clear_bit(struct nmdd_mask* , unsigned no);
+static bool check_bit(const struct nmdd_mask* , unsigned no);
+
+static void release(struct nmdd_mutex_array *);
+static void release(struct nmdd_mask*);
+
+extern "C"
+void
+NdbMutex_DeadlockDetectorInit()
+{
+  NdbMutex_Init(&g_mutex_no_mutex);
+}
+
+extern "C"
+void
+NdbMutex_DeadlockDetectorEnd()
+{
+  release(&g_mutex_no_mask);
+}
+
+extern "C"
+void
+ndb_mutex_created(NdbMutex* p)
+{
+  p->m_mutex_state = (ndb_mutex_state*)malloc(sizeof(ndb_mutex_state));
+  bzero(p->m_mutex_state, sizeof(ndb_mutex_state));
+
+  /**
+   * Assign mutex no
+   */
+  p->m_mutex_state->m_no = alloc_mutex_no();
+}
+
+extern "C"
+void
+ndb_mutex_destoyed(NdbMutex* p)
+{
+  unsigned no = p->m_mutex_state->m_no;
+
+  /**
+   * In order to be able to reuse mutex_no,
+   *   we need to clear this no from all mutexes that has it in before map...
+   *   this is all mutexes in after map
+   */
+  for (unsigned i = 0; i<p->m_mutex_state->m_locked_after_list.m_used; i++)
+  {
+    NdbMutex * m = get_element(&p->m_mutex_state->m_locked_after_list, i);
+    assert(check_bit(&p->m_mutex_state->m_locked_after_mask, m->m_mutex_state->m_no));
+
+    /**
+     * And we need to lock it while doing this
+     */
+    NdbMutex_Lock(m);
+    assert(check_bit(&m->m_mutex_state->m_locked_before_mask, no));
+    clear_bit(&m->m_mutex_state->m_locked_before_mask, no);
+    remove_mutex_from_array(&m->m_mutex_state->m_locked_before_list, p);
+    NdbMutex_Unlock(m);
+  }
+
+  /**
+   * And we need to remove ourselfs from after list of mutexes in out before list
+   */
+  for (unsigned i = 0; i<p->m_mutex_state->m_locked_before_list.m_used; i++)
+  {
+    NdbMutex * m = get_element(&p->m_mutex_state->m_locked_before_list, i);
+    NdbMutex_Lock(m);
+    assert(check_bit(&m->m_mutex_state->m_locked_after_mask, no));
+    clear_bit(&m->m_mutex_state->m_locked_after_mask, no);
+    remove_mutex_from_array(&m->m_mutex_state->m_locked_after_list, p);
+    NdbMutex_Unlock(m);
+  }
+
+  release(&p->m_mutex_state->m_locked_before_mask);
+  release(&p->m_mutex_state->m_locked_before_list);
+  release(&p->m_mutex_state->m_locked_after_mask);
+  release(&p->m_mutex_state->m_locked_after_list);
+  release_mutex_no(no);
+}
+
+static
+ndb_mutex_thr_state*
+get_thr()
+{
+  void * p = NdbThread_GetTlsKey(NDB_THREAD_TLS_SELF);
+  return (ndb_mutex_thr_state*)p;
+}
+
+#define INC_SIZE 16
+
+static
+void
+add_lock_to_thread(ndb_mutex_thr_state * t, NdbMutex * m)
+{
+  add_mutex_to_array(&t->m_mutexes_locked, m);
+}
+
+static
+void
+add_lock_to_mutex_before_list(ndb_mutex_state * m1, NdbMutex * m2)
+{
+  assert(m1 != m2->m_mutex_state);
+  unsigned no = m2->m_mutex_state->m_no;
+  if (!check_bit(&m1->m_locked_before_mask, no))
+  {
+    set_bit(&m1->m_locked_before_mask, no);
+    add_mutex_to_array(&m1->m_locked_before_list, m2);
+  }
+}
+
+static
+void
+add_lock_to_mutex_after_list(ndb_mutex_state * m1, NdbMutex* m2)
+{
+  assert(m1 != m2->m_mutex_state);
+  unsigned no = m2->m_mutex_state->m_no;
+  if (!check_bit(&m1->m_locked_after_mask, no))
+  {
+    set_bit(&m1->m_locked_after_mask, no);
+    add_mutex_to_array(&m1->m_locked_after_list, m2);
+  }
+}
+
+extern "C"
+void
+ndb_mutex_locked(NdbMutex* p)
+{
+  ndb_mutex_state * m = p->m_mutex_state;
+  ndb_mutex_thr_state * thr = get_thr();
+  if (thr == 0)
+  {
+    /**
+     * These are threads not started with NdbThread_Create(...)
+     *   e.g mysql-server threads...ignore these for now
+     */
+    return;
+  }
+
+  for (unsigned i = 0; i < thr->m_mutexes_locked.m_used; i++)
+  {
+    /**
+     * We want to lock m
+     * Check that none of the mutex we curreny have locked
+     *   have m in their *before* list
+     */
+    NdbMutex * h = get_element(&thr->m_mutexes_locked, i);
+    if (check_bit(&h->m_mutex_state->m_locked_before_mask, m->m_no))
+    {
+      abort();
+    }
+
+    /**
+     * Add h to m's list of before-locks
+     */
+    add_lock_to_mutex_before_list(m, h);
+
+    /**
+     * Add m to h's list of after locks
+     */
+    add_lock_to_mutex_after_list(h->m_mutex_state, p);
+  }
+
+  add_lock_to_thread(thr, p);
+}
+
+extern "C"
+void
+ndb_mutex_unlocked(NdbMutex* m)
+{
+  ndb_mutex_thr_state * thr = get_thr();
+  if (thr == 0)
+  {
+    /**
+     * These are threads not started with NdbThread_Create(...)
+     *   e.g mysql-server threads...ignore these for now
+     */
+    return;
+  }
+  unsigned pos = thr->m_mutexes_locked.m_used;
+  assert(pos > 0);
+  assert(get_element(&thr->m_mutexes_locked, pos-1) == m);
+  thr->m_mutexes_locked.m_used --;
+}
+
+extern "C"
+void
+ndb_mutex_try_locked(NdbMutex* p)
+{
+
+}
+
+extern "C"
+void
+ndb_mutex_thread_init(struct ndb_mutex_thr_state* p)
+{
+  bzero(p, sizeof(* p));
+  NdbThread_SetTlsKey(NDB_THREAD_TLS_SELF, p);
+}
+
+extern "C"
+void
+ndb_mutex_thread_exit()
+{
+  ndb_mutex_thr_state * thr = get_thr();
+  if (thr == 0)
+  {
+    /**
+     * These are threads not started with NdbThread_Create(...)
+     *   e.g mysql-server threads...ignore these for now
+     */
+    return;
+  }
+  release(&thr->m_mutexes_locked);
+}
+
+/**
+ * util
+ */
+static
+void
+set_bit(nmdd_mask * mask, unsigned no)
+{
+  unsigned byte_no = no / 8;
+  unsigned bit_no = no & 7;
+  if (byte_no >= mask->m_len)
+  {
+    unsigned new_len = mask->m_len + INC_SIZE;
+    if (byte_no >= new_len)
+    {
+      new_len = byte_no + 1;
+    }
+    unsigned char * new_arr = (unsigned char*)malloc(new_len);
+    bzero(new_arr, new_len);
+    if (mask->m_len != 0)
+    {
+      memcpy(new_arr, mask->m_mask, mask->m_len);
+      free(mask->m_mask);
+    }
+    mask->m_len = new_len;
+    mask->m_mask = new_arr;
+  }
+
+  mask->m_mask[byte_no] |= (1 << bit_no);
+}
+
+static
+void
+clear_bit(nmdd_mask * mask, unsigned no)
+{
+  unsigned byte_no = no / 8;
+  unsigned bit_no = no & 7;
+  if (byte_no >= mask->m_len)
+  {
+    return;
+  }
+
+  mask->m_mask[byte_no] &= ~(unsigned char)(1 << bit_no);
+}
+
+static
+bool
+check_bit(const nmdd_mask * mask, unsigned no)
+{
+  unsigned byte_no = no / 8;
+  unsigned bit_no = no & 7;
+  if (byte_no >= mask->m_len)
+  {
+    return false;
+  }
+
+  return (mask->m_mask[byte_no] & (1 << bit_no)) != 0;
+}
+
+static
+void
+release(nmdd_mask * mask)
+{
+  if (mask->m_len != 0)
+  {
+    free(mask->m_mask);
+  }
+}
+
+static
+NdbMutex*
+get_element(nmdd_mutex_array* arr, unsigned i)
+{
+  assert(i < arr->m_used);
+  return arr->m_array[i];
+}
+
+static
+void
+add_mutex_to_array(nmdd_mutex_array* arr, NdbMutex* m)
+{
+  unsigned pos = arr->m_used;
+  if (arr->m_used == arr->m_array_len)
+  {
+    unsigned new_len = arr->m_array_len + INC_SIZE;
+    NdbMutex** new_arr = (NdbMutex**)malloc(new_len * sizeof(NdbMutex*));
+    if (arr->m_array_len != 0)
+    {
+      memcpy(new_arr, arr->m_array, arr->m_array_len * sizeof(NdbMutex*));
+      free(arr->m_array);
+    }
+    arr->m_array = new_arr;
+    arr->m_array_len = new_len;
+  }
+  for (unsigned i = 0; i<arr->m_used; i++)
+    assert(arr->m_array[i] != m);
+
+  arr->m_array[pos] = m;
+  arr->m_used++;
+}
+
+static
+void
+remove_mutex_from_array(nmdd_mutex_array* arr, NdbMutex* m)
+{
+  for (unsigned i = 0; i < arr->m_used; i++)
+  {
+    unsigned idx = arr->m_used - i - 1;
+    if (arr->m_array[idx] == m)
+    {
+      memmove(arr->m_array+idx,
+              arr->m_array + idx + 1,
+              i * sizeof(NdbMutex*));
+      arr->m_used--;
+      return;
+    }
+  }
+  assert(false);
+}
+
+static
+void
+release(nmdd_mutex_array* arr)
+{
+  if (arr->m_array_len)
+  {
+    free(arr->m_array);
+  }
+}
+
+static
+unsigned
+ff(unsigned char b)
+{
+  for (unsigned i = 0; i<8; i++)
+    if ((b & (1 << i)) == 0)
+      return i;
+  assert(false);
+}
+
+static
+unsigned
+alloc_mutex_no()
+{
+  Guard g(&g_mutex_no_mutex);
+  unsigned no = 0;
+
+  for (unsigned i = 0; i < g_mutex_no_mask.m_len; i++)
+  {
+    if (g_mutex_no_mask.m_mask[i] != 255)
+    {
+      no = (8 * i) + ff(g_mutex_no_mask.m_mask[i]);
+      goto found;
+    }
+  }
+
+  no = 8 * g_mutex_no_mask.m_len;
+found:
+  set_bit(&g_mutex_no_mask, no);
+  assert(check_bit(&g_mutex_no_mask, no));
+  return no;
+}
+
+static
+void
+release_mutex_no(unsigned no)
+{
+  Guard g(&g_mutex_no_mutex);
+  assert(check_bit(&g_mutex_no_mask, no));
+  clear_bit(&g_mutex_no_mask, no);
+}
+
+#endif

=== added file 'storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.h'
--- a/storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.h	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/common/portlib/NdbMutex_DeadlockDetector.h	2011-09-27 17:28:13 +0000
@@ -0,0 +1,73 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+#ifndef NDB_MUTEX_DEADLOCK_DETECTOR_H
+#define NDB_MUTEX_DEADLOCK_DETECTOR_H
+
+#include <NdbMutex.h>
+
+struct nmdd_mask
+{
+  unsigned char * m_mask;
+  unsigned m_len;
+};
+
+struct nmdd_mutex_array
+{
+  NdbMutex ** m_array;
+  unsigned m_used;
+  unsigned m_array_len;
+};
+
+struct ndb_mutex_state
+{
+  struct nmdd_mask m_locked_before_mask; /* mutexes held when locking this mutex */
+  struct nmdd_mutex_array m_locked_before_list; /* mutexes held when locking this mutex */
+
+  struct nmdd_mutex_array m_locked_after_list; /* mutexes locked when holding this mutex*/
+  struct nmdd_mask m_locked_after_mask;        /* mask (for quick check) */
+
+  unsigned m_no; /* my mutex "id" (for access in masks) */
+};
+
+struct ndb_mutex_thr_state
+{
+  struct nmdd_mutex_array m_mutexes_locked;
+};
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+  void NdbMutex_DeadlockDetectorInit();
+  void NdbMutex_DeadlockDetectorEnd();
+
+  void ndb_mutex_created(NdbMutex*);
+  void ndb_mutex_destoyed(NdbMutex*);
+  void ndb_mutex_locked(NdbMutex*);
+  void ndb_mutex_unlocked(NdbMutex*);
+  void ndb_mutex_try_locked(NdbMutex*);
+
+  void ndb_mutex_thread_init(struct ndb_mutex_thr_state*);
+  void ndb_mutex_thread_exit();
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#endif

=== modified file 'storage/ndb/src/common/portlib/NdbThread.c'
--- a/storage/ndb/src/common/portlib/NdbThread.c	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/common/portlib/NdbThread.c	2011-09-27 17:28:13 +0000
@@ -38,6 +38,10 @@
 #include <sys/procset.h>
 #endif
 
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+#include "NdbMutex_DeadlockDetector.h"
+#endif
+
 static int g_min_prio = 0;
 static int g_max_prio = 0;
 static int g_prio = 0;
@@ -65,6 +69,9 @@ struct NdbThread
   char thread_name[16];
   NDB_THREAD_FUNC * func;
   void * object;
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  struct ndb_mutex_thr_state m_mutex_thr_state;
+#endif
 };
 
 #ifdef NDB_SHM_TRANSPORTER
@@ -141,6 +148,11 @@ ndb_thread_wrapper(void* _ss){
       void *ret;
       struct NdbThread * ss = (struct NdbThread *)_ss;
       settid(ss);
+
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+      ndb_mutex_thread_init(&ss->m_mutex_thr_state);
+#endif
+
       NdbMutex_Lock(g_ndb_thread_mutex);
       ss->inited = 1;
       NdbCondition_Signal(g_ndb_thread_condition);
@@ -154,6 +166,7 @@ ndb_thread_wrapper(void* _ss){
   }
 }
 
+static struct NdbThread* g_main_thread = 0;
 
 struct NdbThread*
 NdbThread_CreateObject(const char * name)
@@ -161,6 +174,15 @@ NdbThread_CreateObject(const char * name
   struct NdbThread* tmpThread;
   DBUG_ENTER("NdbThread_Create");
 
+  if (g_main_thread != 0)
+  {
+    if (name)
+    {
+      strnmov(g_main_thread->thread_name, name, sizeof(tmpThread->thread_name));
+    }
+    DBUG_RETURN(g_main_thread);
+  }
+
   tmpThread = (struct NdbThread*)NdbMem_Allocate(sizeof(struct NdbThread));
   if (tmpThread == NULL)
     DBUG_RETURN(NULL);
@@ -183,7 +205,12 @@ NdbThread_CreateObject(const char * name
   settid(tmpThread);
   tmpThread->inited = 1;
 
-  return tmpThread;
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  ndb_mutex_thread_init(&tmpThread->m_mutex_thr_state);
+#endif
+
+  g_main_thread = tmpThread;
+  DBUG_RETURN(tmpThread);
 }
 
 struct NdbThread*
@@ -239,7 +266,7 @@ NdbThread_Create(NDB_THREAD_FUNC *p_thre
   tmpThread->object= p_thread_arg;
 
   NdbMutex_Lock(g_ndb_thread_mutex);
-  result = pthread_create(&tmpThread->thread, 
+  result = pthread_create(&tmpThread->thread,
 			  &thread_attr,
   		          ndb_thread_wrapper,
   		          tmpThread);
@@ -250,7 +277,7 @@ NdbThread_Create(NDB_THREAD_FUNC *p_thre
   {
     NdbMem_Free((char *)tmpThread);
     NdbMutex_Unlock(g_ndb_thread_mutex);
-    return 0;
+    DBUG_RETURN(0);
   }
 
   if (thread_prio == NDB_THREAD_PRIO_HIGH && f_high_prio_set)
@@ -471,7 +498,11 @@ NdbThread_LockCPU(struct NdbThread* pThr
   return error_no;
 }
 
+#ifndef NDB_MUTEX_DEADLOCK_DETECTOR
 static pthread_key(void*, tls_keys[NDB_THREAD_TLS_MAX]);
+#else
+static pthread_key(void*, tls_keys[NDB_THREAD_TLS_MAX + 1]);
+#endif
 
 void *NdbThread_GetTlsKey(NDB_THREAD_TLS key)
 {
@@ -490,6 +521,10 @@ NdbThread_Init()
   g_ndb_thread_condition = NdbCondition_Create();
   pthread_key_create(&(tls_keys[NDB_THREAD_TLS_JAM]), NULL);
   pthread_key_create(&(tls_keys[NDB_THREAD_TLS_THREAD]), NULL);
+#ifdef NDB_MUTEX_DEADLOCK_DETECTOR
+  pthread_key_create(&(tls_keys[NDB_THREAD_TLS_MAX]), NULL);
+#endif
+  NdbThread_CreateObject(0);
   return 0;
 }
 

=== modified file 'storage/ndb/src/common/util/ndb_init.cpp'
--- a/storage/ndb/src/common/util/ndb_init.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/common/util/ndb_init.cpp	2011-09-27 17:28:13 +0000
@@ -32,6 +32,8 @@ int g_ndb_init_need_monotonic = 0;
 
 static int ndb_init_called = 0;
 
+extern "C" void NdbMutex_SysInit();
+extern "C" void NdbMutex_SysEnd();
 extern "C" void NdbCondition_initialize(int need_monotonic);
 extern "C" void NdbTick_Init(int need_monotonic);
 extern "C" int NdbThread_Init();
@@ -45,6 +47,7 @@ void
 ndb_init_internal()
 {
   NdbOut_Init();
+  NdbMutex_SysInit();
   if (!g_ndb_connection_mutex)
     g_ndb_connection_mutex = NdbMutex_Create();
   if (!g_eventLogger)
@@ -88,7 +91,6 @@ ndb_init()
 void
 ndb_end_internal()
 {
-  NdbThread_End();
   if (g_ndb_connection_mutex) 
   {
     NdbMutex_Destroy(g_ndb_connection_mutex);
@@ -96,6 +98,9 @@ ndb_end_internal()
   }
   if (g_eventLogger)
     destroy_event_logger(&g_eventLogger);
+
+  NdbThread_End();
+  NdbMutex_SysEnd();
 }
 
 void

=== modified file 'storage/ndb/src/kernel/vm/ArrayPool.hpp'
--- a/storage/ndb/src/kernel/vm/ArrayPool.hpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/vm/ArrayPool.hpp	2011-09-27 06:44:06 +0000
@@ -1385,7 +1385,7 @@ UnsafeArrayPool<T>::getPtrForce(ConstPtr
 template <class T>
 class SafeArrayPool : public ArrayPool<T> {
 public:
-  SafeArrayPool(NdbMutex* mutex = 0);
+  SafeArrayPool();
   ~SafeArrayPool();
   int lock();
   int unlock();
@@ -1393,6 +1393,8 @@ public:
   void release(Uint32 i);
   void release(Ptr<T>&);
 
+  void setMutex(NdbMutex* mutex = 0);
+
 private:
   NdbMutex* m_mutex;
   bool m_mutex_owner;
@@ -1403,7 +1405,16 @@ private:
 
 template <class T>
 inline
-SafeArrayPool<T>::SafeArrayPool(NdbMutex* mutex)
+SafeArrayPool<T>::SafeArrayPool()
+{
+  m_mutex = 0;
+  m_mutex_owner = false;
+}
+
+template <class T>
+inline
+void
+SafeArrayPool<T>::setMutex(NdbMutex* mutex)
 {
   if (mutex != 0) {
     m_mutex = mutex;

=== modified file 'storage/ndb/src/kernel/vm/Emulator.cpp'
--- a/storage/ndb/src/kernel/vm/Emulator.cpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/vm/Emulator.cpp	2011-09-27 06:44:06 +0000
@@ -89,6 +89,7 @@ EmulatorData::create(){
   theSimBlockList  = new SimBlockList();
   m_socket_server  = new SocketServer();
   m_mem_manager    = new Ndbd_mem_manager();
+  globalData.m_global_page_pool.setMutex();
 
   if (theConfiguration == NULL ||
       theWatchDog == NULL ||

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2011-09-26 07:43:46 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2011-09-28 10:18:35 +0000
@@ -528,8 +528,6 @@ MgmtSrvr::start()
 {
   DBUG_ENTER("MgmtSrvr::start");
 
-  Guard g(m_local_config_mutex);
-
   /* Start transporter */
   if(!start_transporter(m_local_config))
   {

=== modified file 'storage/ndb/test/ndbapi/testNdbApi.cpp'
--- a/storage/ndb/test/ndbapi/testNdbApi.cpp	2011-09-19 12:08:00 +0000
+++ b/storage/ndb/test/ndbapi/testNdbApi.cpp	2011-09-27 05:37:30 +0000
@@ -4580,8 +4580,17 @@ public:
         m_id(id), m_res(res) {
       m_res.lock(m_id);
     }
-    ~Reserve(){
+
+    void unlock() {
       m_res.unlock(m_id);
+      m_id = 0;
+    }
+
+    ~Reserve(){
+      if (m_id)
+      {
+        m_res.unlock(m_id);
+      }
     }
   };
 };
@@ -4644,6 +4653,8 @@ int runNdbClusterConnect(NDBT_Context* c
 {
   const Uint32 api_nodes = ctx->getProperty("API_NODES");
   const Uint32 step_no = step->getStepNo();
+  const Uint32 timeout_after_first_alive = ctx->getProperty("TimeoutAfterFirst",
+                                                            30);
   if (step_no > api_nodes)
   {
     // Don't run with more threads than API node slots
@@ -4652,8 +4663,8 @@ int runNdbClusterConnect(NDBT_Context* c
 
   // Get connectstring from main connection
   char constr[256];
-  if(!ctx->m_cluster_connection.get_connectstring(constr,
-                                                  sizeof(constr)))
+  if (!ctx->m_cluster_connection.get_connectstring(constr,
+                                                   sizeof(constr)))
   {
     g_err << "Too short buffer for connectstring" << endl;
     return NDBT_FAILED;
@@ -4661,9 +4672,17 @@ int runNdbClusterConnect(NDBT_Context* c
 
   Uint32 l = 0;
   const Uint32 loops = ctx->getNumLoops();
-  while (l < loops)
+  while (l < loops && !ctx->isTestStopped())
   {
     g_info << "loop: " << l << endl;
+    if (ctx->getProperty("WAIT") > 0)
+    {
+      ndbout_c("thread %u waiting", step_no);
+      ctx->incProperty("WAITING");
+      while (ctx->getProperty("WAIT") > 0 && !ctx->isTestStopped())
+        NdbSleep_MilliSleep(10);
+      ndbout_c("thread %u waiting complete", step_no);
+    }
     Ndb_cluster_connection con(constr);
 
     const int retries = 12;
@@ -4679,11 +4698,12 @@ int runNdbClusterConnect(NDBT_Context* c
     NodeIdReservations::Reserve res(g_reservations, con.node_id());
 
     const int timeout = 30;
-    const int timeout_after_first_alive = 30;
-    if (con.wait_until_ready(timeout, timeout_after_first_alive) != 0)
+    int ret = con.wait_until_ready(timeout, timeout_after_first_alive);
+    if (! (ret == 0 || (timeout_after_first_alive == 0 && ret > 0)))
     {
       g_err << "Cluster connection was not ready, nodeid: "
             << con.node_id() << endl;
+      abort();
       return NDBT_FAILED;
     }
 
@@ -4699,12 +4719,153 @@ int runNdbClusterConnect(NDBT_Context* c
     NdbSleep_MilliSleep(10 + rand() % max_sleep);
 
     l++;
+    res.unlock(); // make sure it's called before ~Ndb_cluster_connection
+  }
+
+  ctx->incProperty("runNdbClusterConnect_FINISHED");
+
+  return NDBT_OK;
+}
+
+int
+runRestarts(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int result = NDBT_OK;
+  Uint32 threads = ctx->getProperty("API_NODES", (unsigned)0);
+  Uint32 sr = ctx->getProperty("ClusterRestart", (unsigned)0);
+  Uint32 master = ctx->getProperty("Master", (unsigned)0);
+  Uint32 slow = ctx->getProperty("SlowNR", (unsigned)0);
+  NdbRestarter restarter;
+
+  if (restarter.waitClusterStarted() != 0)
+  {
+    g_err << "Cluster failed to start" << endl;
+    return NDBT_FAILED;
+  }
+
+  if (sr == 0 && restarter.getNumDbNodes() < 2)
+    return NDBT_OK;
+
+  while (ctx->getProperty("runNdbClusterConnect_FINISHED") < threads
+         && !ctx->isTestStopped())
+  {
+    ndbout_c("%u %u",
+             ctx->getProperty("runNdbClusterConnect_FINISHED"),
+             threads);
+    if (sr == 0)
+    {
+      int id = rand() % restarter.getNumDbNodes();
+      int nodeId = restarter.getDbNodeId(id);
+      if (master == 1)
+      {
+        nodeId = restarter.getMasterNodeId();
+      }
+      else if (master == 2)
+      {
+        nodeId = restarter.getRandomNotMasterNodeId(rand());
+      }
+      ndbout << "Restart node " << nodeId
+             << "(master: " << restarter.getMasterNodeId() << ")"
+             << endl;
+      if (restarter.restartOneDbNode(nodeId, false, true, true) != 0)
+      {
+        g_err << "Failed to restartNextDbNode" << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+
+      if (restarter.waitNodesNoStart(&nodeId, 1))
+      {
+        g_err << "Failed to waitNodesNoStart" << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+
+      if (slow)
+      {
+        /**
+         * Block starting node in sp4
+         */
+        int dump[] = { 71, 4 };
+        restarter.dumpStateOneNode(nodeId, dump, NDB_ARRAY_SIZE(dump));
+      }
+
+      if (restarter.startNodes(&nodeId, 1))
+      {
+        g_err << "Failed to start node" << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+
+      if (slow)
+      {
+        Uint32 blockTime = 3 * 60 * 1000;
+        Uint64 end = NdbTick_CurrentMillisecond() + blockTime;
+        while (ctx->getProperty("runNdbClusterConnect_FINISHED") < threads
+               && !ctx->isTestStopped() &&
+               NdbTick_CurrentMillisecond() < end)
+        {
+          NdbSleep_MilliSleep(100);
+        }
+
+        // unblock
+        int dump[] = { 71 };
+        restarter.dumpStateOneNode(nodeId, dump, NDB_ARRAY_SIZE(dump));
+      }
+    }
+    else
+    {
+      ndbout << "Blocking threads" << endl;
+      ctx->setProperty("WAITING", Uint32(0));
+      ctx->setProperty("WAIT", 1);
+      while (ctx->getProperty("WAITING") <
+             (threads - ctx->getProperty("runNdbClusterConnect_FINISHED")) &&
+             !ctx->isTestStopped())
+      {
+        NdbSleep_MilliSleep(10);
+      }
+
+      ndbout << "Restart cluster" << endl;
+      if (restarter.restartAll(NdbRestarter::NRRF_NOSTART |
+                               NdbRestarter::NRRF_ABORT) != 0)
+      {
+        g_err << "Failed to restartAll" << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+
+      ctx->setProperty("WAITING", Uint32(0));
+      ctx->setProperty("WAIT", Uint32(0));
+
+      ndbout << "Starting cluster" << endl;
+      restarter.startAll();
+    }
+
+    if (restarter.waitClusterStarted() != 0)
+    {
+      g_err << "Cluster failed to start" << endl;
+      result = NDBT_FAILED;
+      break;
+    }
+  }
+
+  return result;
+}
+
+int runCheckAllNodesStarted(NDBT_Context* ctx, NDBT_Step* step){
+  NdbRestarter restarter;
+
+  if (restarter.waitClusterStarted(1) != 0)
+  {
+    g_err << "All nodes was not started " << endl;
+    return NDBT_FAILED;
   }
 
   return NDBT_OK;
 }
 
 
+
 static bool
 check_connect_no_such_host()
 {
@@ -5040,7 +5201,50 @@ TESTCASE("NdbClusterConnectionConnect",
 {
   INITIALIZER(runNdbClusterConnectionConnect);
 }
-
+TESTCASE("NdbClusterConnectNR",
+         "Make sure that every Ndb_cluster_connection get a unique nodeid")
+{
+  TC_PROPERTY("TimeoutAfterFirst", (Uint32)0);
+  INITIALIZER(runNdbClusterConnectInit);
+  STEPS(runNdbClusterConnect, MAX_NODES);
+  STEP(runRestarts); // Note after runNdbClusterConnect or else counting wrong
+}
+TESTCASE("NdbClusterConnectNR_master",
+         "Make sure that every Ndb_cluster_connection get a unique nodeid")
+{
+  TC_PROPERTY("Master", 1);
+  TC_PROPERTY("TimeoutAfterFirst", (Uint32)0);
+  INITIALIZER(runNdbClusterConnectInit);
+  STEPS(runNdbClusterConnect, MAX_NODES);
+  STEP(runRestarts); // Note after runNdbClusterConnect or else counting wrong
+}
+TESTCASE("NdbClusterConnectNR_non_master",
+         "Make sure that every Ndb_cluster_connection get a unique nodeid")
+{
+  TC_PROPERTY("Master", 2);
+  TC_PROPERTY("TimeoutAfterFirst", (Uint32)0);
+  INITIALIZER(runNdbClusterConnectInit);
+  STEPS(runNdbClusterConnect, MAX_NODES);
+  STEP(runRestarts); // Note after runNdbClusterConnect or else counting wrong
+}
+TESTCASE("NdbClusterConnectNR_slow",
+         "Make sure that every Ndb_cluster_connection get a unique nodeid")
+{
+  TC_PROPERTY("Master", 2);
+  TC_PROPERTY("TimeoutAfterFirst", (Uint32)0);
+  TC_PROPERTY("SlowNR", 1);
+  INITIALIZER(runNdbClusterConnectInit);
+  STEPS(runNdbClusterConnect, MAX_NODES);
+  STEP(runRestarts); // Note after runNdbClusterConnect or else counting wrong
+}
+TESTCASE("NdbClusterConnectSR",
+         "Make sure that every Ndb_cluster_connection get a unique nodeid")
+{
+  TC_PROPERTY("ClusterRestart", (Uint32)1);
+  INITIALIZER(runNdbClusterConnectInit);
+  STEPS(runNdbClusterConnect, MAX_NODES);
+  STEP(runRestarts); // Note after runNdbClusterConnect or else counting wrong
+}
 NDBT_TESTSUITE_END(testNdbApi);
 
 int main(int argc, const char** argv){

=== modified file 'storage/ndb/test/ndbapi/testRestartGci.cpp'
--- a/storage/ndb/test/ndbapi/testRestartGci.cpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/test/ndbapi/testRestartGci.cpp	2011-09-28 10:04:03 +0000
@@ -546,7 +546,7 @@ int runUpdateVerifyGCI(NDBT_Context* ctx
     CHECK(rowGci != NULL);
 
     /* Define an update op to set the next GCI */
-    CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, loopCount+1) == 0);
+    CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, (int)(loopCount+1)) == 0);
 
     if (hugoOps.execute_Commit(pNdb) != 0)
     {

=== modified file 'storage/ndb/test/ndbapi/test_event.cpp'
--- a/storage/ndb/test/ndbapi/test_event.cpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/test/ndbapi/test_event.cpp	2011-09-28 10:04:03 +0000
@@ -168,7 +168,7 @@ Uint32 setAnyValue(Ndb* ndb, NdbTransact
 {
   /* XOR 2 32bit words of transid together */
   Uint64 transId = trans->getTransactionId();
-  return transId ^ (transId >> 32);
+  return (Uint32)(transId ^ (transId >> 32));
 }
 
 bool checkAnyValueTransId(Uint64 transId, Uint32 anyValue)

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2011-09-09 10:48:14 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2011-09-27 05:37:30 +0000
@@ -1753,3 +1753,24 @@ max-time: 500
 cmd: testAsynchMultiwait
 args: -n AsynchMultiwaitWakeup T1
 
+# alloc node id
+max-time: 500
+cmd: testNdbApi
+args: -n NdbClusterConnect T1
+
+max-time: 500
+cmd: testNdbApi
+args: -n NdbClusterConnectionConnect T1
+
+max-time: 500
+cmd: testNdbApi
+args: -n NdbClusterConnectNR_non_master T1
+
+max-time: 500
+cmd: testNdbApi
+args: -n NdbClusterConnectNR_slow T1
+
+max-time: 500
+cmd: testNdbApi
+args: -n NdbClusterConnectSR T1
+

=== modified file 'storage/ndb/test/tools/hugoJoin.cpp'
--- a/storage/ndb/test/tools/hugoJoin.cpp	2011-04-06 14:16:13 +0000
+++ b/storage/ndb/test/tools/hugoJoin.cpp	2011-09-28 09:54:05 +0000
@@ -192,7 +192,7 @@ int main(int argc, char** argv){
     }
     HugoQueryBuilder builder(&MyNdb, tables.getBase(), mask);
     builder.setJoinLevel(_depth);
-    const NdbQueryDef * q = builder.createQuery(&MyNdb);
+    const NdbQueryDef * q = builder.createQuery();
     if (_verbose >= 2)
     {
       q->print(); ndbout << endl;

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.1 branch (jonas.oreland:4293 to 4294) Jonas Oreland2 Oct