List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:February 7 2011 10:18pm
Subject:bzr push into mysql-trunk-wl5379 branch (chris.powers:3220 to 3225) WL#4896
View as plain text  
 3225 Christopher Powers	2011-02-07
      WL#4896 "Performance Schema Net IO"
      
      - Fixed warning in pfs.cc
      - Updated abi_check.out files

    modified:
      include/mysql/psi/psi_abi_v1.h.pp
      include/mysql/psi/psi_abi_v2.h.pp
      storage/perfschema/pfs.cc
 3224 cpowers	2011-02-07
      WL#4896 "Performance Schema Net IO"
      
      - Addd socket_summary_by_instance to mysql_system_tables.sql

    modified:
      scripts/mysql_system_tables.sql
 3223 cpowers	2011-02-07
      WL#4896 "Performance Schema Net IO"
      
      - Build fixes
      - Added visitor calls

    modified:
      scripts/mysql_system_tables.sql
      storage/perfschema/pfs.cc
      storage/perfschema/pfs_instr.cc
      storage/perfschema/pfs_instr_class.cc
      storage/perfschema/pfs_instr_class.h
      storage/perfschema/pfs_stat.h
      storage/perfschema/pfs_visitor.cc
      storage/perfschema/pfs_visitor.h
      storage/perfschema/table_setup_instruments.cc
 3222 cpowers	2011-02-07
      WL#4896 "Performance Schema Net IO"
      
      - Merge w/ local Linux repository

    modified:
      include/mysql/psi/psi.h
      include/mysql/psi/psi_abi_v1.h.pp
      storage/perfschema/pfs.cc
      storage/perfschema/pfs_column_types.h
      storage/perfschema/pfs_instr.cc
      storage/perfschema/pfs_instr.h
      storage/perfschema/pfs_instr_class.cc
      storage/perfschema/pfs_instr_class.h
      storage/perfschema/pfs_stat.h
      storage/perfschema/table_events_waits.cc
      storage/perfschema/table_events_waits_summary.cc
      storage/perfschema/table_helper.h
      storage/perfschema/table_socket_instances.cc
      storage/perfschema/table_socket_instances.h
 3221 Christopher Powers	2011-02-04
      WL#4896 "Peformance Schema Net IO"
      
      - Intermediate version
      - Added table socket_summary_by_instance
      - Updates per worklog review

    added:
      storage/perfschema/table_socket_summary_by_instance.cc
      storage/perfschema/table_socket_summary_by_instance.h
    modified:
      include/mysql/psi/mysql_socket.h*
      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*
 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 'include/mysql/psi/mysql_socket.h' (properties changed: +x to -x)
=== modified file 'include/mysql/psi/psi.h'
--- a/include/mysql/psi/psi.h	2011-01-26 22:26:41 +0000
+++ b/include/mysql/psi/psi.h	2011-02-07 19:17:08 +0000
@@ -276,18 +276,26 @@ enum PSI_socket_operation
   PSI_SOCKET_BIND= 2,
   /** Socket close, as in @c shutdown(). */
   PSI_SOCKET_CLOSE= 3,
-  /** Generic socket send, such as @c send(), @c sendto(), @c sendmsg(). */
+  /** Socket send, @c send(). */
   PSI_SOCKET_SEND= 4,
-  /** Generic socket receive, such as @c recv(), @c recvfrom), @c recvmsg(). */
+  /** Socket receive, @c recv(). */
   PSI_SOCKET_RECV= 5,
-  /** Generic socket seek, such as @c fseek() or @c seek(). */
-  PSI_SOCKET_SEEK= 6,
+  /** Socket send, @c sendto(). */
+  PSI_SOCKET_SENDTO= 6,
+  /** Socket receive, @c recvfrom). */
+  PSI_SOCKET_RECVFROM= 7,
+  /** Socket send, @c sendmsg(). */
+  PSI_SOCKET_SENDMSG= 8,
+  /** Socket receive, @c recvmsg(). */
+  PSI_SOCKET_RECVMSG= 9,
+  /** Socket seek, such as @c fseek() or @c seek(). */
+  PSI_SOCKET_SEEK= 10,
   /** Socket options, as in @c getsockopt() and @c setsockopt(). */
-  PSI_SOCKET_OPT= 7,
+  PSI_SOCKET_OPT= 11,
   /** Socket status, as in @c sockatmark() and @c isfdtype(). */
-  PSI_SOCKET_STAT= 8,
+  PSI_SOCKET_STAT= 12,
   /** Socket shutdown, as in @c shutdown(). */
