List:Commits« Previous MessageNext Message »
From:ahmad.abdullateef Date:January 2 2013 8:26am
Subject:bzr push into mysql-trunk branch (ahmad.abdullateef:5313 to 5314)
Bug#13934876
View as plain text  
 5314 Ahmad Abdullateef	2013-01-02 [merge]
      BUG#13934876 - SHARED MEMORY CONNECTIONS CRASH THE SERVER 
                                   WHEN ENDING 
      
      DESCRIPTION:
      When mysqld is in shared memory mode under windows and
      we stress test the server with a multi threaded client
      which also randomly issues "kill connection" command
      we see the mysqld process crashing randomly.
      
      
      ANALYSIS :
      When "kill connection xx" is received and executed on an 
      arbitrary thread it calls THD::shutdown_active_vio() on the 
      THD refered to by connection xx, this results in the 
      shared memory being unmapped. However the original thread
      serving the connection xx might be in middle of a vio_read
      or vio_write and it might end up accessing the unmapped
      region of memory resulting in a crash.
      
      
      FIX :
      When "kill connection xx" is executed on an arbitrary thread it calls
      THD::shutdown_active_vio() on the THD referred to by xx, this results in the
      shared memory being unmapped. However the thread serving the connection xx
      might be in middle of a vio_read or vio_write and it might end up accessing
      the unmapped region of memory.
      
      All handles are closed and the VIO is cleaned up when vio_delete() is
      called and this completes the vio cleanup operation in its entirety.
      
      All references to vio_close has been changed to vio_shutdown to cleanup code
      and make its meaning relevant.

    modified:
      config.h.cmake
      configure.cmake
      include/violite.h
      sql/rpl_slave.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_connect.cc
      sql/sql_prepare.cc
      vio/vio.c
      vio/vio_priv.h
      vio/viopipe.c
      vio/vioshm.c
      vio/viosocket.c
      vio/viossl.c
 5313 Ahmad Abdullateef	2013-01-02 [merge]
      BUG#14792410 - INCONSISTENCY ABOUT MESSAGEFILE PATH NAME STYLE 
                     IN MTR ON ALL PLATFORMS
      
      DESCRIPTION:
      Errors are printed in the Server logs when a directory containg errmsg.sys
      is specified directly through the --lc-messages-dir or --language parameter.
      
      
      FIX :
      Improved the messaging and changed sql_print_error() to sql_print_warning().

    modified:
      sql/derror.cc
=== modified file 'config.h.cmake'
--- a/config.h.cmake	2012-12-18 08:54:05 +0000
+++ b/config.h.cmake	2013-01-02 08:09:22 +0000
@@ -495,7 +495,7 @@
 #define MACHINE_TYPE "@MYSQL_MACHINE_TYPE@"
 #cmakedefine HAVE_DTRACE 1
 
-#cmakedefine SIGNAL_WITH_VIO_CLOSE 1
+#cmakedefine SIGNAL_WITH_VIO_SHUTDOWN 1
 
 /* Windows stuff, mostly functions, that have Posix analogs but named differently */
 #cmakedefine S_IROTH @S_IROTH@

=== modified file 'configure.cmake'
--- a/configure.cmake	2012-11-23 13:12:26 +0000
+++ b/configure.cmake	2013-01-02 08:09:22 +0000
@@ -55,7 +55,7 @@ ENDIF()
 # As a consequence of ALARMs no longer being used, thread
 # notification for KILL must close the socket to wake up
 # other threads.
-SET(SIGNAL_WITH_VIO_CLOSE 1)
+SET(SIGNAL_WITH_VIO_SHUTDOWN 1)
 
 # Always enable -Wall for gnu C/C++
 IF(CMAKE_COMPILER_IS_GNUCXX)

=== modified file 'include/violite.h'
--- a/include/violite.h	2012-11-06 09:20:51 +0000
+++ b/include/violite.h	2013-01-02 08:09:22 +0000
@@ -37,8 +37,8 @@ typedef struct st_vio Vio;
 
 enum enum_vio_type
 {
-  VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, VIO_TYPE_NAMEDPIPE,
-  VIO_TYPE_SSL, VIO_TYPE_SHARED_MEMORY
+  VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL, 
+  VIO_TYPE_SHARED_MEMORY
 };
 
 /**
@@ -71,19 +71,19 @@ Vio* vio_new_win32shared_memory(HANDLE h
 #define HANDLE void *
 #endif /* __WIN__ */
 
