List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:January 26 2011 11:02pm
Subject:bzr commit into mysql-trunk-wl5379 branch (chris.powers:3220)
View as plain text  
#At file:///home/cpowers/work/dev/mysql-trunk-wl4896/ based on revid:chris.powers@stripped

 3220 Christopher Powers	2011-01-26
      Merge w/ mysql-trunk-wl5379

    modified:
      storage/perfschema/CMakeLists.txt*
      storage/perfschema/pfs.cc*
      storage/perfschema/pfs_column_types.h*
      storage/perfschema/pfs_engine_table.cc*
      storage/perfschema/pfs_events_waits.h*
      storage/perfschema/pfs_instr_class.cc*
      storage/perfschema/table_events_waits.cc*
=== modified file 'storage/perfschema/CMakeLists.txt' (properties changed: -x to +x)
--- a/storage/perfschema/CMakeLists.txt	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/CMakeLists.txt	2011-01-26 23:02:25 +0000
@@ -50,6 +50,7 @@ table_ews_by_thread_by_event_name.h
 table_ews_global_by_event_name.h
 table_file_instances.h
 table_file_summary.h
+table_socket_instances.h
 table_helper.h
 table_os_global_by_type.h
 table_performance_timers.h
@@ -86,6 +87,7 @@ table_ews_by_thread_by_event_name.cc
 table_ews_global_by_event_name.cc
 table_file_instances.cc
 table_file_summary.cc
+table_socket_instances.cc
 table_helper.cc
 table_os_global_by_type.cc
 table_performance_timers.cc

=== modified file 'storage/perfschema/pfs.cc' (properties changed: -x to +x)
--- a/storage/perfschema/pfs.cc	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs.cc	2011-01-26 23:02:25 +0000
@@ -17,7 +17,11 @@
   @file storage/perfschema/pfs.cc
   The performance schema implementation of all instruments.
 */
-
+#ifdef __WIN__
+  #include <winsock2.h>
+#else
+  #include <arpa/inet.h>
+#endif
 #include "my_global.h"
 #include "thr_lock.h"
 #include "mysql/psi/psi.h"
@@ -982,6 +986,23 @@ static enum_operation_type table_lock_op
   OPERATION_TYPE_TL_WRITE_EXTERNAL /* PFS_TL_WRITE_EXTERNAL */
 };
 