-  PSI_SOCKET_SHUTDOWN= 9
+  PSI_SOCKET_SHUTDOWN= 13
 };
 
 /**
@@ -1078,6 +1086,7 @@ typedef struct PSI_file_locker* (*get_th
 typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
   (struct PSI_file_locker_state_v1 *state,
    File file, enum PSI_file_operation op);
+
 /**
   Get a socket instrumentation locker.
   @param state data storage for the locker

=== modified file 'include/mysql/psi/psi_abi_v1.h.pp'
--- a/include/mysql/psi/psi_abi_v1.h.pp	2011-01-26 22:26:41 +0000
+++ b/include/mysql/psi/psi_abi_v1.h.pp	2011-02-07 22:17:15 +0000
@@ -75,10 +75,14 @@ enum PSI_socket_operation
   PSI_SOCKET_CLOSE= 3,
   PSI_SOCKET_SEND= 4,
   PSI_SOCKET_RECV= 5,
-  PSI_SOCKET_SEEK= 6,
-  PSI_SOCKET_OPT= 7,
-  PSI_SOCKET_STAT= 8,
-  PSI_SOCKET_SHUTDOWN= 9
+  PSI_SOCKET_SENDTO= 6,
+  PSI_SOCKET_RECVFROM= 7,
+  PSI_SOCKET_SENDMSG= 8,
+  PSI_SOCKET_RECVMSG= 9,
+  PSI_SOCKET_SEEK= 10,
+  PSI_SOCKET_OPT= 11,
+  PSI_SOCKET_STAT= 12,
+  PSI_SOCKET_SHUTDOWN= 13
 };
 typedef unsigned int PSI_mutex_key;
 typedef unsigned int PSI_rwlock_key;

=== modified file 'include/mysql/psi/psi_abi_v2.h.pp'
--- a/include/mysql/psi/psi_abi_v2.h.pp	2011-01-26 22:26:41 +0000
+++ b/include/mysql/psi/psi_abi_v2.h.pp	2011-02-07 22:17:15 +0000
@@ -75,10 +75,14 @@ enum PSI_socket_operation
   PSI_SOCKET_CLOSE= 3,
   PSI_SOCKET_SEND= 4,
   PSI_SOCKET_RECV= 5,
-  PSI_SOCKET_SEEK= 6,
-  PSI_SOCKET_OPT= 7,
-  PSI_SOCKET_STAT= 8,
-  PSI_SOCKET_SHUTDOWN= 9
+  PSI_SOCKET_SENDTO= 6,
+  PSI_SOCKET_RECVFROM= 7,
+  PSI_SOCKET_SENDMSG= 8,
+  PSI_SOCKET_RECVMSG= 9,
+  PSI_SOCKET_SEEK= 10,
+  PSI_SOCKET_OPT= 11,
+  PSI_SOCKET_STAT= 12,
+  PSI_SOCKET_SHUTDOWN= 13
 };
 typedef unsigned int PSI_mutex_key;
 typedef unsigned int PSI_rwlock_key;

=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql	2011-01-26 22:26:41 +0000
+++ b/scripts/mysql_system_tables.sql	2011-02-07 21:36:49 +0000
@@ -164,7 +164,7 @@ DROP PREPARE stmt;
 
 --
 -- From this point, only create the performance schema tables
--- if the server is build with performance schema
+-- if the server is built with performance schema
 --
 
 set @have_pfs= (select count(engine) from information_schema.engines where engine='PERFORMANCE_SCHEMA' and support != 'NO');
@@ -380,22 +380,121 @@ DROP PREPARE stmt;
 -- TABLE SOCKET_INSTANCES
 --
 
-SET @l1="CREATE TABLE performance_schema.socket_instances(";
-SET @l2="EVENT_NAME varchar(128) not null,";
-SET @l3="OBJECT_INSTANCE_BEGIN bigint(20) not null,";
-SET @l4="SOCKET_ID int(11) not null,";
-SET @l5="IP varchar(128) not null,";
-SET @l6="PORT int(11) not null,";
-SET @l7="BYTES_READ bigint(20) not null,";
-SET @l8="BYTES_WRITE bigint(20) not null";
-SET @l9=")ENGINE=PERFORMANCE_SCHEMA;";
-SET @cmd=concat(@l1,@l2,@l3,@l4,@l5,@l6,@l7,@l8,@l9);
+SET @cmd="CREATE TABLE performance_schema.socket_instances("
+  "EVENT_NAME VARCHAR(128),"
+  "OBJECT_INSTANCE_BEGIN BIGINT unsigned,"
+  "THREAD_ID INTEGER,"
+  "SOCKET_ID INTEGER,"
+  "IP VARCHAR(64),"
+  "PORT INTEGER"
+  ")ENGINE=PERFORMANCE_SCHEMA;";
 
 SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
 PREPARE stmt FROM @str;
 EXECUTE stmt;
 DROP PREPARE stmt;
 
+--
+-- TABLE SOCKET_SUMMARY_BY_INSTANCE
+--
+
+SET @cmd="CREATE TABLE performance_schema.socket_summary_by_instance("
+  "EVENT_NAME VARCHAR(128),"
+  "OBJECT_INSTANCE_BEGIN BIGINT unsigned not null,"
+  "OBJECT_NAME VARCHAR(64),"
+  "COUNT_STAR BIGINT unsigned not null,"
+  "SUM_TIMER_WAIT BIGINT unsigned not null,"
+  "MIN_TIMER_WAIT BIGINT unsigned not null,"
+  "AVG_TIMER_WAIT BIGINT unsigned not null,"
+  "MAX_TIMER_WAIT BIGINT unsigned not null,"
+  "COUNT_READ BIGINT unsigned not null,"
+  "SUM_TIMER_READ BIGINT unsigned not null,"
+  "MIN_TIMER_READ BIGINT unsigned not null,"
+  "AVG_TIMER_READ BIGINT unsigned not null,"
+  "MAX_TIMER_READ BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_READ BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_READ BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_READ BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_READ BIGINT unsigned not null,"
+  "COUNT_WRITE BIGINT unsigned not null,"
+  "SUM_TIMER_WRITE BIGINT unsigned not null,"
+  "MIN_TIMER_WRITE BIGINT unsigned not null,"
+  "AVG_TIMER_WRITE BIGINT unsigned not null,"
+  "MAX_TIMER_WRITE BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_WRITE BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_WRITE BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_WRITE BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_WRITE BIGINT unsigned not null,"
+  "COUNT_RECV BIGINT unsigned not null,"
+  "SUM_TIMER_RECV BIGINT unsigned not null,"
+  "MIN_TIMER_RECV BIGINT unsigned not null,"
+  "AVG_TIMER_RECV BIGINT unsigned not null,"
+  "MAX_TIMER_RECV BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_RECV BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_RECV BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_RECV BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_RECV BIGINT unsigned not null,"
+  "COUNT_SEND BIGINT unsigned not null,"
+  "SUM_TIMER_SEND BIGINT unsigned not null,"
+  "MIN_TIMER_SEND BIGINT unsigned not null,"
+  "AVG_TIMER_SEND BIGINT unsigned not null,"
+  "MAX_TIMER_SEND BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_SEND BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_SEND BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_SEND BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_SEND BIGINT unsigned not null,"
+  "COUNT_RECVFROM BIGINT unsigned not null,"
+  "SUM_TIMER_RECVFROM BIGINT unsigned not null,"
+  "MIN_TIMER_RECVFROM BIGINT unsigned not null,"
+  "AVG_TIMER_RECVFROM BIGINT unsigned not null,"
+  "MAX_TIMER_RECVFROM BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_RECVFROM BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_RECVFROM BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_RECVFROM BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_RECVFROM BIGINT unsigned not null,"
+  "COUNT_SENDTO BIGINT unsigned not null,"
+  "SUM_TIMER_SENDTO BIGINT unsigned not null,"
+  "MIN_TIMER_SENDTO BIGINT unsigned not null,"
+  "AVG_TIMER_SENDTO BIGINT unsigned not null,"
+  "MAX_TIMER_SENDTO BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_SENDTO BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_SENDTO BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_SENDTO BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_SENDTO BIGINT unsigned not null,"
+  "COUNT_RECVMSG BIGINT unsigned not null,"
+  "SUM_TIMER_RECVMSG BIGINT unsigned not null,"
+  "MIN_TIMER_RECVMSG BIGINT unsigned not null,"
+  "AVG_TIMER_RECVMSG BIGINT unsigned not null,"
+  "MAX_TIMER_RECVMSG BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_RECVMSG BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_RECVMSG BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_RECVMSG BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_RECVMSG BIGINT unsigned not null,"
+  "COUNT_SENDMSG BIGINT unsigned not null,"
+  "SUM_TIMER_SENDMSG BIGINT unsigned not null,"
+  "MIN_TIMER_SENDMSG BIGINT unsigned not null,"
+  "AVG_TIMER_SENDMSG BIGINT unsigned not null,"
+  "MAX_TIMER_SENDMSG BIGINT unsigned not null,"
+  "SUM_NUMBER_OF_BYTES_SENDMSG BIGINT unsigned not null,"
+  "MIN_NUMBER_OF_BYTES_SENDMSG BIGINT unsigned not null,"
+  "AVG_NUMBER_OF_BYTES_SENDMSG BIGINT unsigned not null,"
+  "MAX_NUMBER_OF_BYTES_SENDMSG BIGINT unsigned not null,"
+  "COUNT_CONNECT BIGINT unsigned not null,"
+  "SUM_TIMER_CONNECT BIGINT unsigned not null,"
+  "MIN_TIMER_CONNECT BIGINT unsigned not null,"
+  "AVG_TIMER_CONNECT BIGINT unsigned not null,"
+  "MAX_TIMER_CONNECT BIGINT unsigned not null,"
+  "COUNT_MISC BIGINT unsigned not null,"
+  "SUM_TIMER_MISC BIGINT unsigned not null,"
+  "MIN_TIMER_MISC BIGINT unsigned not null,"
+  "AVG_TIMER_MISC BIGINT unsigned not null,"
+  "MAX_TIMER_MISC BIGINT unsigned not null"
+  ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
 
 --
 -- TABLE MUTEX_INSTANCES

=== modified file 'storage/perfschema/pfs.cc' (properties changed: +x to -x)
--- a/storage/perfschema/pfs.cc	2011-01-26 23:02:25 +0000
+++ b/storage/perfschema/pfs.cc	2011-02-07 22:17:15 +0000
@@ -998,6 +998,10 @@ static enum_operation_type socket_operat
   OPERATION_TYPE_SOCKETCLOSE,
   OPERATION_TYPE_SOCKETSEND,
   OPERATION_TYPE_SOCKETRECV,
+  OPERATION_TYPE_SOCKETSENDTO,
+  OPERATION_TYPE_SOCKETRECVFROM,
+  OPERATION_TYPE_SOCKETSENDMSG,
+  OPERATION_TYPE_SOCKETRECVMSG,
   OPERATION_TYPE_SOCKETSEEK,
   OPERATION_TYPE_SOCKETOPT,
   OPERATION_TYPE_SOCKETSTAT,
@@ -1297,21 +1301,7 @@ static void close_table_v1(PSI_table *ta
 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);
+  INIT_BODY_V1(socket, key, identity);
 }
 
 static void destroy_socket_v1(PSI_socket* socket)
@@ -1817,10 +1807,13 @@ get_thread_rwlock_locker_v1(PSI_rwlock_l
   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;
 
@@ -2534,29 +2527,22 @@ 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);
+  PFS_socket *pfs_socket= reinterpret_cast<PFS_socket*> (socket);
   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);
@@ -2592,8 +2578,8 @@ get_thread_socket_locker_v1(PSI_socket_l
       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_object_name= pfs_socket->m_ip;   // TBD: Where is object_name defined?
+   // 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;
@@ -2604,13 +2590,16 @@ get_thread_socket_locker_v1(PSI_socket_l
   else
   {
     if (klass->m_timed)
+    {
       flags= STATE_FLAG_TIMED;
+      state->m_thread= NULL;
+    }
     else
     {
       /*
         Complete shortcut.
       */
