summaryrefslogtreecommitdiff
path: root/mysys/wqueue.c
diff options
context:
space:
mode:
authorunknown <bell@desktop.sanja.is.com.ua>2008-04-21 17:14:58 +0300
committerunknown <bell@desktop.sanja.is.com.ua>2008-04-21 17:14:58 +0300
commit047ce0dcdc83e818ed3ef441b1c5d8b625374b2d (patch)
tree1900ceb08c24732f268e2d4d0f83da987c1db971 /mysys/wqueue.c
parent722a8ebe5b78f82f9cda9872317ff0f8f1dcd63e (diff)
downloadmariadb-git-047ce0dcdc83e818ed3ef441b1c5d8b625374b2d.tar.gz
Problems of partially freed waiting quque fixed (BUG#35040)
mysys/wqueue.c: Problems of partially freed waiting quque fixed. storage/maria/unittest/ma_pagecache_rwconsist.c: Explicitly assigned initial value for increasing readability. Dbug file flush after each line for better debugging. Fixed code style.
Diffstat (limited to 'mysys/wqueue.c')
-rw-r--r--mysys/wqueue.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/mysys/wqueue.c b/mysys/wqueue.c
index df944edeed6..5a90ea302f8 100644
--- a/mysys/wqueue.c
+++ b/mysys/wqueue.c
@@ -140,55 +140,58 @@ void wqueue_release_queue(WQUEUE *wqueue)
@brief Removes all threads waiting for read or first one waiting for write.
@param wqueue pointer to the queue structure
- @apram thread pointer to the thread to be added to the queue
+ @param thread pointer to the thread to be added to the queue
+
+ @note This function is applicable only to single linked lists.
*/
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= &last->next;
struct st_my_thread_var *thread;
- struct st_my_thread_var *new_last= NULL;
+ struct st_my_thread_var *new_list= 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);
- if (thread == last)
+ pthread_cond_signal(&next->suspend);
+#ifndef DBUG_OFF
+ next->prev= NULL; /* force segfault if used */
+#endif
+ if (next == last)
wqueue->last_thread= NULL;
- *prev= thread->next;
- thread->next= NULL;
+ else
+ last->next= next->next;
+ next->next= NULL;
return;
}
do
{
thread= next;
next= thread->next;
+#ifndef DBUG_OFF
+ thread->prev= NULL; /* force segfault if used */
+#endif
if (thread->lock_type == MY_PTHREAD_LOCK_WRITE)
{
/* skip waiting for write lock */
- *prev= thread;
- prev= &thread->next;
- new_last= NULL;
+ if (new_list)
+ {
+ thread->next= new_list->next;
+ new_list= new_list->next= thread;
+ }
+ else
+ new_list= thread->next= thread;
}
else
{
/* release waiting for read lock */
pthread_cond_signal(&thread->suspend);
- new_last= thread->next;
thread->next= NULL;
}
} while (thread != last);
- if (new_last)
- {
- /* last was deleted */
- if (new_last == last)
- wqueue->last_thread= NULL; /* empty list */
- else
- wqueue->last_thread= new_last;
- }
+ wqueue->last_thread= new_list;
}