summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/config-win.h3
-rw-r--r--include/my_pthread.h9
-rw-r--r--mysys/my_winthread.c23
-rw-r--r--mysys/thr_mutex.c49
4 files changed, 73 insertions, 11 deletions
diff --git a/include/config-win.h b/include/config-win.h
index 2e64e165630..07b316dcbab 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -21,6 +21,9 @@
/* We have to do this define before including windows.h to get the AWE API
functions */
#define _WIN32_WINNT 0x0500
+#else
+/* Get NT 4.0 functions */
+#define _WIN32_WINNT 0x0400
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1400
diff --git a/include/my_pthread.h b/include/my_pthread.h
index eb390c2acc4..88abddc9e25 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -101,6 +101,7 @@ struct timespec {
void win_pthread_init(void);
int win_pthread_setspecific(void *A,void *B,uint length);
+int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
@@ -156,7 +157,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#define pthread_equal(A,B) ((A) == (B))
#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
-#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
+#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
@@ -472,7 +473,7 @@ typedef struct st_safe_mutex_info_t
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
const char *file, uint line);
-int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line);
+int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
@@ -495,12 +496,12 @@ void safe_mutex_end(FILE *file);
#undef pthread_cond_timedwait
#undef pthread_mutex_trylock
#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__)
-#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
+#define pthread_mutex_lock(A) safe_mutex_lock((A), FALSE, __FILE__, __LINE__)
#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
-#define pthread_mutex_trylock(A) pthread_mutex_lock(A)
+#define pthread_mutex_trylock(A) safe_mutex_lock((A), TRUE, __FILE__, __LINE__)
#define pthread_mutex_t safe_mutex_t
#define safe_mutex_assert_owner(mp) \
DBUG_ASSERT((mp)->count > 0 && \
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index 27ccaef4f23..e94369bec32 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -40,6 +40,29 @@ void win_pthread_init(void)
pthread_mutex_init(&THR_LOCK_thread,MY_MUTEX_INIT_FAST);
}
+
+/**
+ Adapter to @c pthread_mutex_trylock()
+
+ @retval 0 Mutex was acquired
+ @retval EBUSY Mutex was already locked by a thread
+ */
+int
+win_pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+ if (TryEnterCriticalSection(mutex))
+ {
+ /* Don't allow recursive lock */
+ if (mutex->RecursionCount > 1){
+ LeaveCriticalSection(mutex);
+ return EBUSY;
+ }
+ return 0;
+ }
+ return EBUSY;
+}
+
+
/*
** We have tried to use '_beginthreadex' instead of '_beginthread' here
** but in this case the program leaks about 512 characters for each
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index e7a927e562a..49003553f0b 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -91,7 +91,7 @@ int safe_mutex_init(safe_mutex_t *mp,
}
-int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
+int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line)
{
int error;
if (!mp->file)
@@ -104,15 +104,50 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
}
pthread_mutex_lock(&mp->global);
- if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread))
+ if (mp->count > 0)
{
- fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d in thread %s\n",
- file,line,mp->file, mp->line, my_thread_name());
- fflush(stderr);
- abort();
+ if (try_lock)
+ {
+ pthread_mutex_unlock(&mp->global);
+ return EBUSY;
+ }
+ else if (pthread_equal(pthread_self(),mp->thread))
+ {
+ fprintf(stderr,
+ "safe_mutex: Trying to lock mutex at %s, line %d, when the"
+ " mutex was already locked at %s, line %d in thread %s\n",
+ file,line,mp->file, mp->line, my_thread_name());
+ fflush(stderr);
+ abort();
+ }
}
pthread_mutex_unlock(&mp->global);
- error=pthread_mutex_lock(&mp->mutex);
+
+ /*
+ If we are imitating trylock(), we need to take special
+ precautions.
+
+ - We cannot use pthread_mutex_lock() only since another thread can
+ overtake this thread and take the lock before this thread
+ causing pthread_mutex_trylock() to hang. In this case, we should
+ just return EBUSY. Hence, we use pthread_mutex_trylock() to be
+ able to return immediately.
+
+ - We cannot just use trylock() and continue execution below, since
+ this would generate an error and abort execution if the thread
+ was overtaken and trylock() returned EBUSY . In this case, we
+ instead just return EBUSY, since this is the expected behaviour
+ of trylock().
+ */
+ if (try_lock)
+ {
+ error= pthread_mutex_trylock(&mp->mutex);
+ if (error == EBUSY)
+ return error;
+ }
+ else
+ error= pthread_mutex_lock(&mp->mutex);
+
if (error || (error=pthread_mutex_lock(&mp->global)))
{
fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n",