-      PFS_socket *pfs_socket= reinterpret_cast<PFS_socket *> (socket);
+      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;
@@ -3518,14 +3507,13 @@ static void end_socket_wait_v1(PSI_socke
 */
 static void start_socket_wait_v1(PSI_socket_locker *locker,
                                  size_t count,
-                                 const char *src_file,
-                                 uint src_line)
+                                 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;
+  ulonglong timer_start= 0;
 
   if (flags & STATE_FLAG_TIMED)
   {
@@ -3541,7 +3529,7 @@ static void start_socket_wait_v1(PSI_soc
     wait->m_timer_start= timer_start;
     wait->m_source_file= src_file;
     wait->m_source_line= src_line;
-    wait->m_number_of_bytes= count;
+    wait->m_number_of_bytes= count; // TBD: Get this from end_socket_wait()
   }
 }
 
@@ -3549,7 +3537,7 @@ static void start_socket_wait_v1(PSI_soc
   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)
+static void end_socket_wait_v1(PSI_socket_locker *locker, size_t byte_count)
 {
   PSI_socket_locker_state *state= reinterpret_cast<PSI_socket_locker_state*> (locker);
   DBUG_ASSERT(state != NULL);
@@ -3558,7 +3546,58 @@ static void end_socket_wait_v1(PSI_socke
 
   PFS_socket *socket= reinterpret_cast<PFS_socket *> (state->m_socket);
   DBUG_ASSERT(socket != NULL);
-  PFS_thread *thread= reinterpret_cast<PFS_thread *> (state->m_thread);
+
+  PFS_single_stat *time_stat;
+  PFS_single_stat *io_stat;
+
+  switch (state->m_operation)
+  {
+  case PSI_SOCKET_CONNECT:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_connect.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_connect.m_bytes;
+    break;
+  case PSI_SOCKET_RECV:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_recv.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_recv.m_bytes;
+    break;
+  case PSI_SOCKET_SEND:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_send.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_send.m_bytes;
+    break;
+  case PSI_SOCKET_RECVFROM:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_recvfrom.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_recvfrom.m_bytes;
+    break;
+  case PSI_SOCKET_SENDTO:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_sendto.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_sendto.m_bytes;
+    break;
+  case PSI_SOCKET_RECVMSG:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_recvmsg.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_recvmsg.m_bytes;
+    break;
+  case PSI_SOCKET_SENDMSG:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_sendmsg.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_sendmsg.m_bytes;
+    break;
+
+  /** These operations are grouped as 'miscellaneous' */
+  case PSI_SOCKET_CREATE:
+  case PSI_SOCKET_BIND:
+  case PSI_SOCKET_CLOSE:
+  case PSI_SOCKET_SEEK:
+  case PSI_SOCKET_OPT:
+  case PSI_SOCKET_STAT:
+  case PSI_SOCKET_SHUTDOWN:
+    time_stat= &socket->m_socket_stat.m_io_stat.m_misc.m_waits;
+    io_stat= &socket->m_socket_stat.m_io_stat.m_misc.m_bytes;
+    break;
+  default:
+    DBUG_ASSERT(false);
+    io_stat= NULL;
+    time_stat= NULL;
+    break;
+  }
 
   register uint flags= state->m_flags;
 
@@ -3566,76 +3605,33 @@ static void end_socket_wait_v1(PSI_socke
   {
     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);
+    time_stat->aggregate_timed(wait_time);
   }
   else
   {
-    /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */
-    socket->m_wait_stat.aggregate_counted();
+    time_stat->aggregate_counted();
   }
 
-  if (flags & STATE_FLAG_THREAD)
+  if (flags & STATE_FLAG_WAIT)
   {
+    DBUG_ASSERT(flags & STATE_FLAG_THREAD);
+    PFS_thread *thread= reinterpret_cast<PFS_thread *> (state->m_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);
+    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--;
-    }
+    wait->m_timer_end= timer_end;
+    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;
-  }
+  /** Aggregate the number of bytes for the operation */
+  if ((int)byte_count > -1)
+    io_stat->aggregate_timed(byte_count);
 }
 
 static void set_socket_descriptor_v1(PSI_socket *socket, uint fd)
@@ -3646,6 +3642,10 @@ static void set_socket_descriptor_v1(PSI
 }
 
 #ifdef __WIN__
+/**
+  inet_ntop() and inet_pton() do not exist in Windows. They are defined here
+  for convenience.
+*/
 const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
 {
   if (af == AF_INET)

=== modified file 'storage/perfschema/pfs_column_types.h' (properties changed: +x to -x)
--- a/storage/perfschema/pfs_column_types.h	2011-01-26 23:02:25 +0000
+++ b/storage/perfschema/pfs_column_types.h	2011-02-07 19:17:08 +0000
@@ -144,11 +144,16 @@ enum enum_operation_type
   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
+  OPERATION_TYPE_SOCKETSENDTO = 47,
+  OPERATION_TYPE_SOCKETRECVFROM = 48,
+  OPERATION_TYPE_SOCKETSENDMSG = 49,
+  OPERATION_TYPE_SOCKETRECVMSG = 50,
+  OPERATION_TYPE_SOCKETSEEK = 51,
+  OPERATION_TYPE_SOCKETOPT = 52,
+  OPERATION_TYPE_SOCKETSTAT = 53,
+  OPERATION_TYPE_SOCKETSHUTDOWN = 54
 };
+
 #define FIRST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_LOCK))
 #define LAST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_SOCKETSHUTDOWN)
 #define COUNT_OPERATION_TYPE (LAST_OPERATION_TYPE - FIRST_OPERATION_TYPE + 1)

=== modified file 'storage/perfschema/pfs_engine_table.cc' (properties changed: +x to -x)
=== modified file 'storage/perfschema/pfs_events_waits.h' (properties changed: +x to -x)
=== modified file 'storage/perfschema/pfs_instr.cc'
--- a/storage/perfschema/pfs_instr.cc	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_instr.cc	2011-02-07 21:34:45 +0000
@@ -762,6 +762,11 @@ PFS_file *sanitize_file(PFS_file *unsafe
   SANITIZE_ARRAY_BODY(PFS_file, file_array, file_max, unsafe);
 }
 
+PFS_socket *sanitize_socket(PFS_socket *unsafe)
+{
+  SANITIZE_ARRAY_BODY(PFS_socket, socket_array, socket_max, unsafe);
+}
+
 /**
   Destroy instrumentation for a thread instance.
   @param pfs                          the thread to destroy
@@ -1199,8 +1204,10 @@ PFS_socket* create_socket(PFS_socket_cla
           pfs->m_identity= identity;
           pfs->m_class= klass;
           pfs->m_wait_stat.reset();
-          // TBD socket_io_stat
+          pfs->m_socket_stat.reset();
           pfs->m_lock.dirty_to_allocated();
+          if (klass->is_singleton())
+            klass->m_singleton= pfs;
           return pfs;
         }
       }
@@ -1218,7 +1225,7 @@ PFS_socket* create_socket(PFS_socket_cla
 void release_socket(PFS_socket *pfs)
 {
   DBUG_ASSERT(pfs != NULL);
-  //pfs->m_socket_stat.m_open_count--;
+  pfs->m_socket_stat.m_open_count--;
 }
 
 /**
@@ -1228,7 +1235,20 @@ void release_socket(PFS_socket *pfs)
 void destroy_socket(PFS_socket *pfs)
 {
   DBUG_ASSERT(pfs != NULL);
-  // TBD aggregate
+  PFS_socket_class *klass= pfs->m_class;
+
+  /* Aggregate to EVENTS_WAITS_SUMMARY_BY_EVENT_NAME */
+  uint index= klass->m_event_name_index;
+  global_instr_class_waits_array[index].aggregate(&pfs->m_wait_stat);
+  pfs->m_wait_stat.reset();
+
+  /* Aggregate to SOCKET_SUMMARY_BY_INSTANCE */
+  klass->m_socket_stat.m_io_stat.aggregate(&pfs->m_socket_stat.m_io_stat);
+  pfs->m_socket_stat.m_io_stat.reset();
+
+  if (klass->is_singleton())
+    klass->m_singleton= NULL;
+
   pfs->m_lock.allocated_to_free();
 }
 
@@ -1297,6 +1317,16 @@ void reset_file_instance_io(void)
     pfs->m_file_stat.m_io_stat.reset();
 }
 
