From 10d282f6321cf02b060ed489550b65c35f4bee58 Mon Sep 17 00:00:00 2001
From: unknown <monty@hundin.mysql.fi>
Date: Sat, 29 Jun 2002 20:26:33 +0300
Subject: [PATCH] Added support for rw_tryrdlock() and rw_trywrlock()

include/my_sys.h:
  Removed not needed macro (SAFE_MUTEX can handle this case better).
sql/log.cc:
  Simple optimization
sql/log_event.cc:
  Fix problem in LOAD DATA if table_name is NULL (unlikely event)
sql/log_event.h:
  cleanup
sql/slave.cc:
  remove unnecessary assert
---
 include/my_pthread.h |  6 ++++
 include/my_sys.h     |  7 -----
 mysys/thr_rwlock.c   | 71 +++++++++++++++++++++++++++++++-------------
 sql/log.cc           |  8 ++---
 sql/log_event.cc     | 11 ++++---
 sql/log_event.h      | 11 ++++---
 sql/slave.cc         |  1 -
 7 files changed, 73 insertions(+), 42 deletions(-)

diff --git a/include/my_pthread.h b/include/my_pthread.h
index fda31b9d4f2..7e975a8185d 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -485,6 +485,8 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
 #define my_rwlock_init(A,B) pthread_mutex_init((A),(B))
 #define rw_rdlock(A) pthread_mutex_lock((A))
 #define rw_wrlock(A) pthread_mutex_lock((A))
+#define rw_tryrdlock(A) pthread_mutex_trylock((A))
+#define rw_trywrlock(A) pthread_mutex_trylock((A))
 #define rw_unlock(A) pthread_mutex_unlock((A))
 #define rwlock_destroy(A) pthread_mutex_destroy((A))
 #elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
@@ -492,6 +494,8 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
 #define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
 #define rw_rdlock(A) pthread_rwlock_rdlock(A)
 #define rw_wrlock(A) pthread_rwlock_wrlock(A)
+#define rw_tryrdlock(A) pthread_mutex_tryrdlock((A))
+#define rw_trywrlock(A) pthread_mutex_trywrlock((A))
 #define rw_unlock(A) pthread_rwlock_unlock(A)
 #define rwlock_destroy(A) pthread_rwlock_destroy(A)
 #elif defined(HAVE_RWLOCK_INIT)
@@ -512,6 +516,8 @@ typedef struct _my_rw_lock_t {
 #define rw_lock_t my_rw_lock_t
 #define rw_rdlock(A) my_rw_rdlock((A))
 #define rw_wrlock(A) my_rw_wrlock((A))
+#define rw_tryrdlock(A) my_rw_tryrdlock((A))
+#define rw_trywrlock(A) my_rw_trywrlock((A))
 #define rw_unlock(A) my_rw_unlock((A))
 #define rwlock_destroy(A) my_rwlock_destroy((A))
 
diff --git a/include/my_sys.h b/include/my_sys.h
index 9e64d3159c5..70de1e43a18 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -750,13 +750,6 @@ byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
 ulong checksum(const byte *mem, uint count);
 uint my_bit_log2(ulong value);
 
-#if defined(SAFE_MUTEX) && !defined(DBUG_OFF)
-#define DBUG_ASSERT_LOCK(lock) DBUG_ASSERT((lock)->count == 1 && \
-				   (lock)->thread == pthread_self())
-#else
-#define DBUG_ASSERT_LOCK(lock)
-#endif
-
 #if defined(_MSC_VER) && !defined(__WIN__)
 extern void sleep(int sec);
 #endif
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index 5f561762a3a..f1f70b5c4ac 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -19,11 +19,13 @@
 #include "mysys_priv.h"
 #include <my_pthread.h>
 #if defined(THREAD) && !defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && !defined(HAVE_RWLOCK_INIT)
