List:Commits« Previous MessageNext Message »
From:Tor Didriksen Date:February 15 2012 1:57pm
Subject:bzr push into mysql-trunk branch (tor.didriksen:3853 to 3854) Bug#13645095
View as plain text  
 3854 Tor Didriksen	2012-02-15
      Bug#13645095 SEVERAL TESTS ON DAILY TRUNK ARE FAILING BECAUSE OF MYSQLTEST GOT SIGNAL 11.
      
      Classes ilink, base_ilist and base_ilist_iterator were not type-safe,
      so at high optimization levels, the ilink inheritance corrupted the THD objects.
      Templatizing these classed with typed pointers solved the problem.
     @ sql/event_scheduler.cc
        Move the declaration of 'extern I_List<THD> threads;' 
        to a separate header file.
     @ sql/global_threads.h
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
        This was necessary because mysqld.h is included *lots* of places,
        and the windows compiler expanded the template (for THD which was fwd declared) 
        even if the template was unused.
     @ sql/keycaches.cc
        Move NAMED_ILINK to .h file.
     @ sql/keycaches.h
        Move NAMED_ILINK to .h file.
     @ sql/mysqld.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
     @ sql/mysqld.h
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
        This was necessary because mysqld.h is included *lots* of places,
        and the windows compiler expanded the template (for THD which was fwd declared) 
        even if the template was unused.
     @ sql/rpl_master.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
     @ sql/signal_handler.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
     @ sql/sql_class.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
        Move Item_change_record to .h file.
     @ sql/sql_class.h
        Remove the unused transient_cursor_list
        
        Move Item_change_record to .h file.
        Remove the custom operator new/delete for same class.
        
        Remove Statement <= ilink inheritance, it was unused.
        Add explicit THD <= ilink<THd> inheritance instead.
     @ sql/sql_insert.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
     @ sql/sql_list.h
        Templatize ilink and related classes, to get better type safety.
        
        Remove custom operator new/delete for ilink:
         - they use the heap anyways, and it's better to let std::new do that
         - it used ME_FAE: fatal error
         - it messed up placement new for derived classes 
           (see simplification of Item_change_record)
     @ sql/sql_parse.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
     @ sql/sql_show.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
     @ sql/sql_test.cc
        Move the declaration of 'extern I_List<THD> threads;' to a separate header file.
     @ unittest/gunit/sql_list-t.cc
        Fix some memory leaks.

    added:
      sql/global_threads.h
    modified:
      sql/event_scheduler.cc
      sql/keycaches.cc
      sql/keycaches.h
      sql/mysqld.cc
      sql/mysqld.h
      sql/rpl_master.cc
      sql/signal_handler.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_insert.cc
      sql/sql_list.h
      sql/sql_optimizer.cc
      sql/sql_parse.cc
      sql/sql_show.cc
      sql/sql_test.cc
      unittest/gunit/sql_list-t.cc
 3853 Anitha Gopi	2012-02-15
      Bug#11748899 : Di
      sabled failing test on windows

    modified:
      mysql-test/t/disabled.def
=== modified file 'sql/event_scheduler.cc'
--- a/sql/event_scheduler.cc	2011-10-06 11:06:34 +0000
+++ b/sql/event_scheduler.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2012, 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
@@ -22,6 +22,7 @@
 #include "event_db_repository.h"
 #include "sql_connect.h"         // init_new_connection_handler_thread
 #include "sql_acl.h"             // SUPER_ACL
+#include "global_threads.h"
 
 /**
   @addtogroup Event_Scheduler

=== added file 'sql/global_threads.h'
--- a/sql/global_threads.h	1970-01-01 00:00:00 +0000
+++ b/sql/global_threads.h	2012-02-15 13:57:17 +0000
@@ -0,0 +1,28 @@
+/* Copyright (c) 2012, 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  02111-1307  USA */
+
+#ifndef GLOBAL_THREADS_INCLUDED
+#define GLOBAL_THREADS_INCLUDED
+
+/*
+  TODO: Make a proper interface for keeping track of global threads.
+ */
+#include "sql_list.h"
+#include "sql_class.h"
+
+extern I_List<THD> threads;
+extern uint volatile thread_count;
+
+#endif  // GLOBAL_THREADS_INCLUDED