-void	vio_delete(Vio* vio);
-int	vio_close(Vio* vio);
+void    vio_delete(Vio* vio);
+int vio_shutdown(Vio* vio);
 my_bool vio_reset(Vio* vio, enum enum_vio_type type,
                   my_socket sd, void *ssl, uint flags);
-size_t	vio_read(Vio *vio, uchar *	buf, size_t size);
+size_t  vio_read(Vio *vio, uchar *	buf, size_t size);
 size_t  vio_read_buff(Vio *vio, uchar * buf, size_t size);
-size_t	vio_write(Vio *vio, const uchar * buf, size_t size);
+size_t  vio_write(Vio *vio, const uchar * buf, size_t size);
 /* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible */
-int	vio_fastsend(Vio *vio);
+int vio_fastsend(Vio *vio);
 /* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible */
-int	vio_keepalive(Vio *vio, my_bool	onoff);
+int vio_keepalive(Vio *vio, my_bool	onoff);
 /* Whenever we should retry the last read/write operation. */
-my_bool	vio_should_retry(Vio *vio);
+my_bool vio_should_retry(Vio *vio);
 /* Check that operation was timed out */
 my_bool vio_was_timeout(Vio *vio);
 /* Short text description of the socket for those, who are curious.. */
@@ -161,13 +161,13 @@ int sslconnect(struct st_VioSSLFd*, Vio 
 
 struct st_VioSSLFd
 *new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
-		       const char *ca_file,  const char *ca_path,
-		       const char *cipher, enum enum_ssl_init_error *error,
+                       const char *ca_file,  const char *ca_path,
+                       const char *cipher, enum enum_ssl_init_error *error,
                        const char *crl_file, const char *crl_path);
 struct st_VioSSLFd
 *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
-		      const char *ca_file,const char *ca_path,
-		      const char *cipher, enum enum_ssl_init_error *error,
+                      const char *ca_file,const char *ca_path,
+                      const char *cipher, enum enum_ssl_init_error *error,
                       const char *crl_file, const char *crl_path);
 void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
 #endif /* ! EMBEDDED_LIBRARY */
@@ -175,21 +175,21 @@ void free_vio_ssl_acceptor_fd(struct st_
 
 void vio_end(void);
 
-#ifdef	__cplusplus
+#ifdef  __cplusplus
 }
 #endif
 
 #if !defined(DONT_MAP_VIO)
-#define vio_delete(vio) 			(vio)->viodelete(vio)
-#define vio_errno(vio)	 			(vio)->vioerrno(vio)
+#define vio_delete(vio)                         (vio)->viodelete(vio)
+#define vio_errno(vio)                          (vio)->vioerrno(vio)
 #define vio_read(vio, buf, size)                ((vio)->read)(vio,buf,size)
 #define vio_write(vio, buf, size)               ((vio)->write)(vio, buf, size)
-#define vio_fastsend(vio)			(vio)->fastsend(vio)
-#define vio_keepalive(vio, set_keep_alive)	(vio)->viokeepalive(vio, set_keep_alive)
-#define vio_should_retry(vio) 			(vio)->should_retry(vio)
+#define vio_fastsend(vio)                       (vio)->fastsend(vio)
+#define vio_keepalive(vio, set_keep_alive)  (vio)->viokeepalive(vio, set_keep_alive)
+#define vio_should_retry(vio)                   (vio)->should_retry(vio)
 #define vio_was_timeout(vio)                    (vio)->was_timeout(vio)
-#define vio_close(vio)				((vio)->vioclose)(vio)
-#define vio_peer_addr(vio, buf, prt, buflen)	(vio)->peer_addr(vio, buf, prt, buflen)
+#define vio_shutdown(vio)                       ((vio)->vioshutdown)(vio)
+#define vio_peer_addr(vio, buf, prt, buflen)    (vio)->peer_addr(vio, buf, prt, buflen)
 #define vio_io_wait(vio, event, timeout)        (vio)->io_wait(vio, event, timeout)
 #define vio_is_connected(vio)                   (vio)->is_connected(vio)
 #endif /* !defined(DONT_MAP_VIO) */