+/**
+  Conversion map from PSI_socket_operation to enum_operation_type.
+  Indexed by enum PSI_socket_operation.
+*/
+static enum_operation_type socket_operation_map[]=
+{
+  OPERATION_TYPE_SOCKETCREATE,
+  OPERATION_TYPE_SOCKETCONNECT,
+  OPERATION_TYPE_SOCKETBIND,
+  OPERATION_TYPE_SOCKETCLOSE,
+  OPERATION_TYPE_SOCKETSEND,
+  OPERATION_TYPE_SOCKETRECV,
+  OPERATION_TYPE_SOCKETSEEK,
+  OPERATION_TYPE_SOCKETOPT,
+  OPERATION_TYPE_SOCKETSTAT,
+  OPERATION_TYPE_SOCKETSHUTDOWN
+};
 
 /**
   Build the prefix name of a class of instruments in a category.
@@ -1117,6 +1138,16 @@ static void register_file_v1(const char
                    register_file_class)
 }
 
+static void register_socket_v1(const char *category,
+                             PSI_socket_info_v1 *info,
+                             int count)
+{
+  REGISTER_BODY_V1(PSI_socket_key,
+                   socket_instrument_prefix,
+                   register_socket_class)
+}
+
+
 #define INIT_BODY_V1(T, KEY, ID)                                            \
   PFS_##T##_class *klass;                                                   \
   PFS_##T *pfs;                                                             \
@@ -1263,6 +1294,32 @@ static void close_table_v1(PSI_table *ta
   destroy_table(pfs);
 }
 
+static PSI_socket*
+init_socket_v1(PSI_socket_key key, const void *identity)
+{
+//  INIT_BODY_V1(socket, key, identity);
+  PFS_socket_class *klass;
+  PFS_socket *pfs;
+  PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+  if (unlikely(pfs_thread == NULL))
+    return NULL;
+  if (!pfs_thread->m_enabled)
+    return NULL;
+  klass= find_socket_class(key);
+  if (unlikely(klass == NULL))
+    return NULL;
+  if (!klass->m_enabled)
+    return NULL;
+  pfs= create_socket(klass, identity);
+  return reinterpret_cast<PSI_socket *> (pfs);
+}
+
+static void destroy_socket_v1(PSI_socket* socket)
+{
+  PFS_socket *pfs= reinterpret_cast<PFS_socket*> (socket);
+  destroy_socket(pfs);
+}
+
 /**
   Implementation of the file instrumentation interface.
   @sa PSI_v1::create_file.
@@ -2471,6 +2528,101 @@ get_thread_file_descriptor_locker_v1(PSI
   return reinterpret_cast<PSI_file_locker*> (state);
 }
 
+/** Socket locker */
+
+static PSI_socket_locker*
+get_thread_socket_locker_v1(PSI_socket_locker_state *state,
+                               PSI_socket *socket, PSI_socket_operation op)
+{
+  PFS_socket *pfs_socket= reinterpret_cast<PFS_socket*> (socket);
+
+  DBUG_ASSERT(static_cast<int> (op) >= 0);
+  DBUG_ASSERT(static_cast<uint> (op) < array_elements(socket_operation_map));
+  DBUG_ASSERT(state != NULL);
+  DBUG_ASSERT(pfs_socket != NULL);
+  DBUG_ASSERT(pfs_socket->m_class != NULL);
+
+  if (!flag_global_instrumentation)
+    return NULL;
+  if (!pfs_socket->m_class->m_enabled)
+    return NULL;
+  PFS_socket_class *klass= pfs_socket->m_class;
+  if (!klass->m_enabled)
+    return NULL;
+
+  register uint flags;
+
+  if (klass->m_timed)
+    state->m_flags= STATE_FLAG_TIMED;
+  else
+    state->m_flags= 0;
+
+  if (flag_thread_instrumentation)
+  {
+    PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+    if (unlikely(pfs_thread == NULL))
+      return NULL;
+
+    if (! pfs_thread->m_enabled)
+      return NULL;
+
+    state->m_thread= reinterpret_cast<PSI_thread *> (pfs_thread);
+    flags= STATE_FLAG_THREAD;
+
+    if (klass->m_timed)
+      flags|= STATE_FLAG_TIMED;
+
+    if (flag_events_waits_current)
+    {
+      if (unlikely(pfs_thread->m_events_waits_count >= WAIT_STACK_SIZE))
+      {
+        locker_lost++;
+        return NULL;
+      }
+      PFS_events_waits *wait= &pfs_thread->m_events_waits_stack[pfs_thread->m_events_waits_count];
+      state->m_wait= wait;
+      flags|= STATE_FLAG_WAIT;
+
+#ifdef HAVE_NESTED_EVENTS
+      wait->m_nesting_event_id= (wait - 1)->m_event_id;
+#endif
+      wait->m_thread= pfs_thread;
+      wait->m_class= klass;
+      wait->m_timer_start= 0;
+      wait->m_timer_end= 0;
+      wait->m_object_instance_addr= pfs_socket;
+//    wait->m_object_name= pfs_socket->m_ip;
+//    wait->m_object_name_length= pfs_socket->m_ip_length;
+      wait->m_event_id= pfs_thread->m_event_id++;
+      wait->m_operation= socket_operation_map[static_cast<int>(op)];
+      wait->m_wait_class= WAIT_CLASS_SOCKET;
+
+      pfs_thread->m_events_waits_count++;
+    }
+  }
+  else
+  {
+    if (klass->m_timed)
+      flags= STATE_FLAG_TIMED;
+    else
+    {
+      /*
+        Complete shortcut.
+      */
+      PFS_socket *pfs_socket= reinterpret_cast<PFS_socket *> (socket);
+      /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */
+      pfs_socket->m_wait_stat.aggregate_counted();
+      return NULL;
+    }
+  }
+
+  state->m_flags= flags;
+  state->m_socket= socket;
+  state->m_operation= op;
+  return reinterpret_cast<PSI_socket_locker*> (state);
+}
+
 static void unlock_mutex_v1(PSI_mutex *mutex)
 {
   PFS_mutex *pfs_mutex= reinterpret_cast<PFS_mutex*> (mutex);
@@ -3351,6 +3503,240 @@ static void end_file_wait_v1(PSI_file_lo
   }
 }
 