+/** Reset the io statistics per socket instance. */
+void reset_socket_instance_io(void)
+{
+  PFS_socket *pfs= socket_array;
+  PFS_socket *pfs_last= socket_array + socket_max;
+
+  for ( ; pfs < pfs_last; pfs++)
+    pfs->m_socket_stat.m_io_stat.reset();
+}
+
 void reset_global_wait_stat()
 {
   PFS_single_stat *stat= global_instr_class_waits_array;

=== modified file 'storage/perfschema/pfs_instr.h'
--- a/storage/perfschema/pfs_instr.h	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_instr.h	2011-02-07 19:17:08 +0000
@@ -198,6 +198,8 @@ struct PFS_socket : public PFS_instr
 {
   /** Socket identity, typically int */
   const void *m_identity;
+  /** Thread identifier */
+  uint m_thread_id;
   /** Socket file descriptor */
   uint m_fd;
   /** Socket ip address, IPV4 or IPV6 */
@@ -350,6 +352,7 @@ PFS_cond *sanitize_cond(PFS_cond *unsafe
 PFS_thread *sanitize_thread(PFS_thread *unsafe);
 const char *sanitize_file_name(const char *unsafe);
 PFS_file *sanitize_file(PFS_file *unsafe);
+PFS_socket *sanitize_socket(PFS_socket *unsafe);
 
 int init_instruments(const PFS_global_param *param);
 void cleanup_instruments();
@@ -415,6 +418,7 @@ extern PFS_socket *socket_array;
 void reset_events_waits_by_instance();
 void reset_per_thread_wait_stat();
 void reset_file_instance_io();
+void reset_socket_instance_io();
 
 void reset_global_wait_stat(void);
 

=== modified file 'storage/perfschema/pfs_instr_class.cc' (properties changed: +x to -x)
--- a/storage/perfschema/pfs_instr_class.cc	2011-01-26 23:02:25 +0000
+++ b/storage/perfschema/pfs_instr_class.cc	2011-02-07 21:34:45 +0000
@@ -450,7 +450,8 @@ int init_socket_class(uint socket_class_
 
   if (socket_class_max > 0)
   {
-    socket_class_array= PFS_MALLOC_ARRAY(socket_class_max, PFS_socket_class, MYF(MY_ZEROFILL));
+    socket_class_array= PFS_MALLOC_ARRAY(socket_class_max, PFS_socket_class,
+                                         MYF(MY_ZEROFILL));
     if (unlikely(socket_class_array == NULL))
       return 1;
   }
@@ -821,18 +822,8 @@ PFS_socket_key register_socket_class(con
   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);
-    }
-  }
+  REGISTER_CLASS_BODY_PART(index, socket_class_array, socket_class_max,
+                           name, name_length)
 
   index= PFS_atomic::add_u32(&socket_class_dirty_count, 1);
 
@@ -858,10 +849,7 @@ PFS_socket_key register_socket_class(con
 */
 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];
+  FIND_CLASS_BODY(key, socket_class_allocated_count, socket_class_array);
 }
 
 PFS_socket_class *sanitize_socket_class(PFS_socket_class *unsafe)

=== modified file 'storage/perfschema/pfs_instr_class.h'
--- a/storage/perfschema/pfs_instr_class.h	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_instr_class.h	2011-02-07 21:34:45 +0000
@@ -284,6 +284,8 @@ struct PFS_file_class : public PFS_instr
   PFS_file *m_singleton;
 };
 
+struct  PFS_socket;
+
 /** Instrumentation metadata for a socket. */
 struct PFS_socket_class : public PFS_instr_class
 {
@@ -292,7 +294,7 @@ struct PFS_socket_class : public PFS_ins
   /** Self index in @c socket_class_array. */
   uint m_index;
   /** Singleton instance. */
-  PFS_file *m_singleton;
+  PFS_socket *m_singleton;
 };
 
 void init_event_name_sizing(const PFS_global_param *param);

=== modified file 'storage/perfschema/pfs_stat.h'
--- a/storage/perfschema/pfs_stat.h	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/pfs_stat.h	2011-02-07 21:34:45 +0000
@@ -82,6 +82,27 @@ struct PFS_single_stat
   }
 };
 
+/** Single statistic. */
+struct PFS_multi_stat
+{
+  /** Timer statistics */
+  PFS_single_stat m_waits;
+  /** Byte count statistics */
+  PFS_single_stat m_bytes;
+
+  inline void aggregate(const PFS_multi_stat *stat)
+  {
+    m_waits.aggregate(&stat->m_waits);
+    m_bytes.aggregate(&stat->m_bytes);
+  }
+
+  inline void reset(void)
+  {
+    m_waits.reset();
+    m_bytes.reset();
+  }
+};
+
 /** Statistics for COND usage. */
 struct PFS_cond_stat
 {
@@ -306,45 +327,84 @@ struct PFS_table_stat
   }
 };
 
-/** Statistics for SOCKET IO usage. */
+/** Statistics for SOCKET IO. Used for both waits and byte counts. */
 struct PFS_socket_io_stat
 {
-  /** Count of READ operations. */
-  ulonglong m_count_read;
-  /** Count of WRITE operations. */
-  ulonglong m_count_write;
-  /** Number of bytes read. */
-  ulonglong m_read_bytes;
-  /** Number of bytes written. */
-  ulonglong m_write_bytes;
+  /** READ statistics */
+  PFS_multi_stat m_read;
+  /** WRITE statistics */
+  PFS_multi_stat m_write;
+  /** RECV statistics */
+  PFS_multi_stat m_recv;
+  /** SEND statistics */
+  PFS_multi_stat m_send;
+  /** RECVFROM statistics */
+  PFS_multi_stat m_recvfrom;
+  /** SENDTO statistics */
+  PFS_multi_stat m_sendto;
+  /** RECVMSG statistics */
+  PFS_multi_stat m_recvmsg;
+  /** SENDMSG statistics */
+  PFS_multi_stat m_sendmsg;
+  /** CONNECT statistics */
+  PFS_multi_stat m_connect;
+  /** Miscelleanous statistics */
+  PFS_multi_stat m_misc;
 
-  /** Reset socket statistics. */
   inline void reset(void)
   {
-    m_count_read= 0;
-    m_count_write= 0;
-    m_read_bytes= 0;
-    m_write_bytes= 0;
+    m_read.reset();
+    m_write.reset();
+    m_recv.reset();
+    m_send.reset();
+    m_recvfrom.reset();
+    m_sendto.reset();
+    m_recvmsg.reset();
+    m_sendmsg.reset();
+    m_connect.reset();
+    m_misc.reset();
   }
 
   inline void aggregate(const PFS_socket_io_stat *stat)
   {
-    m_count_read+= stat->m_count_read;
-    m_count_write+= stat->m_count_write;
-    m_read_bytes+= stat->m_read_bytes;
-    m_write_bytes+= stat->m_write_bytes;
+    m_recv.aggregate(&stat->m_recv);
+    m_send.aggregate(&stat->m_send);
+    m_recvfrom.aggregate(&stat->m_recvfrom);
+    m_sendto.aggregate(&stat->m_sendto);
+    m_recvmsg.aggregate(&stat->m_recvmsg);
+    m_sendmsg.aggregate(&stat->m_sendmsg);
+    m_connect.aggregate(&stat->m_connect);
+    m_misc.aggregate(&stat->m_misc);
+  }
+
+  inline void sum_waits(PFS_single_stat *result)
+  {
+    result->aggregate(&m_recv.m_waits);
+    result->aggregate(&m_send.m_waits);
+    result->aggregate(&m_recvfrom.m_waits);
+    result->aggregate(&m_sendto.m_waits);
+    result->aggregate(&m_recvmsg.m_waits);
+    result->aggregate(&m_sendmsg.m_waits);
+    result->aggregate(&m_connect.m_waits);
+    result->aggregate(&m_misc.m_waits);
+  }
+
+  inline void sum_bytes(PFS_single_stat *result)
+  {
+    result->aggregate(&m_recv.m_bytes);
+    result->aggregate(&m_send.m_bytes);
+    result->aggregate(&m_recvfrom.m_bytes);
+    result->aggregate(&m_sendto.m_bytes);
+    result->aggregate(&m_recvmsg.m_bytes);
+    result->aggregate(&m_sendmsg.m_bytes);
+    result->aggregate(&m_connect.m_bytes);
+    result->aggregate(&m_misc.m_bytes);
   }
 
-  inline void aggregate_read(ulonglong bytes)
+  inline void sum(PFS_multi_stat *result)
   {
-    m_count_read++;
-    m_read_bytes+= bytes;
-  }
-
-  inline void aggregate_write(ulonglong bytes)
-  {
-    m_count_write++;
-    m_write_bytes+= bytes;
+    sum_waits(&result->m_waits);
+    sum_bytes(&result->m_bytes);
   }
 };
 
@@ -353,10 +413,17 @@ struct PFS_socket_stat
 {
   /** Number of current open sockets. //TBD Not relevant */
   ulong m_open_count;
-  /** Socket IO statistics. */
+  
+  /** Socket timing and byte count statistics per operation */
   PFS_socket_io_stat m_io_stat;
-};
 
+  /** Reset socket statistics. */
+  inline void reset(void)
+  {
+    m_open_count= 0;
+    m_io_stat.reset();
+  }
+};
 
 /** @} */
 #endif

=== modified file 'storage/perfschema/pfs_visitor.cc'
--- a/storage/perfschema/pfs_visitor.cc	2011-01-07 16:20:19 +0000
+++ b/storage/perfschema/pfs_visitor.cc	2011-02-07 21:34:45 +0000
@@ -175,6 +175,38 @@ void PFS_instance_iterator::visit_file_i
   }
 }
 