=== modified file 'sql/keycaches.cc'
--- a/sql/keycaches.cc	2011-06-30 15:50:45 +0000
+++ b/sql/keycaches.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2012, 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
@@ -21,33 +21,6 @@
 
 NAMED_ILIST key_caches;
 
-/**
-  ilink (intrusive list element) with a name
-*/
-class NAMED_ILINK :public ilink
-{
-public:
-  const char *name;
-  uint name_length;
-  uchar* data;
-
-  NAMED_ILINK(I_List<NAMED_ILINK> *links, const char *name_arg,
-             uint name_length_arg, uchar* data_arg)
-    :name_length(name_length_arg), data(data_arg)
-  {
-    name= my_strndup(name_arg, name_length, MYF(MY_WME));
-    links->push_back(this);
-  }
-  inline bool cmp(const char *name_cmp, uint length)
-  {
-    return length == name_length && !memcmp(name, name_cmp, length);
-  }
-  ~NAMED_ILINK()
-  {
-    my_free((void *) name);
-  }
-};
-
 uchar* find_named(I_List<NAMED_ILINK> *list, const char *name, uint length,
                 NAMED_ILINK **found)
 {

=== modified file 'sql/keycaches.h'
--- a/sql/keycaches.h	2011-06-30 15:50:45 +0000
+++ b/sql/keycaches.h	2012-02-15 13:57:17 +0000
@@ -24,7 +24,34 @@ extern "C"
   typedef int (*process_key_cache_t) (const char *, KEY_CACHE *);
 }
 