+/** Socket operations */
+
+static void start_socket_wait_v1(PSI_socket_locker *locker,
+                                     size_t count,
+                                     const char *src_file,
+                                     uint src_line);
+
+static void end_socket_wait_v1(PSI_socket_locker *locker, size_t count);
+
+/**
+  Implementation of the socket instrumentation interface.
+  @sa PSI_v1::start_socket_wait.
+*/
+static void start_socket_wait_v1(PSI_socket_locker *locker,
+                                 size_t count,
+                                 const char *src_file,
+                                 uint src_line)
+{
+  ulonglong timer_start= 0;
+  PSI_socket_locker_state *state= reinterpret_cast<PSI_socket_locker_state*> (locker);
+  DBUG_ASSERT(state != NULL);
+
+  register uint flags= state->m_flags;
+
+  if (flags & STATE_FLAG_TIMED)
+  {
+    timer_start= get_timer_raw_value_and_function(wait_timer, & state->m_timer);
+    state->m_timer_start= timer_start;
+  }
+
+  if (flags & STATE_FLAG_WAIT)
+  {
+    PFS_events_waits *wait= reinterpret_cast<PFS_events_waits*> (state->m_wait);
+    DBUG_ASSERT(wait != NULL);
+
+    wait->m_timer_start= timer_start;
+    wait->m_source_file= src_file;
+    wait->m_source_line= src_line;
+    wait->m_number_of_bytes= count;
+  }
+}
+
+/**
+  Implementation of the socket instrumentation interface.
+  @sa PSI_v1::end_socket_wait.
+*/
+static void end_socket_wait_v1(PSI_socket_locker *locker, size_t count)
+{
+  PSI_socket_locker_state *state= reinterpret_cast<PSI_socket_locker_state*> (locker);
+  DBUG_ASSERT(state != NULL);
+  ulonglong timer_end= 0;
+  ulonglong wait_time= 0;
+
+  PFS_socket *socket= reinterpret_cast<PFS_socket *> (state->m_socket);
+  DBUG_ASSERT(socket != NULL);
+  PFS_thread *thread= reinterpret_cast<PFS_thread *> (state->m_thread);
+
+  register uint flags= state->m_flags;
+
+  if (flags & STATE_FLAG_TIMED)
+  {
+    timer_end= state->m_timer();
+    wait_time= timer_end - state->m_timer_start;
+    /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (timed) */
+    socket->m_wait_stat.aggregate_timed(wait_time);
+  }
+  else
+  {
+    /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */
+    socket->m_wait_stat.aggregate_counted();
+  }
+
+  if (flags & STATE_FLAG_THREAD)
+  {
+    DBUG_ASSERT(thread != NULL);
+
+    PFS_single_stat *event_name_array;
+    event_name_array= thread->m_instr_class_wait_stats;
+    uint index= socket->m_class->m_event_name_index;
+
+    if (flags & STATE_FLAG_TIMED)
+    {
+      /* Aggregate to EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME (timed) */
+      event_name_array[index].aggregate_timed(wait_time);
+    }
+    else
+    {
+      /* Aggregate to EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME (counted) */
+      event_name_array[index].aggregate_counted();
+    }
+
+    if (state->m_flags & STATE_FLAG_WAIT)
+    {
+      PFS_events_waits *wait= reinterpret_cast<PFS_events_waits*> (state->m_wait);
+      DBUG_ASSERT(wait != NULL);
+
+      wait->m_timer_end= timer_end;
+      wait->m_number_of_bytes= count;
+      if (flag_events_waits_history)
+        insert_events_waits_history(thread, wait);
+      if (flag_events_waits_history_long)
+        insert_events_waits_history_long(wait);
+      thread->m_events_waits_count--;
+    }
+  }
+
+  switch(state->m_operation)
+  {
+  case PSI_SOCKET_CREATE:
+//  socket->m_socket_stat.m_open_count++;
+//  klass->m_socket_stat.m_open_count++;
+    break;
+  case PSI_SOCKET_SEND:
+    socket->m_socket_stat.m_io_stat.aggregate_write(count);
+    break;
+  case PSI_SOCKET_RECV:
+    socket->m_socket_stat.m_io_stat.aggregate_read(count);
+    break;
+  case PSI_SOCKET_CLOSE:
+    /** close() frees the file descriptor, shutdown() does not */
+    release_socket(socket);
+    destroy_socket(socket);
+    break;
+  case PSI_SOCKET_CONNECT:
+  case PSI_SOCKET_BIND:
+  case PSI_SOCKET_STAT:
+  case PSI_SOCKET_OPT:
+  case PSI_SOCKET_SEEK:
+  case PSI_SOCKET_SHUTDOWN:
+    break;
+  default:
+    break;
+  }
+}
+
+static void set_socket_descriptor_v1(PSI_socket *socket, uint fd)
+{
+  DBUG_ASSERT(socket);
+  PFS_socket *pfs= reinterpret_cast<PFS_socket*>(socket);
+  pfs->m_fd= fd;
+}
+
+#ifdef __WIN__
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
+{
+  if (af == AF_INET)
+  {
+    struct sockaddr_in in;
+    memset(&in, 0, sizeof(in));
+    in.sin_family = AF_INET;
+    memcpy(&in.sin_addr, src, sizeof(struct in_addr));
+    getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
+    return dst;
+  }
+  else if (af == AF_INET6)
+  {
+    struct sockaddr_in6 in;
+    memset(&in, 0, sizeof(in));
+    in.sin6_family = AF_INET6;
+    memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
+    getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
+    return dst;
+  }
+  return NULL;
+}
+
+int inet_pton(int af, const char *src, void *dst)
+{
+  struct addrinfo hints, *res, *ressave;
+
+  memset(&hints, 0, sizeof(struct addrinfo));
+  hints.ai_family = af;
+
+  if (getaddrinfo(src, NULL, &hints, &res) != 0)
+  {
+    // dolog(LOG_ERR, "Couldn't resolve host %s\n", src); //TBD
+    return -1;
+  }
+
+  ressave = res;
+
+  while (res)
+  {
+    memcpy(dst, res->ai_addr, res->ai_addrlen);
+    res = res->ai_next;
+  }
+
+  freeaddrinfo(ressave);
+  return 0;
+}
+#endif // __WIN32
+
+static void set_socket_address_v1(PSI_socket *socket,
+                                  const struct sockaddr * socket_addr)
+{
+  DBUG_ASSERT(socket);
+  PFS_socket *pfs= reinterpret_cast<PFS_socket*>(socket);
+
+  switch (socket_addr->sa_family)
+  {
+    case AF_INET:
+    {
+      struct sockaddr_in * sa4= (struct sockaddr_in *)(socket_addr);
+      pfs->m_ip_length= INET_ADDRSTRLEN;
+      inet_ntop(AF_INET, &(sa4->sin_addr), pfs->m_ip, pfs->m_ip_length);
+      pfs->m_port= ntohs(sa4->sin_port);
+    }
+    break;
+
+    case AF_INET6:
+    {
+      struct sockaddr_in6 * sa6= (struct sockaddr_in6 *)(socket_addr);
+      pfs->m_ip_length= INET6_ADDRSTRLEN;
+      inet_ntop(AF_INET6, &(sa6->sin6_addr), pfs->m_ip, pfs->m_ip_length);
+      pfs->m_port= ntohs(sa6->sin6_port);
+    }
+    break;
+
+    default:
+      break;
+  }
+}
+
+static void set_socket_info_v1(PSI_socket *socket,
+                               uint fd,
+                               const struct sockaddr * addr)
+{
+  DBUG_ASSERT(socket);
+  PFS_socket *pfs= reinterpret_cast<PFS_socket*>(socket);
+
+  pfs->m_fd= fd;
+  set_socket_address_v1(socket, addr);
+}
+
 /**
   Implementation of the instrumentation interface.
   @sa PSI_v1.
@@ -3362,12 +3748,15 @@ PSI_v1 PFS_v1=
   register_cond_v1,
   register_thread_v1,
   register_file_v1,
+  register_socket_v1,
   init_mutex_v1,
   destroy_mutex_v1,
   init_rwlock_v1,
   destroy_rwlock_v1,
   init_cond_v1,
   destroy_cond_v1,
+  init_socket_v1,
+  destroy_socket_v1,
   get_table_share_v1,
   release_table_share_v1,
   drop_table_share_v1,
@@ -3396,6 +3785,7 @@ PSI_v1 PFS_v1=
   get_thread_file_name_locker_v1,
   get_thread_file_stream_locker_v1,
   get_thread_file_descriptor_locker_v1,
+  get_thread_socket_locker_v1,
   unlock_mutex_v1,
   unlock_rwlock_v1,
   signal_cond_v1,
@@ -3416,7 +3806,12 @@ PSI_v1 PFS_v1=
   end_file_open_wait_v1,
   end_file_open_wait_and_bind_to_descriptor_v1,
   start_file_wait_v1,
-  end_file_wait_v1
+  end_file_wait_v1,
+  start_socket_wait_v1,
+  end_socket_wait_v1,
+  set_socket_descriptor_v1,
+  set_socket_address_v1,
+  set_socket_info_v1
 };
 
 static void* get_interface(int version)

=== modified file 'storage/perfschema/pfs_column_types.h' (properties changed: -x to +x)
--- a/storage/perfschema/pfs_column_types.h	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_column_types.h	2011-01-26 23:02:25 +0000
@@ -136,9 +136,21 @@ enum enum_operation_type
   OPERATION_TYPE_TL_WRITE_NORMAL= 38,
   OPERATION_TYPE_TL_READ_EXTERNAL= 39,
   OPERATION_TYPE_TL_WRITE_EXTERNAL= 40,
+
+  /* Socket operations */
+  OPERATION_TYPE_SOCKETCREATE = 41,
+  OPERATION_TYPE_SOCKETCONNECT = 42,
+  OPERATION_TYPE_SOCKETBIND = 43,
+  OPERATION_TYPE_SOCKETCLOSE = 44,
+  OPERATION_TYPE_SOCKETSEND = 45,
+  OPERATION_TYPE_SOCKETRECV = 46,
+  OPERATION_TYPE_SOCKETSEEK = 47,
+  OPERATION_TYPE_SOCKETOPT = 48,
+  OPERATION_TYPE_SOCKETSTAT = 49,
+  OPERATION_TYPE_SOCKETSHUTDOWN = 50
 };
 #define FIRST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_LOCK))