@@ -209,13 +209,14 @@ enum SSL_type
 /* This structure is for every connection on both sides */
 struct st_vio
 {
-  MYSQL_SOCKET  mysql_socket;     /* Instrumented socket */
-  my_bool		localhost;	/* Are we from localhost? */
-  struct sockaddr_storage	local;		/* Local internet address */
-  struct sockaddr_storage	remote;		/* Remote internet address */
+  MYSQL_SOCKET  mysql_socket;           /* Instrumented socket */
+  my_bool       localhost;              /* Are we from localhost? */
+  struct sockaddr_storage   local;      /* Local internet address */
+  struct sockaddr_storage   remote;     /* Remote internet address */
   int addrLen;                          /* Length of remote address */
-  enum enum_vio_type	type;		/* Type of connection */
-  char			desc[VIO_DESCRIPTION_SIZE]; /* Description string. This
+  enum enum_vio_type    type;           /* Type of connection */
+  my_bool               inactive; /* Connection inactive (has been shutdown) */
+  char                  desc[VIO_DESCRIPTION_SIZE]; /* Description string. This
                                                       member MUST NOT be
                                                       used directly, but only
                                                       via function
@@ -226,7 +227,16 @@ struct st_vio
   char                  *read_end;      /* end of unfetched data */
   int                   read_timeout;   /* Timeout value (ms) for read ops. */
   int                   write_timeout;  /* Timeout value (ms) for write ops. */
-  /* function pointers. They are similar for socket/SSL/whatever */
+  
+  /* 
+     VIO vtable interface to be implemented by VIO's like SSL, Socket,
+     Named Pipe, etc.
+  */
+  
+  /* 
+     viodelete is responsible for cleaning up the VIO object by freeing 
+     internal buffers, closing descriptors, handles. 
+  */
   void    (*viodelete)(Vio*);
   int     (*vioerrno)(Vio*);
   size_t  (*read)(Vio*, uchar *, size_t);
@@ -238,7 +248,12 @@ struct st_vio
   void    (*in_addr)(Vio*, struct sockaddr_storage*);
   my_bool (*should_retry)(Vio*);
   my_bool (*was_timeout)(Vio*);
-  int     (*vioclose)(Vio*);
+  /* 
+     vioshutdown is resposnible to shutdown/close the channel, so that no 
+     further communications can take place, however any related buffers,
+     descriptors, handles can remain valid after a shutdown.
+  */
+  int     (*vioshutdown)(Vio*);
   my_bool (*is_connected)(Vio*);
   my_bool (*has_data) (Vio*);
   int (*io_wait)(Vio*, enum enum_vio_io_event, int);
@@ -248,7 +263,7 @@ struct st_vio
   HANDLE hPipe;
 #endif
 #ifdef HAVE_OPENSSL
-  void	  *ssl_arg;
+  void    *ssl_arg;
 #endif
 #ifdef HAVE_SMEM
   HANDLE  handle_file_map;

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2012-12-14 15:20:59 +0000
+++ b/sql/rpl_slave.cc	2013-01-02 08:09:22 +0000
@@ -3883,7 +3883,7 @@ static int try_to_reconnect(THD *thd, MY
 {
   mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
   thd->proc_info= messages[SLAVE_RECON_MSG_WAIT];
-#ifdef SIGNAL_WITH_VIO_CLOSE  
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN  
   thd->clear_active_vio();
 #endif
   end_server(mysql);
@@ -4291,11 +4291,11 @@ err:
       Here we need to clear the active VIO before closing the
       connection with the master.  The reason is that THD::awake()
       might be called from terminate_slave_thread() because somebody
-      issued a STOP SLAVE.  If that happends, the close_active_vio()
+      issued a STOP SLAVE.  If that happends, the shutdown_active_vio()
       can be called in the middle of closing the VIO associated with
       the 'mysql' object, causing a crash.
     */
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
     thd->clear_active_vio();
 #endif
     mysql_close(mysql);
@@ -6576,7 +6576,7 @@ err:
 
 extern "C" void slave_io_thread_detach_vio()
 {
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
   THD *thd= current_thd;
   if (thd && thd->slave_thread)
     thd->clear_active_vio();
@@ -6754,7 +6754,7 @@ replication resumed in log '%s' at posit
       general_log_print(thd, COM_CONNECT_OUT, "%s@%s:%d",
                         mi->get_user(), mi->host, mi->port);
     }
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
     thd->set_active_vio(mysql->net.vio);
 #endif
   }

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2012-12-19 09:35:15 +0000
+++ b/sql/sql_class.cc	2013-01-02 08:09:22 +0000
@@ -329,7 +329,7 @@ void thd_unlock_thread_count(THD *)
 void thd_close_connection(THD *thd)
 {
   if (thd->net.vio)
-    vio_close(thd->net.vio);
+    vio_shutdown(thd->net.vio);
 }
 
 /**
@@ -988,7 +988,7 @@ THD::THD(bool enable_plugins)
   peer_port= 0;					// For SHOW PROCESSLIST
   transaction.m_pending_rows_event= 0;
   transaction.flags.enabled= true;
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
   active_vio = 0;
 #endif
   mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST);
@@ -1711,7 +1711,7 @@ void THD::awake(THD::killed_state state_
 
   if (state_to_set != THD::KILL_QUERY)
   {
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
     if (this != current_thd)
     {
       /*
@@ -1740,7 +1740,7 @@ void THD::awake(THD::killed_state state_
         reading the next statement.
       */
 
-      close_active_vio();
+      shutdown_active_vio();
     }
 #endif
 
@@ -1809,20 +1809,20 @@ void THD::disconnect()
 
   killed= THD::KILL_CONNECTION;
 
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
   /*
     Since a active vio might might have not been set yet, in
     any case save a reference to avoid closing a inexistent
     one or closing the vio twice if there is a active one.
   */
   vio= active_vio;
-  close_active_vio();
+  shutdown_active_vio();
 #endif
 
   /* Disconnect even if a active vio is not associated. */
   if (net.vio != vio && net.vio != NULL)
   {
-    vio_close(net.vio);
+    vio_shutdown(net.vio);
   }
 
   mysql_mutex_unlock(&LOCK_thd_data);
@@ -2269,15 +2269,15 @@ int THD::send_explain_fields(select_resu
                                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
 }
 
-#ifdef SIGNAL_WITH_VIO_CLOSE
-void THD::close_active_vio()
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
+void THD::shutdown_active_vio()
 {
-  DBUG_ENTER("close_active_vio");
+  DBUG_ENTER("shutdown_active_vio");
   mysql_mutex_assert_owner(&LOCK_thd_data);
 #ifndef EMBEDDED_LIBRARY
   if (active_vio)
   {
-    vio_close(active_vio);
+    vio_shutdown(active_vio);
     active_vio = 0;
   }
 #endif

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-12-13 11:16:18 +0000
+++ b/sql/sql_class.h	2013-01-02 08:09:22 +0000
@@ -2389,7 +2389,7 @@ public:
 #ifndef __WIN__
   sigset_t signals;
 #endif
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
   Vio* active_vio;
 #endif
   /*
@@ -3009,7 +3009,7 @@ public:
   void cleanup_after_query();
   bool store_globals();
   bool restore_globals();
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
   inline void set_active_vio(Vio* vio)
   {
     mysql_mutex_lock(&LOCK_thd_data);
@@ -3022,7 +3022,7 @@ public:
     active_vio = 0;
     mysql_mutex_unlock(&LOCK_thd_data);
   }
-  void close_active_vio();
+  void shutdown_active_vio();
 #endif
   void awake(THD::killed_state state_to_set);
 

=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc	2012-11-21 12:44:48 +0000
+++ b/sql/sql_connect.cc	2013-01-02 08:09:22 +0000
@@ -501,7 +501,7 @@ static int check_connection(THD *thd)
 
   DBUG_PRINT("info",
              ("New connection received on %s", vio_description(net->vio)));
-#ifdef SIGNAL_WITH_VIO_CLOSE
+#ifdef SIGNAL_WITH_VIO_SHUTDOWN
   thd->set_active_vio(net->vio);
 #endif
 

=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc	2012-11-21 12:44:48 +0000
+++ b/sql/sql_prepare.cc	2013-01-02 08:09:22 +0000
@@ -2644,7 +2644,7 @@ void mysqld_stmt_execute(THD *thd, char 
   sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
 
   /* Close connection socket; for use with client testing (Bug#43560). */
-  DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio););
+  DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_shutdown(thd->net.vio););
 
   DBUG_VOID_RETURN;
 }

