/*
Copyright ( c ) 2007 , 2008 , Sun Microsystems , Inc ,
Copyright ( c ) 2011 , 2012 , Monty Program Ab
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; version 2 of the License .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#include <my_global.h>
#include <wqueue.h>
#define STRUCT_PTR(TYPE, MEMBER, a) \
(TYPE *) ((char *) (a) - offsetof(TYPE, MEMBER))
/*
Link a thread into double - linked queue of waiting threads .
SYNOPSIS
wqueue_link_into_queue ( )
wqueue pointer to the queue structure
thread pointer to the thread to be added to the queue
RETURN VALUE
none
NOTES .
Queue is represented by a circular list of the thread structures
The list is double - linked of the type ( * * prev , * next ) , accessed by
a pointer to the last element .
*/
void wqueue_link_into_queue(WQUEUE *wqueue, struct st_my_thread_var *thread)
{
struct st_my_thread_var *last;
if (!(last= wqueue->last_thread))
{
/* Queue is empty */
thread->next= thread;
thread->prev= &thread->next;
}
else
{
thread->prev= last->next->prev;
last->next->prev= &thread->next;
thread->next= last->next;
last->next= thread;
}
wqueue->last_thread= thread;
}
/*
Add a thread to single - linked queue of waiting threads
SYNOPSIS
wqueue_add_to_queue ( )
wqueue pointer to the queue structure
thread pointer to the thread to be added to the queue
RETURN VALUE
none
NOTES .
Queue is represented by a circular list of the thread structures
The list is single - linked of the type ( * next ) , accessed by a pointer
to the last element .
*/
void wqueue_add_to_queue(WQUEUE *wqueue, struct st_my_thread_var *thread)
{
struct st_my_thread_var *last;
if (!(last= wqueue->last_thread))
thread->next= thread;
else
{
thread->next= last->next;
last->next= thread;
}
#ifndef DBUG_OFF
thread->prev= NULL; /* force segfault if used */
#endif
wqueue->last_thread= thread;
}
/*
Unlink a thread from double - linked queue of waiting threads
SYNOPSIS
wqueue_unlink_from_queue ( )
wqueue pointer to the queue structure
thread pointer to the thread to be removed from the queue
RETURN VALUE
none
NOTES .
See NOTES for link_into_queue
*/
void wqueue_unlink_from_queue(WQUEUE *wqueue, struct st_my_thread_var *thread)
{
if (thread->next == thread)
/* The queue contains only one member */
wqueue->last_thread= NULL;
else
{
thread->next->prev= thread->prev;
*thread->prev= thread->next;
if (wqueue->last_thread == thread)
wqueue->last_thread= STRUCT_PTR(struct st_my_thread_var, next,
thread->prev);
}
thread->next= NULL;
}
/*
Remove all threads from queue signaling them to proceed
SYNOPSIS
wqueue_realease_queue ( )
wqueue pointer to the queue structure
thread pointer to the thread to be added to the queue
RETURN VALUE
none
NOTES .
See notes for add_to_queue
When removed from the queue each thread is signaled via condition
variable thread - > suspend .
*/
void wqueue_release_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 *thread;
do
{
thread= next;
mysql_cond_signal(&thread->suspend);
next= thread->next;
thread->next= NULL;
}
while (thread != last);
wqueue->last_thread= NULL;
}
/**
@ brief Removes all threads waiting for read or first one waiting for write .
@ param wqueue pointer to the queue structure
@ 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 *thread;
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 */
mysql_cond_signal(&next->suspend);
if (next == last)
wqueue->last_thread= NULL;
else
last->next= next->next;
next->next= NULL;
return ;
}
do
{
thread= next;
next= thread->next;
if (thread->lock_type == MY_PTHREAD_LOCK_WRITE)
{
/* skip waiting for write lock */
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 */
mysql_cond_signal(&thread->suspend);
thread->next= NULL;
}
} while (thread != last);
wqueue->last_thread= new_list;
}
/*
Add thread and wait
SYNOPSIS
wqueue_add_and_wait ( )
wqueue queue to add to
thread thread which is waiting
lock mutex need for the operation
*/
void wqueue_add_and_wait(WQUEUE *wqueue,
struct st_my_thread_var *thread,
mysql_mutex_t *lock)
{
DBUG_ENTER("wqueue_add_and_wait" );
DBUG_PRINT("enter" ,
("thread: %p cond: %p mutex: %p" ,
thread, &thread->suspend, lock));
wqueue_add_to_queue(wqueue, thread);
do
{
DBUG_PRINT("info" , ("wait... cond: %p mutex: %p" ,
&thread->suspend, lock));
mysql_cond_wait(&thread->suspend, lock);
DBUG_PRINT("info" , ("wait done cond: %p mutex: %p next: %p" ,
&thread->suspend, lock,
thread->next));
}
while (thread->next);
DBUG_VOID_RETURN;
}
Messung V0.5 in Prozent C=95 H=72 G=83
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-08)
¤
*© Formatika GbR, Deutschland