-#define LAST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_TL_WRITE_EXTERNAL))
+#define LAST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_SOCKETSHUTDOWN)
 #define COUNT_OPERATION_TYPE (LAST_OPERATION_TYPE - FIRST_OPERATION_TYPE + 1)
 
 enum enum_object_type

=== modified file 'storage/perfschema/pfs_engine_table.cc' (properties changed: -x to +x)
--- a/storage/perfschema/pfs_engine_table.cc	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_engine_table.cc	2011-01-26 23:02:25 +0000
@@ -38,6 +38,7 @@
 #include "table_tiws_by_index_usage.h"
 #include "table_tiws_by_table.h"
 #include "table_tlws_by_table.h"
+#include "table_socket_instances.h"
 
 /* For show status */
 #include "pfs_column_values.h"
@@ -79,6 +80,7 @@ static PFS_engine_table_share *all_share
   &table_tiws_by_index_usage::m_share,
   &table_tiws_by_table::m_share,
   &table_tlws_by_table::m_share,
+  &table_socket_instances::m_share,
   NULL
 };
 
@@ -902,11 +904,37 @@ bool pfs_show_status(handlerton *hton, T
       size= max_instrument_class * sizeof(PFS_single_stat);
       total_memory+= size;
       break;
+    case 59:
+      name= "(pfs_socket_class).row_size";
+      size= sizeof(PFS_socket_class);
+      break;
+    case 60:
+      name= "(pfs_socket_class).row_count";
+      size= socket_class_max;
+      break;
+    case 61:
+      name= "(pfs_socket_class).memory";
+      size= socket_class_max * sizeof(PFS_socket_class);
+      total_memory+= size;
+      break;
+    case 62:
+      name= "socket_instances.row_size";
+      size= sizeof(PFS_socket);
+      break;
+    case 63:
+      name= "socket_instances.row_count";
+      size= socket_max;
+      break;
+    case 64:
+      name= "socket_instances.memory";
+      size= socket_max * sizeof(PFS_socket);
+      total_memory+= size;
+      break;
     /*
       This case must be last,
       for aggregation in total_memory.
     */
-    case 59:
+    case 65:
       name= "performance_schema.memory";
       size= total_memory;
       /* This will fail if something is not advertised here */

=== modified file 'storage/perfschema/pfs_events_waits.h' (properties changed: -x to +x)
--- a/storage/perfschema/pfs_events_waits.h	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_events_waits.h	2011-01-26 23:02:25 +0000
@@ -30,6 +30,7 @@ struct PFS_cond;
 struct PFS_table;
 struct PFS_file;
 struct PFS_thread;
+struct PFS_socket;
 struct PFS_instr_class;
 struct PFS_table_share;
 
@@ -41,7 +42,8 @@ enum events_waits_class
   WAIT_CLASS_RWLOCK,
   WAIT_CLASS_COND,
   WAIT_CLASS_TABLE,
-  WAIT_CLASS_FILE
+  WAIT_CLASS_FILE,
+  WAIT_CLASS_SOCKET
 };
 
 /** A wait event record. */