+#include <errno.h>
 
 /*
- * Source base from Sun Microsystems SPILT, simplified
- * for MySQL use -- Joshua Chamas
- */
+  Source base from Sun Microsystems SPILT, simplified for MySQL use
+  -- Joshua Chamas
+  Some cleanup and additional code by Monty
+*/
 
 /*
 *  Multithreaded Demo Source
@@ -71,7 +73,7 @@ int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
   rwp->state	= 0;
   rwp->waiters	= 0;
 
-  return( 0 );
+  return(0);
 }
 
 
@@ -80,8 +82,7 @@ int my_rwlock_destroy(rw_lock_t *rwp)
   pthread_mutex_destroy( &rwp->lock );
   pthread_cond_destroy( &rwp->readers );
   pthread_cond_destroy( &rwp->writers );
-
-  return( 0 );
+  return(0);
 }
 
 
@@ -89,54 +90,84 @@ int my_rw_rdlock(rw_lock_t *rwp)
 {
   pthread_mutex_lock(&rwp->lock);
 
-  /* active or queued writers		*/
+  /* active or queued writers */
   while (( rwp->state < 0 ) || rwp->waiters)
     pthread_cond_wait( &rwp->readers, &rwp->lock);
 
   rwp->state++;
   pthread_mutex_unlock(&rwp->lock);
+  return(0);
+}
 
-  return( 0 );
+int my_rw_tryrdlock(rw_lock_t *rwp)
+{
+  int res;
+  pthread_mutex_lock(&rwp->lock);
+  if ((rwp->state < 0 ) || rwp->waiters)
+    res= EBUSY;					/* Can't get lock */
+  else
+  {
+    res=0;
+    rwp->state++;
+  }
+  pthread_mutex_unlock(&rwp->lock);
+  return(res);
 }
 
+
 int my_rw_wrlock(rw_lock_t *rwp)
 {
   pthread_mutex_lock(&rwp->lock);
-  rwp->waiters++; /* another writer queued		*/
+  rwp->waiters++;				/* another writer queued */
 
-  while ( rwp->state )
-    pthread_cond_wait( &rwp->writers, &rwp->lock);
+  while (rwp->state)
+    pthread_cond_wait(&rwp->writers, &rwp->lock);
   rwp->state	= -1;
-  --rwp->waiters;
-  pthread_mutex_unlock( &rwp->lock );
-
+  rwp->waiters--;
+  pthread_mutex_unlock(&rwp->lock);
   return(0);
 }
 
 
+int my_rw_trywrlock(rw_lock_t *rwp)
+{
+  int res;
+  pthread_mutex_lock(&rwp->lock);
+  if (rwp->state)
+    res= EBUSY;					/* Can't get lock */    
+  else
+  {
+    res=0;
+    rwp->state	= -1;
+  }
+  pthread_mutex_unlock(&rwp->lock);
+  return(res);
+}
+
+
 int my_rw_unlock(rw_lock_t *rwp)
 {
   DBUG_PRINT("rw_unlock",
 	     ("state: %d waiters: %d", rwp->state, rwp->waiters));
   pthread_mutex_lock(&rwp->lock);
 
-  if ( rwp->state == -1 ) {	/* writer releasing	*/
-    rwp->state	= 0;		/* mark as available	*/
+  if (rwp->state == -1)		/* writer releasing */
+  {
+    rwp->state= 0;		/* mark as available */
 
-    if ( rwp->waiters )		/* writers queued	*/
+    if ( rwp->waiters )		/* writers queued */
       pthread_cond_signal( &rwp->writers );
     else
       pthread_cond_broadcast( &rwp->readers );
   }
   else
   {
-    if ( --rwp->state == 0 )	/* no more readers	*/
+    if ( --rwp->state == 0 )	/* no more readers */
       pthread_cond_signal( &rwp->writers );
   }
 
   pthread_mutex_unlock( &rwp->lock );
-
-  return( 0 );
+  return(0);
 }
 
 #endif
diff --git a/sql/log.cc b/sql/log.cc
index b0483ea4a27..f8bcd05510d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -888,15 +888,15 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
 
 bool MYSQL_LOG::write(Log_event* event_info)
 {
-  /* In most cases this is only called if 'is_open()' is true */
   bool error=0;
-  bool should_rotate = 0;
   
   if (!inited)					// Can't use mutex if not init
     return 0;
   VOID(pthread_mutex_lock(&LOCK_log));
+  /* In most cases this is only called if 'is_open()' is true */
   if (is_open())
   {
+    bool should_rotate = 0;
     THD *thd=event_info->thd;
     const char* db = event_info->get_db();
 #ifdef USING_TRANSACTIONS    
@@ -985,9 +985,9 @@ bool MYSQL_LOG::write(Log_event* event_info)
     }
     if (file == &log_file)
       signal_update();
+    if (should_rotate)
+      new_file(1); // inside mutex
   }
-  if (should_rotate)
-    new_file(1); // inside mutex
   VOID(pthread_mutex_unlock(&LOCK_log));
   return error;
 }
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 5ff2362e9db..6765ecc5b1f 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1022,16 +1022,19 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
 #ifndef MYSQL_CLIENT
 Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
 			       const char* db_arg, const char* table_name_arg,