=== modified file 'vio/vio.c'
--- a/vio/vio.c	2012-12-11 15:56:03 +0000
+++ b/vio/vio.c	2013-01-02 08:09:22 +0000
@@ -84,7 +84,7 @@ static void vio_init(Vio *vio, enum enum
     vio->viokeepalive	=vio_keepalive;
     vio->should_retry	=vio_should_retry;
     vio->was_timeout    =vio_was_timeout;
-    vio->vioclose	=vio_close_pipe;
+    vio->vioshutdown	=vio_shutdown_pipe;
     vio->peer_addr	=vio_peer_addr;
     vio->io_wait        =no_io_wait;
     vio->is_connected   =vio_is_connected_pipe;
@@ -95,7 +95,7 @@ static void vio_init(Vio *vio, enum enum
 #ifdef HAVE_SMEM
   if (type == VIO_TYPE_SHARED_MEMORY)
   {
-    vio->viodelete	=vio_delete;
+    vio->viodelete	=vio_delete_shared_memory;
     vio->vioerrno	=vio_errno;
     vio->read           =vio_read_shared_memory;
     vio->write          =vio_write_shared_memory;
@@ -103,7 +103,7 @@ static void vio_init(Vio *vio, enum enum
     vio->viokeepalive	=vio_keepalive;
     vio->should_retry	=vio_should_retry;
     vio->was_timeout    =vio_was_timeout;
-    vio->vioclose	=vio_close_shared_memory;
+    vio->vioshutdown	=vio_shutdown_shared_memory;
     vio->peer_addr	=vio_peer_addr;
     vio->io_wait        =no_io_wait;
     vio->is_connected   =vio_is_connected_shared_memory;
@@ -122,7 +122,7 @@ static void vio_init(Vio *vio, enum enum
     vio->viokeepalive	=vio_keepalive;
     vio->should_retry	=vio_should_retry;
     vio->was_timeout    =vio_was_timeout;
-    vio->vioclose	=vio_ssl_close;
+    vio->vioshutdown	=vio_ssl_shutdown;
     vio->peer_addr	=vio_peer_addr;
     vio->io_wait        =vio_io_wait;
     vio->is_connected   =vio_is_connected;
@@ -139,7 +139,7 @@ static void vio_init(Vio *vio, enum enum
   vio->viokeepalive     =vio_keepalive;
   vio->should_retry     =vio_should_retry;
   vio->was_timeout      =vio_was_timeout;
-  vio->vioclose         =vio_close;
+  vio->vioshutdown      =vio_shutdown;
   vio->peer_addr        =vio_peer_addr;
   vio->io_wait          =vio_io_wait;
   vio->is_connected     =vio_is_connected;
@@ -335,8 +335,8 @@ void vio_delete(Vio* vio)
   if (!vio)
     return; /* It must be safe to delete null pointers. */
 
-  if (vio->type != VIO_CLOSED)
-    vio->vioclose(vio);
+  if (vio->inactive == FALSE)
+    vio->vioshutdown(vio);
   my_free(vio->read_buffer);
   my_free(vio);
 }

=== modified file 'vio/vio_priv.h'
--- a/vio/vio_priv.h	2011-09-07 10:08:09 +0000
+++ b/vio/vio_priv.h	2013-01-02 07:54:14 +0000
@@ -29,14 +29,15 @@
 size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size);
 size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size);
 my_bool vio_is_connected_pipe(Vio *vio);
-int vio_close_pipe(Vio * vio);
+int vio_shutdown_pipe(Vio * vio);
 #endif
 
 #ifdef HAVE_SMEM
 size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size);
 size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size);
 my_bool vio_is_connected_shared_memory(Vio *vio);
-int vio_close_shared_memory(Vio * vio);
+int vio_shutdown_shared_memory(Vio * vio);
+void vio_delete_shared_memory(Vio *vio);
 #endif
 
 my_bool vio_buff_has_data(Vio *vio);
@@ -50,7 +51,7 @@ size_t	vio_ssl_read(Vio *vio,uchar* buf,
 size_t	vio_ssl_write(Vio *vio,const uchar* buf, size_t size);
 
 /* When the workday is over... */
-int vio_ssl_close(Vio *vio);
+int vio_ssl_shutdown(Vio *vio);
 void vio_ssl_delete(Vio *vio);
 my_bool vio_ssl_has_data(Vio *vio);
 

=== modified file 'vio/viopipe.c'
--- a/vio/viopipe.c	2011-06-06 19:57:05 +0000
+++ b/vio/viopipe.c	2013-01-02 07:54:14 +0000
@@ -101,17 +101,17 @@ my_bool vio_is_connected_pipe(Vio *vio)
 }
 
 
-int vio_close_pipe(Vio *vio)
+int vio_shutdown_pipe(Vio *vio)
 {
   BOOL ret;
-  DBUG_ENTER("vio_close_pipe");
+  DBUG_ENTER("vio_shutdown_pipe");
 
   CancelIo(vio->hPipe);
   CloseHandle(vio->overlapped.hEvent);
   DisconnectNamedPipe(vio->hPipe);
   ret= CloseHandle(vio->hPipe);
 
-  vio->type= VIO_CLOSED;
+  vio->inactive= TRUE;
   vio->hPipe= NULL;
   vio->mysql_socket= MYSQL_INVALID_SOCKET;
 

=== modified file 'vio/vioshm.c'
--- a/vio/vioshm.c	2011-06-06 19:57:05 +0000
+++ b/vio/vioshm.c	2013-01-02 07:54:14 +0000
@@ -43,7 +43,7 @@ size_t vio_read_shared_memory(Vio *vio, 
                                           FALSE, timeout);
 
       /*
-        WaitForMultipleObjects can return next values:
+         WaitForMultipleObjects can return next values:
          WAIT_OBJECT_0+0 - event from vio->event_server_wrote
          WAIT_OBJECT_0+1 - event from vio->event_conn_closed.
                            We can't read anything
@@ -153,64 +153,73 @@ my_bool vio_is_connected_shared_memory(V
 }
 
 
-/**
- Close shared memory and DBUG_PRINT any errors that happen on closing.
- @return Zero if all closing functions succeed, and nonzero otherwise.
+void vio_delete_shared_memory(Vio *vio)
+{
+  DBUG_ENTER("vio_delete_shared_memory");
+
+  if (!vio)
+    DBUG_VOID_RETURN;
+
+  if (vio->inactive == FALSE)
+    vio->vioshutdown(vio);
+
+  /*
+    Close all handlers. UnmapViewOfFile and CloseHandle return non-zero
+    result if they are success.
+  */
+  if (UnmapViewOfFile(vio->handle_map) == 0)
+    DBUG_PRINT("vio_error", ("UnmapViewOfFile() failed"));
+  
+  if (CloseHandle(vio->event_server_wrote) == 0)
+    DBUG_PRINT("vio_error", ("CloseHandle(vio->esw) failed"));
+  
+  if (CloseHandle(vio->event_server_read) == 0)
+    DBUG_PRINT("vio_error", ("CloseHandle(vio->esr) failed"));
+  
+  if (CloseHandle(vio->event_client_wrote) == 0)
+    DBUG_PRINT("vio_error", ("CloseHandle(vio->ecw) failed"));
+  
+  if (CloseHandle(vio->event_client_read) == 0)
+    DBUG_PRINT("vio_error", ("CloseHandle(vio->ecr) failed"));
+
+  if (CloseHandle(vio->handle_file_map) == 0)
+    DBUG_PRINT("vio_error", ("CloseHandle(vio->hfm) failed"));
+
+  if (CloseHandle(vio->event_conn_closed) == 0)
+    DBUG_PRINT("vio_error", ("CloseHandle(vio->ecc) failed"));
+
+  vio_delete(vio);
+
+  DBUG_VOID_RETURN;
+}
+
+/*
+  When "kill connection xx" is executed on an arbitrary thread it calls
+  THD::shutdown_active_vio() on the THD referred to by xx. Since the
+  thread serving the connection xx might be in the middle of a vio_read
+  or vio_write, we cannot unmap the shared memory here.
+
+  Therefore we here just signal the connection_closed event and give
+  the thread servicing connection xx a chance to gracefully exit.
+  All handles are closed and the VIO is cleaned up when vio_delete() is
+  called and this completes the vio cleanup operation in its entirety.
 */
-int vio_close_shared_memory(Vio * vio)
+int vio_shutdown_shared_memory(Vio * vio)
 {
-  int error_count= 0;
-  DBUG_ENTER("vio_close_shared_memory");
-  if (vio->type != VIO_CLOSED)
+  DBUG_ENTER("vio_shutdown_shared_memory");
+  if (vio->inactive == FALSE)
   {
     /*
       Set event_conn_closed for notification of both client and server that
       connection is closed
     */
     SetEvent(vio->event_conn_closed);
-    /*
-      Close all handlers. UnmapViewOfFile and CloseHandle return non-zero
-      result if they are success.
-    */
-    if (UnmapViewOfFile(vio->handle_map) == 0)
-    {
-      error_count++;
-      DBUG_PRINT("vio_error", ("UnmapViewOfFile() failed"));
-    }
-    if (CloseHandle(vio->event_server_wrote) == 0)
-    {
-      error_count++;
-      DBUG_PRINT("vio_error", ("CloseHandle(vio->esw) failed"));
-    }
-    if (CloseHandle(vio->event_server_read) == 0)
-    {
-      error_count++;
-      DBUG_PRINT("vio_error", ("CloseHandle(vio->esr) failed"));
-    }
-    if (CloseHandle(vio->event_client_wrote) == 0)
-    {
-      error_count++;
-      DBUG_PRINT("vio_error", ("CloseHandle(vio->ecw) failed"));
-    }
-    if (CloseHandle(vio->event_client_read) == 0)
-    {
-      error_count++;
-      DBUG_PRINT("vio_error", ("CloseHandle(vio->ecr) failed"));
-    }
-    if (CloseHandle(vio->handle_file_map) == 0)
-    {
-      error_count++;
-      DBUG_PRINT("vio_error", ("CloseHandle(vio->hfm) failed"));
-    }
-    if (CloseHandle(vio->event_conn_closed) == 0)
-    {
-      error_count++;
-      DBUG_PRINT("vio_error", ("CloseHandle(vio->ecc) failed"));
-    }
   }
-  vio->type= VIO_CLOSED;
+
+  vio->inactive= TRUE;
   vio->mysql_socket= MYSQL_INVALID_SOCKET;
-  DBUG_RETURN(error_count);
+
+  DBUG_RETURN(0);
 }
 
 #endif /* #if defined(_WIN32) && defined(HAVE_SMEM) */

=== modified file 'vio/viosocket.c'
--- a/vio/viosocket.c	2012-11-09 12:19:42 +0000
+++ b/vio/viosocket.c	2013-01-02 08:09:22 +0000
@@ -400,12 +400,12 @@ vio_was_timeout(Vio *vio)
 }
 
 