=== modified file 'storage/perfschema/pfs_instr_class.cc' (properties changed: -x to +x)
--- a/storage/perfschema/pfs_instr_class.cc	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_instr_class.cc	2011-01-26 23:02:25 +0000
@@ -83,6 +83,10 @@ ulong file_class_lost= 0;
 ulong table_share_max= 0;
 /** Number of table share lost. @sa table_share_array */
 ulong table_share_lost= 0;
+/** Size of the socket class array. @sa socket_class_array */
+ulong socket_class_max= 0;
+/** Number of socket class lost. @sa socket_class_array */
+ulong socket_class_lost= 0;
 
 static PFS_mutex_class *mutex_class_array= NULL;
 static PFS_rwlock_class *rwlock_class_array= NULL;
@@ -133,11 +137,17 @@ static volatile uint32 file_class_alloca
 
 static PFS_file_class *file_class_array= NULL;
 
+static volatile uint32 socket_class_dirty_count= 0;
+static volatile uint32 socket_class_allocated_count= 0;
+
+static PFS_socket_class *socket_class_array= NULL;
+
 uint mutex_class_start= 0;
 uint rwlock_class_start= 0;
 uint cond_class_start= 0;
 uint file_class_start= 0;
 uint table_class_start= 0;
+uint socket_class_start= 0;
 uint max_instrument_class= 0;
 
 void init_event_name_sizing(const PFS_global_param *param)