-class NAMED_ILINK;
+/**
+  ilink (intrusive list element) with a name
+*/
+class NAMED_ILINK :public ilink<NAMED_ILINK>
+{
+public:
+  const char *name;
+  uint name_length;
+  uchar* data;
+
+  NAMED_ILINK(I_List<NAMED_ILINK> *links, const char *name_arg,
+             uint name_length_arg, uchar* data_arg)
+    :name_length(name_length_arg), data(data_arg)
+  {
+    name= my_strndup(name_arg, name_length, MYF(MY_WME));
+    links->push_back(this);
+  }
+
+  bool cmp(const char *name_cmp, uint length)
+  {
+    return length == name_length && !memcmp(name, name_cmp, length);
+  }
+
+  ~NAMED_ILINK()
+  {
+    my_free((void *) name);
+  }
+};
 
 class NAMED_ILIST: public I_List<NAMED_ILINK>
 {

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-01-30 05:34:32 +0000
+++ b/sql/mysqld.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, 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
@@ -71,6 +71,9 @@
 #include "sql_callback.h"
 #include "opt_trace_context.h"
 
+#include "global_threads.h"
+#include "mysqld.h"
+
 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
 #include "../storage/perfschema/pfs_server.h"
 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2012-01-25 10:07:23 +0000
+++ b/sql/mysqld.h	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2012, 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
@@ -107,7 +107,6 @@ extern bool opt_ignore_builtin_innodb;
 extern my_bool opt_character_set_client_handshake;
 extern bool volatile abort_loop;
 extern bool in_bootstrap;
-extern uint volatile thread_count;
 extern uint connection_count;
 extern my_bool opt_safe_user_create;
 extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
@@ -233,7 +232,6 @@ extern MYSQL_FILE *bootstrap_file;
 extern my_bool old_mode;
 extern LEX_STRING opt_init_connect, opt_init_slave;
 extern int bootstrap_error;
-extern I_List<THD> threads;
 extern char err_shared_dir[];
 extern TYPELIB thread_handling_typelib;
 extern my_decimal decimal_zero;

=== modified file 'sql/rpl_master.cc'
--- a/sql/rpl_master.cc	2012-01-22 17:00:21 +0000
+++ b/sql/rpl_master.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2012, 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
@@ -17,6 +17,7 @@
 #include "sql_priv.h"
 #include "unireg.h"
 #include "sql_parse.h"                          // check_access
+#include "global_threads.h"
 #ifdef HAVE_REPLICATION
 
 #include "sql_acl.h"                            // SUPER_ACL

=== modified file 'sql/signal_handler.cc'
--- a/sql/signal_handler.cc	2011-12-02 13:33:08 +0000
+++ b/sql/signal_handler.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2011, 2012 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
@@ -18,6 +18,7 @@
 
 #include "sys_vars.h"
 #include "my_stacktrace.h"
+#include "global_threads.h"
 
 #ifdef __WIN__
 #include <crtdbg.h>

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2012-02-08 15:25:17 +0000
+++ b/sql/sql_class.cc	2012-02-15 13:57:17 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2000, 2012, 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
@@ -57,6 +57,8 @@
 #include "sql_parse.h"                          // is_update_query
 #include "sql_callback.h"
 #include "lock.h"
+#include "global_threads.h"
+#include "mysqld.h"
 
 #include <mysql/psi/mysql_statement.h>
 
@@ -2069,17 +2071,6 @@ void THD::close_active_vio()
 #endif
 
 
-struct Item_change_record: public ilink
-{
-  Item **place;
-  Item *old_value;
-  /* Placement new was hidden by `new' in ilink (TODO: check): */
-  static void *operator new(size_t size, void *mem) { return mem; }
-  static void operator delete(void *ptr, size_t size) {}
-  static void operator delete(void *ptr, void *mem) { /* never called */ }
-};
-
-
 /*
   Register an item tree tree transformation, performed by the query
   optimizer. We need a pointer to runtime_memroot because it may be !=

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-01-31 15:16:16 +0000
+++ b/sql/sql_class.h	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, 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
@@ -1052,7 +1052,7 @@ class Server_side_cursor;
   be used explicitly.
 */
 
-class Statement: public ilink, public Query_arena
+class Statement: public Query_arena
 {
   Statement(const Statement &rhs);              /* not implemented: */
   Statement &operator=(const Statement &rhs);   /* non-copyable */
@@ -1205,6 +1205,7 @@ public:
     Close all cursors of this connection that use tables of a storage
     engine that has transaction-specific state and therefore can not
     survive COMMIT or ROLLBACK. Currently all but MyISAM cursors are closed.
+    CURRENTLY NOT IMPLEMENTED!
   */
   void close_transient_cursors();
   void erase(Statement *statement);
@@ -1214,7 +1215,6 @@ public:
 private:
   HASH st_hash;
   HASH names_hash;
-  I_List<Statement> transient_cursor_list;
   Statement *last_found_statement;
 };
 
@@ -1655,7 +1655,12 @@ extern Log_throttle log_throttle_qni;
   yet another time.
 */
 
-struct Item_change_record;
+struct Item_change_record: public ilink<Item_change_record>
+{
+  Item **place;
+  Item *old_value;
+};
+
 typedef I_List<Item_change_record> Item_change_list;
 
 
@@ -2149,7 +2154,8 @@ my_micro_time_to_timeval(ulonglong micro
   a thread/connection descriptor
 */
 
-class THD :public Statement,
+class THD :public ilink<THD>,
+           public Statement,
            public Open_tables_state,
            public MDL_context_owner
 {

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2012-01-31 15:16:16 +0000
+++ b/sql/sql_insert.cc	2012-02-15 13:57:17 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2000, 2012, 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
@@ -81,6 +81,7 @@
 #include "delayable_insert_operation.h"
 #include "sql_tmp_table.h"    // tmp tables
 #include "sql_optimizer.h"    // JOIN
+#include "global_threads.h"
 
 #include "debug_sync.h"
 
@@ -1838,7 +1839,7 @@ int check_that_all_fields_are_given_valu
 
    @note that custom operator new/delete are inherited from the ilink class.
 */
-class delayed_row :public ilink {
+class delayed_row :public ilink<delayed_row> {
 public:
   char *record;
   enum_duplicates dup;
@@ -1980,7 +1981,7 @@ bool delayed_row::copy_context(THD *thd,
 
    @note that custom operator new/delete are inherited from the ilink class.
 */
-class Delayed_insert :public ilink {
+class Delayed_insert :public ilink<Delayed_insert> {
   uint locks_in_memory;
   thr_lock_type delayed_lock;
 public:

=== modified file 'sql/sql_list.h'
--- a/sql/sql_list.h	2011-10-06 11:06:34 +0000
+++ b/sql/sql_list.h	2012-02-15 13:57:17 +0000
@@ -1,6 +1,6 @@
 #ifndef INCLUDES_MYSQL_SQL_LIST_H
 #define INCLUDES_MYSQL_SQL_LIST_H
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, 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
@@ -573,41 +573,43 @@ public:
 };
 
 
+template <typename T> class base_ilist;
+template <typename T> class base_ilist_iterator;
+
 /*
   A simple intrusive list which automaticly removes element from list
   on delete (for THD element)
+  NOTE: this inherently unsafe, since we rely on <T> to have
+  the same layout as ilink<T> (see base_ilist::sentinel).
+  Please consider using a different strategy for linking objects.
 */
 
-struct ilink
+template <typename T>
+class ilink
 {
-  struct ilink **prev,*next;
-  static void *operator new(size_t size) throw ()
-  {
-    return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR));
-  }
-  static void operator delete(void* ptr_arg, size_t size)
-  {
-     my_free(ptr_arg);
-  }
+  T **prev, *next;
+public:
+  ilink() : prev(NULL), next(NULL) {}
 
-  inline ilink()
-  {
-    prev=0; next=0;
-  }
-  inline void unlink()
+  void unlink()
   {
     /* Extra tests because element doesn't have to be linked */
     if (prev) *prev= next;
     if (next) next->prev=prev;
-    prev=0 ; next=0;
+    prev= NULL;
+    next= NULL;
   }
+
   virtual ~ilink() { unlink(); }		/*lint -e1740 */
+
+  friend class base_ilist<T>;
+  friend class base_ilist_iterator<T>;
 };
 
 
 /* Needed to be able to have an I_List of char* strings in mysqld.cc. */
 
-class i_string: public ilink
+class i_string: public ilink<i_string>
 {
 public:
   const char* ptr;
@@ -616,7 +618,7 @@ public:
 };
 
 /* needed for linked list of two strings for replicate-rewrite-db */
-class i_string_pair: public ilink
+class i_string_pair: public ilink<i_string_pair>
 {
 public:
   const char* key;
@@ -630,38 +632,48 @@ public:
 template <class T> class I_List_iterator;
 
 
+template<typename T>
 class base_ilist
 {
-  struct ilink *first;
-  struct ilink last;
+  T *first;
+  ilink<T> sentinel;
 public:
-  inline void empty() { first= &last; last.prev= &first; }
+  void empty() {
+    first= static_cast<T*>(&sentinel);
+    sentinel.prev= &first;
+  }
   base_ilist() { empty(); }
-  inline bool is_empty() {  return first == &last; }
-  inline void push_front(ilink *a)
+  bool is_empty() { return first == static_cast<T*>(&sentinel); }
+
+  /// Pushes new element in front of list.
+  void push_front(T *a)
   {
     first->prev= &a->next;
-    a->next=first; a->prev= &first; first=a;
+    a->next= first;
+    a->prev= &first;
+    first= a;
   }
-  inline void push_back(ilink *a)
+
+  /// Pushes new element to the end of the list, i.e. in front of the sentinel.
+  void push_back(T *a)
   {
-    *last.prev= a;
-    a->next= &last;
-    a->prev= last.prev;
-    last.prev= &a->next;
+    *sentinel.prev= a;
+    a->next= static_cast<T*>(&sentinel);
+    a->prev= sentinel.prev;
+    sentinel.prev= &a->next;
   }
-  inline struct ilink *get()
+
+  // Unlink first element, and return it.
+  T *get()
   {
-    struct ilink *first_link=first;
-    if (first_link == &last)
-      return 0;
-    first_link->unlink();			// Unlink from list
+    if (is_empty())
+      return NULL;
+    T *first_link= first;
+    first_link->unlink();
     return first_link;
   }
-  inline struct ilink *head()
-  {
-    return (first != &last) ? first : 0;
-  }
+
+  T *head() { return is_empty() ? NULL : first; }
 
   /**
     Moves list elements to new owner, and empties current owner (i.e. this).
@@ -674,11 +686,11 @@ public:
   {
     DBUG_ASSERT(new_owner->is_empty());
     new_owner->first= first;
-    new_owner->last= last;
+    new_owner->sentinel= sentinel;
     empty();
   }
 
-  friend class base_ilist_iterator;
+  friend class base_ilist_iterator<T>;
  private:
   /*
     We don't want to allow copying of this class, as that would give us
@@ -690,18 +702,24 @@ public:
 };
 
 
+template<typename T>
 class base_ilist_iterator
 {
-  base_ilist *list;
-  struct ilink **el,*current;
+  base_ilist<T> *list;
+  T **el, *current;
 public:
-  base_ilist_iterator(base_ilist &list_par) :list(&list_par),
-    el(&list_par.first),current(0) {}
-  void *next(void)
+  base_ilist_iterator(base_ilist<T> &list_par) :
+    list(&list_par),
+    el(&list_par.first),
+    current(NULL)
+  {}
+
+  T *next(void)
   {
     /* This is coded to allow push_back() while iterating */
     current= *el;
-    if (current == &list->last) return 0;
+    if (current == static_cast<T*>(&list->sentinel))
+      return NULL;
     el= &current->next;
     return current;
   }
@@ -709,18 +727,17 @@ public:
 
 
 template <class T>
-class I_List :private base_ilist
+class I_List :private base_ilist<T>
 {
 public:
-  I_List() :base_ilist()	{}
-  inline void empty()		{ base_ilist::empty(); }
-  inline bool is_empty()        { return base_ilist::is_empty(); } 
-  inline void push_front(T* a)	{ base_ilist::push_front(a); }
-  inline void push_back(T* a)	{ base_ilist::push_back(a); }
-  inline T* get()		{ return (T*) base_ilist::get(); }
-  inline T* head()		{ return (T*) base_ilist::head(); }
-  inline void move_elements_to(I_List<T>* new_owner) {
-    base_ilist::move_elements_to(new_owner);
+  using base_ilist<T>::empty;
+  using base_ilist<T>::is_empty;
+  using base_ilist<T>::get;
+  using base_ilist<T>::push_front;
+  using base_ilist<T>::push_back;
+  using base_ilist<T>::head;
+  void move_elements_to(I_List<T>* new_owner) {
+    base_ilist<T>::move_elements_to(new_owner);
   }
 #ifndef _lint
   friend class I_List_iterator<T>;
@@ -728,11 +745,12 @@ public:
 };
 
 
-template <class T> class I_List_iterator :public base_ilist_iterator
+template <class T> 
+class I_List_iterator :public base_ilist_iterator<T>
 {
 public:
-  I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
-  inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
+  I_List_iterator(I_List<T> &a) : base_ilist_iterator<T>(a) {}
+  inline T* operator++(int) { return base_ilist_iterator<T>::next(); }
 };
 
 /**

=== modified file 'sql/sql_optimizer.cc'
--- a/sql/sql_optimizer.cc	2012-02-14 14:42:12 +0000
+++ b/sql/sql_optimizer.cc	2012-02-15 13:57:17 +0000
@@ -944,7 +944,7 @@ void reset_nj_counters(List<TABLE_LIST> 
   Return in cond_value FALSE if condition is impossible (1 = 2)
 *****************************************************************************/
 
-class COND_CMP :public ilink {
+class COND_CMP :public ilink<COND_CMP> {
 public:
   static void *operator new(size_t size)
   {

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2012-02-08 06:45:31 +0000
+++ b/sql/sql_parse.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, 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
@@ -97,6 +97,7 @@
 #include "sql_bootstrap.h"
 #include "opt_explain.h"
 #include "sql_rewrite.h"
+#include "global_threads.h"
 
 #include <algorithm>
 using std::max;

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2012-02-08 12:49:33 +0000
+++ b/sql/sql_show.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, 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
@@ -57,6 +57,7 @@
 #include "opt_trace.h"     // Optimizer trace information schema tables
 #include "sql_tmp_table.h" // Tmp tables
 #include "sql_optimizer.h" // JOIN
+#include "global_threads.h"
 
 #include <algorithm>
 using std::max;
@@ -1995,7 +1996,7 @@ view_store_create_info(THD *thd, TABLE_L
   returns for each thread: thread id, user, host, db, command, info
 ****************************************************************************/
 
-class thread_info :public ilink {
+class thread_info :public ilink<thread_info> {
 public:
   static void *operator new(size_t size)
   {

=== modified file 'sql/sql_test.cc'
--- a/sql/sql_test.cc	2011-12-14 12:32:55 +0000
+++ b/sql/sql_test.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, 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
@@ -39,6 +39,8 @@
 #include "events.h"
 #endif
 
+#include "global_threads.h"
+
 static const char *lock_descriptions[] =
 {
   /* TL_UNLOCK                  */  "No lock",

=== modified file 'unittest/gunit/sql_list-t.cc'
--- a/unittest/gunit/sql_list-t.cc	2011-12-20 09:51:05 +0000
+++ b/unittest/gunit/sql_list-t.cc	2012-02-15 13:57:17 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2009, 2012, 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
@@ -142,16 +142,16 @@ TEST_F(SqlListTest, DeepCopy)
 {
   int values[] = {11, 22, 33, 42, 5};
   insert_values(values, &m_int_list);
-  MEM_ROOT *mem_root= (MEM_ROOT*) malloc(1 << 20);
-  init_alloc_root(mem_root, 4096, 4096);
-  List<int> list_copy(m_int_list, mem_root);
+  MEM_ROOT mem_root;
+  init_alloc_root(&mem_root, 4096, 4096);
+  List<int> list_copy(m_int_list, &mem_root);
   EXPECT_EQ(list_copy.elements, m_int_list.elements);
   while (!list_copy.is_empty())
   {
     EXPECT_EQ(*m_int_list.pop(), *list_copy.pop());
   }
   EXPECT_TRUE(m_int_list.is_empty());
-  free(mem_root);
+  free_root(&mem_root, MYF(0));
 }
 
 
@@ -175,7 +175,7 @@ TEST_F(SqlListTest, Iterate)
 
 
 // A simple helper class for testing intrusive lists.
-class Linked_node : public ilink
+class Linked_node : public ilink<Linked_node>
 {
 public:
   Linked_node(int val) : m_value(val) {}
@@ -183,6 +183,7 @@ public:
 private:
   int m_value;
 };
+const Linked_node * const null_node= NULL;
 
 
 // An example of a test without any fixture.
@@ -191,17 +192,17 @@ TEST(SqlIlistTest, ConstructAndDestruct)
   I_List<Linked_node> i_list;
   I_List_iterator<Linked_node> i_list_iter(i_list);
   EXPECT_TRUE(i_list.is_empty());
-  const Linked_node *null_node= NULL;
   EXPECT_EQ(null_node, i_list_iter++);
 }
 
 
 // Tests iteration over intrusive lists.
-TEST(SqlIlistTest, Iterate)
+TEST(SqlIlistTest, PushBackAndIterate)
 {
   I_List<Linked_node> i_list;
   I_List_iterator<Linked_node> i_list_iter(i_list);
   int values[] = {11, 22, 33, 42, 5};
+  EXPECT_EQ(null_node, i_list.head());
   for (int ix= 0; ix < array_size(values); ++ix)
   {
     i_list.push_back(new Linked_node(values[ix]));
@@ -213,6 +214,12 @@ TEST(SqlIlistTest, Iterate)
   {
     EXPECT_EQ(values[value_number++], node->get_value());
   }
+  for (value_number= 0; (node= i_list.get()); ++value_number)
+  {
+    EXPECT_EQ(values[value_number], node->get_value());
+    delete node;
+  }
+  EXPECT_EQ(array_size(values), value_number);
 }
 
 // Another iteration test over intrusive lists.
@@ -232,6 +239,8 @@ TEST(SqlIlistTest, PushFrontAndIterate)
   {
     EXPECT_EQ(values[value_number--], node->get_value());
   }
+  while ((node= i_list.get()))
+    delete node;
 }
 
 static int cmp_test(void *a, void *b, void *c)

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (tor.didriksen:3853 to 3854) Bug#13645095Tor Didriksen15 Feb