+void PFS_instance_iterator::visit_socket_instances(PFS_socket_class *klass,
+                                                   PFS_instance_visitor *visitor)
+{
+  DBUG_ASSERT(visitor != NULL);
+
+  visitor->visit_socket_class(klass);
+
+  if (klass->is_singleton())
+  {
+    PFS_socket *pfs= sanitize_socket(klass->m_singleton);
+    if (likely(pfs != NULL))
+    {
+      if (likely(pfs->m_lock.is_populated()))
+      {
+        visitor->visit_socket(pfs);
+      }
+    }
+  }
+  else
+  {
+    PFS_socket *pfs= socket_array;
+    PFS_socket *pfs_last= pfs + socket_max;
+    for ( ; pfs < pfs_last; pfs++)
+    {
+      if ((pfs->m_class == klass) && pfs->m_lock.is_populated())
+      {
+        visitor->visit_socket(pfs);
+      }
+    }
+  }
+}
+
 void PFS_object_iterator::visit_all_tables(PFS_object_visitor *visitor)
 {
   DBUG_ASSERT(visitor != NULL);
@@ -294,6 +326,12 @@ void PFS_instance_wait_visitor::visit_fi
   m_stat.aggregate(& global_instr_class_waits_array[index]);
 }
 
+void PFS_instance_wait_visitor::visit_socket_class(PFS_socket_class *pfs) 
+{
+  uint index= pfs->m_event_name_index;
+  m_stat.aggregate(& global_instr_class_waits_array[index]);
+}
+
 void PFS_instance_wait_visitor::visit_mutex(PFS_mutex *pfs) 
 {
   m_stat.aggregate(& pfs->m_wait_stat);
@@ -313,6 +351,11 @@ void PFS_instance_wait_visitor::visit_fi
 {
   m_stat.aggregate(& pfs->m_wait_stat);
 }
+
+void PFS_instance_wait_visitor::visit_socket(PFS_socket *pfs) 
+{
+  m_stat.aggregate(& pfs->m_wait_stat);
+}
 
 PFS_table_io_wait_visitor::PFS_table_io_wait_visitor()
 {}

=== modified file 'storage/perfschema/pfs_visitor.h'
--- a/storage/perfschema/pfs_visitor.h	2011-01-07 16:20:19 +0000
+++ b/storage/perfschema/pfs_visitor.h	2011-02-07 21:34:45 +0000
@@ -34,6 +34,7 @@ struct PFS_mutex_class;
 struct PFS_rwlock_class;
 struct PFS_cond_class;
 struct PFS_file_class;
+struct PFS_socket_class;
 struct PFS_table_share;
 struct PFS_mutex;
 struct PFS_rwlock;
@@ -42,6 +43,7 @@ struct PFS_file;
 struct PFS_table;
 struct PFS_stage_class;
 struct PFS_statement_class;
+struct PFS_socket;
 
 /**
   Interface class to visit groups of connections.
@@ -99,6 +101,8 @@ public:
   virtual void visit_cond_class(PFS_cond_class *pfs) {}
   /** Visit a file class. */
   virtual void visit_file_class(PFS_file_class *pfs) {}
+  /** Visit a socket class. */
+  virtual void visit_socket_class(PFS_socket_class *pfs) {}
   /** Visit a mutex instance. */
   virtual void visit_mutex(PFS_mutex *pfs) {}
   /** Visit a rwlock instance. */
@@ -107,6 +111,8 @@ public:
   virtual void visit_cond(PFS_cond *pfs) {}
   /** Visit a file instance. */
   virtual void visit_file(PFS_file *pfs) {}
+  /** Visit a socket instance. */
+  virtual void visit_socket(PFS_socket *pfs) {}
 };
 
 /**
@@ -144,6 +150,13 @@ public:
   */
   static void visit_file_instances(PFS_file_class *klass,
                                    PFS_instance_visitor *visitor);
+  /**
+    Visit a socket class and related instances.
+    @param klass the klass to visit.
+    @param visitor the visitor to call
+  */
+  static void visit_socket_instances(PFS_socket_class *klass,
+                                     PFS_instance_visitor *visitor);
 };
 
 /**
@@ -217,10 +230,12 @@ public:
   virtual void visit_rwlock_class(PFS_rwlock_class *pfs);
   virtual void visit_cond_class(PFS_cond_class *pfs);
   virtual void visit_file_class(PFS_file_class *pfs);
+  virtual void visit_socket_class(PFS_socket_class *pfs);
   virtual void visit_mutex(PFS_mutex *pfs);
   virtual void visit_rwlock(PFS_rwlock *pfs);
   virtual void visit_cond(PFS_cond *pfs);
   virtual void visit_file(PFS_file *pfs);
+  virtual void visit_socket(PFS_socket *pfs);
 
   /** Wait statistic collected. */
   PFS_single_stat m_stat;

=== modified file 'storage/perfschema/table_events_waits.cc' (properties changed: +x to -x)
--- a/storage/perfschema/table_events_waits.cc	2011-01-26 23:02:25 +0000
+++ b/storage/perfschema/table_events_waits.cc	2011-02-07 19:17:08 +0000
@@ -478,7 +478,11 @@ static const LEX_STRING operation_names_
   { C_STRING_WITH_LEN("bind") },
   { C_STRING_WITH_LEN("close") },
   { C_STRING_WITH_LEN("send") },
-  { C_STRING_WITH_LEN("receive") },
+  { C_STRING_WITH_LEN("recv") },
+  { C_STRING_WITH_LEN("sendto") },
+  { C_STRING_WITH_LEN("recvfrom") },
+  { C_STRING_WITH_LEN("sendmsg") },
+  { C_STRING_WITH_LEN("recvmsg") },
   { C_STRING_WITH_LEN("seek") },
   { C_STRING_WITH_LEN("opt") },
   { C_STRING_WITH_LEN("stat") },

=== modified file 'storage/perfschema/table_events_waits_summary.cc'
--- a/storage/perfschema/table_events_waits_summary.cc	2010-12-07 18:55:54 +0000
+++ b/storage/perfschema/table_events_waits_summary.cc	2011-02-07 19:17:08 +0000
@@ -200,10 +200,10 @@ void table_events_waits_summary_by_insta
     return;
 
   /*
-    Files don't have a in memory structure associated to it,
+    Sockets don't have a in memory structure associated to it,
     so we use the address of the PFS_socket buffer as object_instance_begin
   */
-  make_instr_row(pfs, safe_class, pfs);
+  make_instr_row(pfs, safe_class, pfs); // TBD: check this
 }
 
 int table_events_waits_summary_by_instance

=== modified file 'storage/perfschema/table_helper.h'
--- a/storage/perfschema/table_helper.h	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/table_helper.h	2011-02-07 19:17:08 +0000
@@ -127,7 +127,7 @@ struct PFS_stat_row
   /** Column MAX_TIMER_WAIT. */
   ulonglong m_max;
 
-  /** Build a row from a memory buffer. */
+  /** Build a row with timer fields from a memory buffer. */
   inline void set(time_normalizer *normalizer, const PFS_single_stat *stat)
   {
     m_count= stat->m_count;
@@ -148,6 +148,27 @@ struct PFS_stat_row
     }
   }
 
+  /** Build a row with count values from a memory buffer. */
+  inline void set(const PFS_single_stat *stat)
+  {
+    m_count= stat->m_count;
+
+    if (m_count)
+    {
+      m_sum= stat->m_sum;
+      m_min= stat->m_min;
+      m_max= stat->m_max;
+      m_avg= (stat->m_sum / m_count);
+    }
+    else
+    {
+      m_sum= 0;
+      m_min= 0;
+      m_avg= 0;
+      m_max= 0;
+    }
+  }
+
   /** Set a table field from the row. */
   void set_field(uint index, Field *f)
   {
@@ -273,6 +294,110 @@ struct PFS_table_lock_stat_row
   }
 };
 