-		 List<Item>& fields_arg, enum enum_duplicates handle_dup)
+			       List<Item>& fields_arg,
+			       enum enum_duplicates handle_dup)
   :Log_event(thd),thread_id(thd->thread_id), num_fields(0),fields(0),
-  field_lens(0),field_block_len(0), table_name(table_name_arg),
+  field_lens(0),field_block_len(0),
+  table_name(table_name_arg ? table_name_arg : ""),
   db(db_arg), fname(ex->file_name)
 {
   time_t end_time;
   time(&end_time);
   exec_time = (ulong) (end_time  - thd->start_time);
-  db_len = (db) ? (uint32) strlen(db) : 0;
-  table_name_len = (table_name) ? (uint32) strlen(table_name) : 0;
+  /* db can never be a zero pointer in 4.0 */
+  db_len = (uint32) strlen(db);
+  table_name_len = (uint32) strlen(table_name);
   fname_len = (fname) ? (uint) strlen(fname) : 0;
   sql_ex.field_term = (char*) ex->field_term->ptr();
   sql_ex.field_term_len = (uint8) ex->field_term->length();
diff --git a/sql/log_event.h b/sql/log_event.h
index 29cf6287a4f..bcdcc72e0c2 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -407,15 +407,15 @@ class Load_log_event: public Log_event
   String fields_buf;
   
   Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
-			       const char* table_name_arg,
+		 const char* table_name_arg,
 		 List<Item>& fields_arg, enum enum_duplicates handle_dup);
   void set_fields(List<Item> &fields_arg);
   void pack_info(String* packet);
   const char* get_db() { return db; }
   int exec_event(struct st_relay_log_info* rli)
-    {
-      return exec_event(thd->slave_net,rli);
-    }
+  {
+    return exec_event(thd->slave_net,rli);
+  }
   int exec_event(NET* net, struct st_relay_log_info* rli);
 #else
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
@@ -423,8 +423,7 @@ class Load_log_event: public Log_event
 
   Load_log_event(const char* buf, int event_len, bool old_format);
   ~Load_log_event()
-  {
-  }
+  {}
   Log_event_type get_type_code() { return sql_ex.new_format() ?
 				     NEW_LOAD_EVENT: LOAD_EVENT; }
   int write_data_header(IO_CACHE* file); 
diff --git a/sql/slave.cc b/sql/slave.cc
index 5ca78b6c7a2..4b58816f409 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -405,7 +405,6 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
     */
     struct timespec abstime;
     set_timespec(abstime,2);
-    DBUG_ASSERT_LOCK(cond_lock);
     pthread_cond_timedwait(term_cond, cond_lock, &abstime);
     if (*slave_running)
     {
-- 
2.30.9