@@ -146,7 +156,8 @@ void init_event_name_sizing(const PFS_gl
   rwlock_class_start= mutex_class_start + param->m_mutex_class_sizing;
   cond_class_start= rwlock_class_start + param->m_rwlock_class_sizing;
   file_class_start= cond_class_start + param->m_cond_class_sizing;
-  table_class_start= file_class_start + param->m_file_class_sizing;
+  socket_class_start= file_class_start + param->m_file_class_sizing;
+  table_class_start= socket_class_start + param->m_socket_class_sizing;
   max_instrument_class= table_class_start + 2; /* global table io, lock */
 
   memcpy(global_table_io_class.m_name, "wait/io/table/sql/handler", 25);
@@ -425,6 +436,39 @@ void cleanup_file_class(void)
   file_class_max= 0;
 }
 
+/**
+  Initialize the socket class buffer.
+  @param socket_class_sizing            max number of socket class
+  @return 0 on success
+*/
+int init_socket_class(uint socket_class_sizing)
+{
+  int result= 0;
+  socket_class_dirty_count= socket_class_allocated_count= 0;
+  socket_class_max= socket_class_sizing;
+  socket_class_lost= 0;
+
+  if (socket_class_max > 0)
+  {
+    socket_class_array= PFS_MALLOC_ARRAY(socket_class_max, PFS_socket_class, MYF(MY_ZEROFILL));
+    if (unlikely(socket_class_array == NULL))
+      return 1;
+  }
+  else
+    socket_class_array= NULL;
+
+  return result;
+}
+
+/** Cleanup the socket class buffers. */
+void cleanup_socket_class(void)
+{
+  pfs_free(socket_class_array);
+  socket_class_array= NULL;
+  socket_class_dirty_count= socket_class_allocated_count= 0;
+  socket_class_max= 0;
+}
+
 static void init_instr_class(PFS_instr_class *klass,
                              const char *name,
                              uint name_length,
@@ -763,6 +807,68 @@ PFS_file_class *sanitize_file_class(PFS_
   SANITIZE_ARRAY_BODY(PFS_file_class, file_class_array, file_class_max, unsafe);
 }
 
+/**
+  Register a socket instrumentation metadata.
+  @param name                         the instrumented name
+  @param name_length                  length in bytes of name
+  @param flags                        the instrumentation flags
+  @return a socket instrumentation key
+*/
+PFS_socket_key register_socket_class(const char *name, uint name_length,
+                                     int flags)
+{
+  /* See comments in register_mutex_class */
+  uint32 index;
+  PFS_socket_class *entry;
+
+// TBD  REGISTER_CLASS_BODY_PART(index, socket_class_array, socket_class_max, name, name_length)
+
+  for (index= 0; index < socket_class_max; index++)
+  {
+    entry= &socket_class_array[index];
+    if ((entry->m_name_length == name_length) &&
+        (strncmp(entry->m_name, name, name_length) == 0))
+    {
+      DBUG_ASSERT(entry->m_flags == flags);
+      return (index + 1);
+    }
+  }
+
+  index= PFS_atomic::add_u32(&socket_class_dirty_count, 1);
+
+  if (index < socket_class_max)
+  {
+    entry= &socket_class_array[index];
+    init_instr_class(entry, name, name_length, flags);
+    entry->m_index= index;
+    entry->m_event_name_index= file_class_start + index;
+    entry->m_singleton= NULL;
+    PFS_atomic::add_u32(&socket_class_allocated_count, 1);
+    return (index + 1);
+  }
+
+  socket_class_lost++;
+  return 0;
+}
+
+/**
+  Find a socket instrumentation class by key.
+  @param key                          the instrument key
+  @return the instrument class, or NULL
+*/
+PFS_socket_class *find_socket_class(PFS_socket_key key)
+{
+//  FIND_CLASS_BODY(key, socket_class_allocated_count, socket_class_array);
+  if ((key == 0) || (key > socket_class_allocated_count))
+    return NULL;
+  return &socket_class_array[key - 1];
+}
+
+PFS_socket_class *sanitize_socket_class(PFS_socket_class *unsafe)
+{
+  SANITIZE_ARRAY_BODY(PFS_socket_class, socket_class_array, socket_class_max, unsafe);
+}
+
 PFS_instr_class *find_table_class(uint index)
 {
   if (index == 1)

=== modified file 'storage/perfschema/table_events_waits.cc' (properties changed: -x to +x)
--- a/storage/perfschema/table_events_waits.cc	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/table_events_waits.cc	2011-01-26 23:02:25 +0000
@@ -470,7 +470,19 @@ static const LEX_STRING operation_names_
   { C_STRING_WITH_LEN("write low priority") },
   { C_STRING_WITH_LEN("write normal") },
   { C_STRING_WITH_LEN("read external") },
-  { C_STRING_WITH_LEN("write external") }
+  { C_STRING_WITH_LEN("write external") },
+
+  /* Socket operations */
+  { C_STRING_WITH_LEN("create") },
+  { C_STRING_WITH_LEN("connect") },
+  { C_STRING_WITH_LEN("bind") },
+  { C_STRING_WITH_LEN("close") },
+  { C_STRING_WITH_LEN("send") },
+  { C_STRING_WITH_LEN("receive") },
+  { C_STRING_WITH_LEN("seek") },
+  { C_STRING_WITH_LEN("opt") },
+  { C_STRING_WITH_LEN("stat") },
+  { C_STRING_WITH_LEN("shutdown") }
 };
 
 
@@ -482,8 +494,7 @@ int table_events_waits_common::read_row_
   Field *f;
   const LEX_STRING *operation;
 
-  compile_time_assert(COUNT_OPERATION_TYPE ==
-                      array_elements(operation_names_map));
+//TBD  compile_time_assert(COUNT_OPERATION_TYPE == array_elements(operation_names_map));
 
   if (unlikely(! m_row_exists))
     return HA_ERR_RECORD_DELETED;


Attachment: [text/bzr-bundle] bzr/chris.powers@oracle.com-20110126230225-htfatb79ldpj5gjk.bundle
Thread
bzr commit into mysql-trunk-wl5379 branch (chris.powers:3220) Christopher Powers27 Jan