+/** Row fragment for socket io statistics columns. */
+struct PFS_socket_io_stat_row
+{
+  PFS_stat_row m_all;
+  PFS_stat_row m_all_read;
+  PFS_stat_row m_all_write;
+  PFS_stat_row m_recv;
+  PFS_stat_row m_send;
+  PFS_stat_row m_recvfrom;
+  PFS_stat_row m_sendto;
+  PFS_stat_row m_recvmsg;
+  PFS_stat_row m_sendmsg;
+  PFS_stat_row m_connect;
+  PFS_stat_row m_misc;
+
+  /** Build a row of timer fields from a memory buffer. */
+  inline void set_waits(time_normalizer *normalizer, const PFS_socket_io_stat *stat)
+  {
+    PFS_single_stat all_read;
+    PFS_single_stat all_write;
+    PFS_single_stat all;
+
+    /* Combine receive operations */
+    m_recv.set(normalizer, &stat->m_recv.m_waits);
+    m_recvfrom.set(normalizer, &stat->m_recvfrom.m_waits);
+    m_recvmsg.set(normalizer, &stat->m_recvmsg.m_waits);
+
+    all_read.aggregate(&stat->m_recv.m_waits);
+    all_read.aggregate(&stat->m_recvfrom.m_waits);
+    all_read.aggregate(&stat->m_recvmsg.m_waits);
+
+    /* Combine send operations */
+    m_send.set(normalizer, &stat->m_send.m_waits);
+    m_sendto.set(normalizer, &stat->m_sendto.m_waits);
+    m_sendmsg.set(normalizer, &stat->m_sendmsg.m_waits);
+
+    all_write.aggregate(&stat->m_send.m_waits);
+    all_write.aggregate(&stat->m_sendto.m_waits);
+    all_write.aggregate(&stat->m_sendmsg.m_waits);
+
+    /* Set row values for miscellaneous socket operations */
+    m_connect.set(normalizer, &stat->m_connect.m_waits);
+    m_misc.set(normalizer, &stat->m_misc.m_waits);
+    
+    /* Combine timer stats for all operations */
+    all.aggregate(&all_read);
+    all.aggregate(&all_write);
+    all.aggregate(&stat->m_misc.m_waits);
+    all.aggregate(&stat->m_connect.m_waits);
+
+    m_all_read.set(normalizer, &all_read);
+    m_all_write.set(normalizer, &all_write);
+    m_all.set(normalizer, &all);
+  }
+
+  /** Build a row of byte count fields from a memory buffer. */
+  inline void set_bytes(const PFS_socket_io_stat *stat)
+  {
+    PFS_single_stat all_read;
+    PFS_single_stat all_write;
+    PFS_single_stat all;
+    PFS_single_stat misc;
+
+    /* Combine receive operations */
+    m_recv.set(&stat->m_recv.m_bytes);
+    m_recvfrom.set(&stat->m_recvfrom.m_bytes);
+    m_recvmsg.set(&stat->m_recvmsg.m_bytes);
+
+    all_read.aggregate(&stat->m_recv.m_bytes);
+    all_read.aggregate(&stat->m_recvfrom.m_bytes);
+    all_read.aggregate(&stat->m_recvmsg.m_bytes);
+
+    /* Combine send operations */
+    m_send.set(&stat->m_send.m_bytes);
+    m_sendto.set(&stat->m_sendto.m_bytes);
+    m_sendmsg.set(&stat->m_sendmsg.m_bytes);
+
+    all_write.aggregate(&stat->m_send.m_bytes);
+    all_write.aggregate(&stat->m_sendto.m_bytes);
+    all_write.aggregate(&stat->m_sendmsg.m_bytes);
+
+    /* Miscellaneous socket operations */
+    m_connect.set(&stat->m_connect.m_bytes);
+    m_misc.set(&stat->m_misc.m_bytes);
+    
+    /* Combine byte counts for all operations */
+    all.aggregate(&all_read);
+    all.aggregate(&all_write);
+    all.aggregate(&stat->m_connect.m_bytes);
+    all.aggregate(&stat->m_misc.m_bytes);
+
+    m_all_read.set(&all_read);
+    m_all_write.set(&all_write);
+    m_all.set(&all);
+  }
+
+  /** Build a row of timer and byte count fields from a memory buffer. */
+  inline void set(time_normalizer *normalizer, const PFS_socket_io_stat *stat)
+  {
+    set_waits(normalizer, stat);
+    set_bytes(stat);
+  }
+};
+
 void set_field_object_type(Field *f, enum_object_type object_type);
 
 /** @} */

=== modified file 'storage/perfschema/table_setup_instruments.cc'
--- a/storage/perfschema/table_setup_instruments.cc	2011-01-26 22:26:41 +0000
+++ b/storage/perfschema/table_setup_instruments.cc	2011-02-07 21:34:45 +0000
@@ -112,6 +112,9 @@ int table_setup_instruments::rnd_next(vo
     case pos_setup_instruments::VIEW_TABLE:
       instr_class= find_table_class(m_pos.m_index_2);
       break;
+    case pos_setup_instruments::VIEW_SOCKET:
+      instr_class= find_table_class(m_pos.m_index_2);
+      break;
     }
     if (instr_class)
     {
@@ -151,6 +154,9 @@ int table_setup_instruments::rnd_pos(con
   case pos_setup_instruments::VIEW_TABLE:
     instr_class= find_table_class(m_pos.m_index_2);
     break;
+  case pos_setup_instruments::VIEW_SOCKET:
+    instr_class= find_table_class(m_pos.m_index_2);
+    break;
   }
   if (instr_class)
   {

=== modified file 'storage/perfschema/table_socket_instances.cc'
--- a/storage/perfschema/table_socket_instances.cc	2010-12-08 03:24:30 +0000
+++ b/storage/perfschema/table_socket_instances.cc	2011-02-07 19:17:08 +0000
@@ -41,28 +41,23 @@ static const TABLE_FIELD_TYPE field_type
     { NULL, 0}
   },
   {
-    { C_STRING_WITH_LEN("SOCKET_ID") },
-    { C_STRING_WITH_LEN("int(11)") },
-    { NULL, 0}
-  },
-  {
-    { C_STRING_WITH_LEN("IP") },
-    { C_STRING_WITH_LEN("varchar(128)") },
+    { C_STRING_WITH_LEN("THREAD_ID") },
+    { C_STRING_WITH_LEN("int(10)") },
     { NULL, 0}
   },
   {
-    { C_STRING_WITH_LEN("PORT") },
-    { C_STRING_WITH_LEN("int(11)") },
+    { C_STRING_WITH_LEN("SOCKET_ID") },
+    { C_STRING_WITH_LEN("int(10)") },
     { NULL, 0}
   },
   {
-    { C_STRING_WITH_LEN("BYTES_READ") },
-    { C_STRING_WITH_LEN("bigint(20)") },
+    { C_STRING_WITH_LEN("IP") },
+    { C_STRING_WITH_LEN("varchar(64)") },
     { NULL, 0}
   },
   {
-    { C_STRING_WITH_LEN("BYTES_WRITE") },
-    { C_STRING_WITH_LEN("bigint(20)") },
+    { C_STRING_WITH_LEN("PORT") },
+    { C_STRING_WITH_LEN("int(10)") },
     { NULL, 0}
   }
 };
@@ -70,7 +65,7 @@ static const TABLE_FIELD_TYPE field_type
 
 TABLE_FIELD_DEF
 table_socket_instances::m_field_def=
-{ 7, field_types };
+{ 6, field_types };
 
 PFS_engine_table_share
 table_socket_instances::m_share=
@@ -156,12 +151,11 @@ void table_socket_instances::make_row(PF
   m_row.m_event_name=         safe_class->m_name;
   m_row.m_event_name_length=  safe_class->m_name_length;
   m_row.m_identity=           pfs->m_identity;
+  m_row.m_thread_id=          pfs->m_thread_id;
   m_row.m_fd=                 pfs->m_fd;
   m_row.m_ip=                 pfs->m_ip;
   m_row.m_ip_length=          pfs->m_ip_length;
   m_row.m_port=               pfs->m_port;
-  m_row.m_bytes_read=         pfs->m_socket_stat.m_io_stat.m_read_bytes; //TBD
-  m_row.m_bytes_write=        pfs->m_socket_stat.m_io_stat.m_write_bytes;
 
   if (pfs->m_lock.end_optimistic_lock(&lock))
     m_row_exists= true;
@@ -192,21 +186,18 @@ int table_socket_instances::read_row_val
       case 1: /* OBJECT_INSTANCE_BEGIN */
         set_field_ulonglong(f, (intptr)m_row.m_identity);
         break;
-      case 2: /* SOCKET_ID */
+      case 2: /* THREAD_ID */
+        set_field_ulong(f, m_row.m_thread_id);
+        break;
+      case 3: /* SOCKET_ID */
         set_field_ulong(f, m_row.m_fd);
         break;
-      case 3: /* IP */
+      case 4: /* IP */
         set_field_varchar_utf8(f, m_row.m_ip, m_row.m_ip_length);
         break;
-      case 4: /* PORT */
+      case 5: /* PORT */
         set_field_ulong(f, m_row.m_port);
         break;
-      case 5: /* BYTES_READ */
-        set_field_ulonglong(f, m_row.m_bytes_read);
-        break;
-      case 6: /* BYTES_WRITE */
-        set_field_ulonglong(f, m_row.m_bytes_write);
-        break;
       default:
         DBUG_ASSERT(false);
       }

