summaryrefslogtreecommitdiff
path: root/mysys/wqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/wqueue.c')
-rw-r--r--mysys/wqueue.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/mysys/wqueue.c b/mysys/wqueue.c
index 0766e13a4e4..df944edeed6 100644
--- a/mysys/wqueue.c
+++ b/mysys/wqueue.c
@@ -147,15 +147,18 @@ void wqueue_release_one_locktype_from_queue(WQUEUE *wqueue)
{
struct st_my_thread_var *last= wqueue->last_thread;
struct st_my_thread_var *next= last->next;
- struct st_my_thread_var **prev= &wqueue->last_thread;
+ struct st_my_thread_var **prev= &last->next;
struct st_my_thread_var *thread;
+ struct st_my_thread_var *new_last= NULL;
uint first_type= next->lock_type;
if (first_type == MY_PTHREAD_LOCK_WRITE)
{
/* release first waiting for write lock */
thread= next;
pthread_cond_signal(&thread->suspend);
- wqueue->last_thread= next;
+ if (thread == last)
+ wqueue->last_thread= NULL;
+ *prev= thread->next;
thread->next= NULL;
return;
}
@@ -168,17 +171,27 @@ void wqueue_release_one_locktype_from_queue(WQUEUE *wqueue)
/* skip waiting for write lock */
*prev= thread;
prev= &thread->next;
+ new_last= NULL;
}
else
{
/* release waiting for read lock */
pthread_cond_signal(&thread->suspend);
+ new_last= thread->next;
thread->next= NULL;
}
} while (thread != last);
- *prev= NULL;
+ if (new_last)
+ {
+ /* last was deleted */
+ if (new_last == last)
+ wqueue->last_thread= NULL; /* empty list */
+ else
+ wqueue->last_thread= new_last;
+ }
}
+
/*
Add thread and wait