-int vio_close(Vio * vio)
+int vio_shutdown(Vio * vio)
 {
   int r=0;
-  DBUG_ENTER("vio_close");
+  DBUG_ENTER("vio_shutdown");
 
- if (vio->type != VIO_CLOSED)
+ if (vio->inactive == FALSE)
   {
     DBUG_ASSERT(vio->type ==  VIO_TYPE_TCPIP ||
       vio->type == VIO_TYPE_SOCKET ||
@@ -422,7 +422,7 @@ int vio_close(Vio * vio)
     DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
     /* FIXME: error handling (not critical for MySQL) */
   }
-  vio->type= VIO_CLOSED;
+  vio->inactive= TRUE;
   vio->mysql_socket= MYSQL_INVALID_SOCKET;
   DBUG_RETURN(r);
 }

=== modified file 'vio/viossl.c'
--- a/vio/viossl.c	2011-09-07 10:08:09 +0000
+++ b/vio/viossl.c	2013-01-02 07:54:14 +0000
@@ -210,11 +210,11 @@ static long yassl_send(void *ptr, const 
 
 #endif
 
-int vio_ssl_close(Vio *vio)
+int vio_ssl_shutdown(Vio *vio)
 {
   int r= 0;
   SSL *ssl= (SSL*)vio->ssl_arg;
-  DBUG_ENTER("vio_ssl_close");
+  DBUG_ENTER("vio_ssl_shutdown");
 
   if (ssl)
   {
@@ -245,7 +245,7 @@ int vio_ssl_close(Vio *vio)
       break;
     }
   }
-  DBUG_RETURN(vio_close(vio));
+  DBUG_RETURN(vio_shutdown(vio));
 }
 
 
@@ -254,8 +254,8 @@ void vio_ssl_delete(Vio *vio)
   if (!vio)
     return; /* It must be safe to delete null pointer */
 
-  if (vio->type == VIO_TYPE_SSL)
-    vio_ssl_close(vio); /* Still open, close connection first */
+  if (vio->inactive == FALSE)
+    vio_ssl_shutdown(vio); /* Still open, close connection first */
 
   if (vio->ssl_arg)
   {

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (ahmad.abdullateef:5313 to 5314)Bug#13934876ahmad.abdullateef26 Jan