=== modified file 'storage/perfschema/table_socket_instances.h'
--- a/storage/perfschema/table_socket_instances.h	2010-12-07 19:50:08 +0000
+++ b/storage/perfschema/table_socket_instances.h	2011-02-07 19:17:08 +0000
@@ -38,6 +38,8 @@ struct row_socket_instances
   uint m_event_name_length;
   /** Column OBJECT_INSTANCE_BEGIN */
   const void *m_identity;
+  /** Column THREAD_ID */
+  uint m_thread_id;
   /** Column SOCKET_ID */
   uint m_fd;
   /** Column IP. */
@@ -46,10 +48,6 @@ struct row_socket_instances
   uint m_ip_length;
   /** Column PORT */
   uint m_port;
-  /** Column BYTES_READ */
-  ulonglong m_bytes_read;           // TBD
-  /** Column BYTES_WRITE */
-  ulonglong m_bytes_write;
 };
 
 /** Table PERFORMANCE_SCHEMA.SOCKET_INSTANCES. */

=== added file 'storage/perfschema/table_socket_summary_by_instance.cc'
--- a/storage/perfschema/table_socket_summary_by_instance.cc	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_socket_summary_by_instance.cc	2011-02-04 22:00:44 +0000
@@ -0,0 +1,913 @@
+/* Copyright (c) 2008, 2010, 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,
+  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+/**
+  @file storage/perfschema/table_socket_summary_by_instance.cc
+  Table SOCKET_INSTANCES (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_socket_summary_by_instance.h"
+#include "pfs_global.h"
+
+THR_LOCK table_socket_summary_by_instance::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+  {
+    { C_STRING_WITH_LEN("EVENT_NAME") },
+    { C_STRING_WITH_LEN("varchar(128)") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("OBJECT_NAME") },
+    { C_STRING_WITH_LEN("varchar(64)") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("COUNT_STAR") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Read */
+  {
+    { C_STRING_WITH_LEN("COUNT_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_READ") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Write */
+  {
+    { C_STRING_WITH_LEN("COUNT_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_WRITE") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Recv */
+  {
+    { C_STRING_WITH_LEN("COUNT_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_RECV") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Send */
+  {
+    { C_STRING_WITH_LEN("COUNT_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_SEND") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Recvfrom */
+  {
+    { C_STRING_WITH_LEN("COUNT_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_RECVFROM") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Sendto */
+  {
+    { C_STRING_WITH_LEN("COUNT_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_SENDTO") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Recvmsg */
+  {
+    { C_STRING_WITH_LEN("COUNT_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_RECVMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Sendmsg */
+  {
+    { C_STRING_WITH_LEN("COUNT_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_NUMBER_OF_BYTES_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_NUMBER_OF_BYTES_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_NUMBER_OF_BYTES_SENDMSG") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Connect */
+  {
+    { C_STRING_WITH_LEN("COUNT_CONNECT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_CONNECT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_CONNECT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_CONNECT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_CONNECT") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+
+  /** Misc */
+  {
+    { C_STRING_WITH_LEN("COUNT_MISC") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("SUM_TIMER_MISC") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MIN_TIMER_MISC") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("AVG_TIMER_MISC") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  },
+  {
+    { C_STRING_WITH_LEN("MAX_TIMER_MISC") },
+    { C_STRING_WITH_LEN("bigint") },
+    { NULL, 0}
+  }
+};
+
+TABLE_FIELD_DEF
+table_socket_summary_by_instance::m_field_def=
+{ 90, field_types };
+
+PFS_engine_table_share
+table_socket_summary_by_instance::m_share=
+{
+  { C_STRING_WITH_LEN("socket_summary_by_instance") },
+  &pfs_readonly_acl,
+  &table_socket_summary_by_instance::create,
+  NULL, /* write_row */
+  NULL, /* delete_all_rows */
+  NULL, /* get_row_count */
+  1000, /* records */ // TBD: Check this
+  sizeof(PFS_simple_index),
+  &m_table_lock,
+  &m_field_def,
+  false /* checked */
+};
+
+PFS_engine_table* table_socket_summary_by_instance::create(void)
+{
+  return new table_socket_summary_by_instance();
+}
+
+table_socket_summary_by_instance::table_socket_summary_by_instance()
+  : PFS_engine_table(&m_share, &m_pos),
+  m_row_exists(false), m_pos(0), m_next_pos(0)
+{}
+
+void table_socket_summary_by_instance::reset_position(void)
+{
+  m_pos.m_index= 0;
+  m_next_pos.m_index= 0;
+}
+
+int table_socket_summary_by_instance::rnd_next(void)
+{
+  PFS_socket *pfs;
+
+  for (m_pos.set_at(&m_next_pos);
+       m_pos.m_index < socket_max;
+       m_pos.next())
+  {
+    pfs= &socket_array[m_pos.m_index];
+    if (pfs->m_lock.is_populated())
+    {
+      make_row(pfs);
+      m_next_pos.set_after(&m_pos);
+      return 0;
+    }
+  }
+
+  return HA_ERR_END_OF_FILE;
+}
+
+int table_socket_summary_by_instance::rnd_pos(const void *pos)
+{
+  PFS_socket *pfs;
+
+  set_position(pos);
+  DBUG_ASSERT(m_pos.m_index < socket_max);
+  pfs= &socket_array[m_pos.m_index];
+
+  if (! pfs->m_lock.is_populated())
+    return HA_ERR_RECORD_DELETED;
+
+  make_row(pfs);
+  return 0;
+}
+
+void table_socket_summary_by_instance::make_row(PFS_socket *pfs)
+{
+  pfs_lock lock;
+  PFS_socket_class *safe_class;
+
+  m_row_exists= false;
+
+  /* Protect this reader against a socket delete */
+  pfs->m_lock.begin_optimistic_lock(&lock);
+
+  safe_class= sanitize_socket_class(pfs->m_class);
+  if (unlikely(safe_class == NULL))
+    return;
+
+  m_row.m_event_name.make_row(safe_class);
+  m_row.m_identity= pfs->m_identity;
+
+  if (!pfs->m_lock.end_optimistic_lock(&lock))
+    return;
+
+  m_row_exists= true;
+
+  time_normalizer *normalizer= time_normalizer::get(wait_timer);
+  
+  /* Collect timer and byte count stats */
+  m_row.m_io_stat.set(normalizer, &pfs->m_socket_stat.m_io_stat);
+}
+
+int table_socket_summary_by_instance::read_row_values(TABLE *table,
+                                          unsigned char *,
+                                          Field **fields,
+                                          bool read_all)
+{
+  Field *f;
+
+  if (unlikely(!m_row_exists))
+    return HA_ERR_RECORD_DELETED;
+
+  /* Set the null bits */
+  DBUG_ASSERT(table->s->null_bytes == 0);
+
+  for (; (f= *fields) ; fields++)
+  {
+    if (read_all || bitmap_is_set(table->read_set, f->field_index))
+    {
+      switch(f->field_index)
+      {
+      case  0: /* EVENT_NAME */
+        m_row.m_event_name.set_field(f);
+        break;
+      case  1: /* OBJECT_INSTANCE */
+        // TBD: Fix
+        set_field_ulonglong(f, (ulonglong)m_row.m_identity);
+        break;
+      case  2: /* OBJECT_NAME */
+        // TBD: Fix
+        break;
+      case  3: /* COUNT_STAR */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all.m_count);
+        break;
+      case  4: /* SUM_TIMER_WAIT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all.m_sum);
+        break;
+      case  5: /* MIN_TIMER_WAIT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all.m_min);
+        break;
+      case  6: /* AVG_TIMER_WAIT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all.m_avg);
+        break;
+      case  7: /* MAX_TIMER_WAIT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all.m_max);
+        break;
+
+      case  8: /* COUNT_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_count);
+        break;
+      case  9: /* SUM_TIMER_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_sum);
+        break;
+      case 10: /* MIN_TIMER_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_min);
+        break;
+      case 11: /* AVG_TIMER_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_avg);
+        break;
+      case 12: /* MAX_TIMER_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_max);
+        break;
+      case 13: /* SUM_NUMBER_OF_BYTES_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_sum);
+        break;
+      case 14: /* MIN_NUMBER_OF_BYTES_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_min);
+        break;
+      case 15: /* AVG_NUMBER_OF_BYTES_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_avg);
+        break;
+      case 16: /* MAX_NUMBER_OF_BYTES_READ */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_read.m_max);
+        break;
+
+      case 17: /* COUNT_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_count);
+        break;
+      case 18: /* SUM_TIMER_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_sum);
+        break;
+      case 19: /* MIN_TIMER_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_min);
+        break;
+      case 20: /* AVG_TIMER_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_avg);
+        break;
+      case 21: /* MAX_TIMER_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_max);
+        break;
+      case 22: /* SUM_NUMBER_OF_BYTES_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_sum);
+        break;
+      case 23: /* MIN_NUMBER_OF_BYTES_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_min);
+        break;
+      case 24: /* AVG_NUMBER_OF_BYTES_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_avg);
+        break;
+      case 25: /* MAX_NUMBER_OF_BYTES_WRITE */
+        set_field_ulonglong(f, m_row.m_io_stat.m_all_write.m_max);
+        break;
+
+      case 26: /* COUNT_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_count);
+        break;
+      case 27: /* SUM_TIMER_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_sum);
+        break;
+      case 28: /* MIN_TIMER_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_min);
+        break;
+      case 29: /* AVG_TIMER_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_avg);
+        break;
+      case 30: /* MAX_TIMER_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_max);
+        break;
+      case 31: /* SUM_NUMBER_OF_BYTES_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_sum);
+        break;
+      case 32: /* MIN_NUMBER_OF_BYTES_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_min);
+        break;
+      case 33: /* AVG_NUMBER_OF_BYTES_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_avg);
+        break;
+      case 34: /* MAX_NUMBER_OF_BYTES_RECV */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recv.m_max);
+        break;
+
+      case 35: /* COUNT_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_count);
+        break;
+      case 36: /* SUM_TIMER_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_sum);
+        break;
+      case 37: /* MIN_TIMER_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_min);
+        break;
+      case 38: /* AVG_TIMER_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_avg);
+        break;
+      case 39: /* MAX_TIMER_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_max);
+        break;
+      case 40: /* SUM_NUMBER_OF_BYTES_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_sum);
+        break;
+      case 41: /* MIN_NUMBER_OF_BYTES_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_min);
+        break;
+      case 42: /* AVG_NUMBER_OF_BYTES_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_avg);
+        break;
+      case 43: /* MAX_NUMBER_OF_BYTES_SEND */
+        set_field_ulonglong(f, m_row.m_io_stat.m_send.m_max);
+        break;
+
+      case 44: /* COUNT_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_count);
+        break;
+      case 45: /* SUM_TIMER_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_sum);
+        break;
+      case 46: /* MIN_TIMER_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_min);
+        break;
+      case 47: /* AVG_TIMER_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_avg);
+        break;
+      case 48: /* MAX_TIMER_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_max);
+        break;
+      case 49: /* SUM_NUMBER_OF_BYTES_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_sum);
+        break;
+      case 50: /* MIN_NUMBER_OF_BYTES_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_min);
+        break;
+      case 51: /* AVG_NUMBER_OF_BYTES_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_avg);
+        break;
+      case 52: /* MAX_NUMBER_OF_BYTES_RECVFROM */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvfrom.m_max);
+        break;
+
+      case 53: /* COUNT_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_count);
+        break;
+      case 54: /* SUM_TIMER_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_sum);
+        break;
+      case 55: /* MIN_TIMER_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_min);
+        break;
+      case 56: /* AVG_TIMER_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_avg);
+        break;
+      case 57: /* MAX_TIMER_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_max);
+        break;
+      case 58: /* SUM_NUMBER_OF_BYTES_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_sum);
+        break;
+      case 59: /* MIN_NUMBER_OF_BYTES_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_min);
+        break;
+      case 60: /* AVG_NUMBER_OF_BYTES_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_avg);
+        break;
+      case 61: /* MAX_NUMBER_OF_BYTES_SENDTO */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendto.m_max);
+        break;
+
+      case 62: /* COUNT_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_count);
+        break;
+      case 63: /* SUM_TIMER_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_sum);
+        break;
+      case 64: /* MIN_TIMER_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_min);
+        break;
+      case 65: /* AVG_TIMER_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_avg);
+        break;
+      case 66: /* MAX_TIMER_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_max);
+        break;
+      case 67: /* SUM_NUMBER_OF_BYTES_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_sum);
+        break;
+      case 68: /* MIN_NUMBER_OF_BYTES_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_min);
+        break;
+      case 69: /* AVG_NUMBER_OF_BYTES_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_avg);
+        break;
+      case 70: /* MAX_NUMBER_OF_BYTES_RECVMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_recvmsg.m_max);
+        break;
+
+      case 71: /* COUNT_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_count);
+        break;
+      case 72: /* SUM_TIMER_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_sum);
+        break;
+      case 73: /* MIN_TIMER_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_min);
+        break;
+      case 74: /* AVG_TIMER_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_avg);
+        break;
+      case 75: /* MAX_TIMER_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_max);
+        break;
+      case 76: /* SUM_NUMBER_OF_BYTES_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_sum);
+        break;
+      case 77: /* MIN_NUMBER_OF_BYTES_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_min);
+        break;
+      case 78: /* AVG_NUMBER_OF_BYTES_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_avg);
+        break;
+      case 79: /* MAX_NUMBER_OF_BYTES_SENDMSG */
+        set_field_ulonglong(f, m_row.m_io_stat.m_sendmsg.m_max);
+        break;
+
+      case 80: /* COUNT_CONNECT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_connect.m_count);
+        break;
+      case 81: /* SUM_TIMER_CONNECT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_connect.m_sum);
+        break;
+      case 82: /* MIN_TIMER_CONNECT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_connect.m_min);
+        break;
+      case 83: /* AVG_TIMER_CONNECT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_connect.m_avg);
+        break;
+      case 84: /* MAX_TIMER_CONNECT */
+        set_field_ulonglong(f, m_row.m_io_stat.m_connect.m_max);
+        break;
+
+      case 85: /* COUNT_MISC */
+        set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_count);
+        break;
+      case 86: /* SUM_TIMER_MISC */
+        set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_sum);
+        break;
+      case 87: /* MIN_TIMER_MISC */
+        set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_min);
+        break;
+      case 88: /* AVG_TIMER_MISC */
+        set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_avg);
+        break;
+      case 89: /* MAX_TIMER_MISC */
+        set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_max);
+        break;
+      default:
+        DBUG_ASSERT(false);
+        break;
+      }
+    }
+  }
+
+  return 0;
+}
+

=== added file 'storage/perfschema/table_socket_summary_by_instance.h'
--- a/storage/perfschema/table_socket_summary_by_instance.h	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_socket_summary_by_instance.h	2011-02-04 22:00:44 +0000
@@ -0,0 +1,94 @@
+/* Copyright (c) 2008, 2010, 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,
+  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef TABLE_SOCKET_SUMMARY_BY_INSTANCE_H
+#define TABLE_SOCKET_SUMMARY_BY_INSTANCE_H
+
+/**
+  @file storage/perfschema/table_socket_summary_by_instance.h
+  Table SOCKET_SUMMARY_BY_INSTANCE (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "table_helper.h"
+
+/**
+  @addtogroup Performance_schema_tables
+  @{
+*/
+
+/**
+  A row of table
+  PERFORMANCE_SCHEMA.SOCKET_SUMMARY_BY_INSTANCE.
+*/
+struct row_socket_summary_by_instance
+{
+  /** Column EVENT_NAME. */
+  PFS_event_name_row m_event_name;
+
+  /** Column OBJECT_INSTANCE_BEGIN */
+  const void *m_identity;
+
+  /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER and NUMBER_OF_BYTES for each operation. */
+  PFS_socket_io_stat_row m_io_stat;
+};
+
+/** Table PERFORMANCE_SCHEMA.SOCKET_SUMMARY_BY_INSTANCE. */
+class table_socket_summary_by_instance : public PFS_engine_table
+{
+public:
+  /** Table share */
+  static PFS_engine_table_share m_share;
+  static PFS_engine_table* create();
+
+  virtual int rnd_next();
+  virtual int rnd_pos(const void *pos);
+  virtual void reset_position(void);
+
+private:
+  virtual int read_row_values(TABLE *table,
+                              unsigned char *buf,
+                              Field **fields,
+                              bool read_all);
+
+  table_socket_summary_by_instance();
+
+public:
+  ~table_socket_summary_by_instance()
+  {}
+
+private:
+  void make_row(PFS_socket *pfs);
+
+  /** Table share lock. */
+  static THR_LOCK m_table_lock;
+  /** Fields definition. */
+  static TABLE_FIELD_DEF m_field_def;
+
+  /** Current row. */
+  row_socket_summary_by_instance m_row;
+  /** True if the current row exists. */
+  bool m_row_exists;
+  /** Current position. */
+  PFS_simple_index m_pos;
+  /** Next position. */
+  PFS_simple_index m_next_pos;
+};
+
+/** @} */
+#endif


Attachment: [text/bzr-bundle] bzr/chris.powers@oracle.com-20110207221715-e0cq6pg99bw2z57u.bundle
Thread
bzr push into mysql-trunk-wl5379 branch (chris.powers:3220 to 3225) WL#4896Christopher Powers8 Feb