~ubuntu-branches/ubuntu/trusty/mariadb-5.5/trusty-proposed

« back to all changes in this revision

Viewing changes to storage/maria/ma_servicethread.c

  • Committer: Package Import Robot
  • Author(s): Otto Kekäläinen
  • Date: 2013-12-22 10:27:05 UTC
  • Revision ID: package-import@ubuntu.com-20131222102705-mndw7s12mz0szrcn
Tags: upstream-5.5.32
Import upstream version 5.5.32

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (c) 2009, 2011, Monty Program Ab
 
3
 
 
4
   This program is free software; you can redistribute it and/or modify
 
5
   it under the terms of the GNU General Public License as published by
 
6
   the Free Software Foundation; version 2 of the License.
 
7
 
 
8
   This program is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
   GNU General Public License for more details.
 
12
 
 
13
   You should have received a copy of the GNU General Public License
 
14
   along with this program; if not, write to the Free Software
 
15
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
16
 
 
17
#include "maria_def.h"
 
18
#include "ma_servicethread.h"
 
19
 
 
20
/**
 
21
   Initializes the service thread
 
22
 
 
23
   @param control        control block
 
24
 
 
25
   @return Operation status
 
26
    @retval 0 OK
 
27
    @retval 1 error
 
28
*/
 
29
 
 
30
int ma_service_thread_control_init(MA_SERVICE_THREAD_CONTROL *control)
 
31
{
 
32
  int res= 0;
 
33
  DBUG_ENTER("ma_service_thread_control_init");
 
34
  DBUG_PRINT("init", ("control 0x%lx", (ulong) control));
 
35
  control->inited= TRUE;
 
36
  control->status= THREAD_DEAD; /* not yet born == dead */
 
37
  res= (mysql_mutex_init(key_SERVICE_THREAD_CONTROL_lock,
 
38
                         control->LOCK_control, MY_MUTEX_INIT_SLOW) ||
 
39
        mysql_cond_init(key_SERVICE_THREAD_CONTROL_cond,
 
40
                        control->COND_control, 0));
 
41
  DBUG_PRINT("info", ("init: %s", (res ? "Error" : "OK")));
 
42
  DBUG_RETURN(res);
 
43
}
 
44
 
 
45
 
 
46
/**
 
47
   Kill the service thread
 
48
 
 
49
   @param control        control block
 
50
 
 
51
   @note The service thread should react on condition and status equal
 
52
   THREAD_DYING, by setting status THREAD_DEAD, and issuing message to
 
53
   control thread via condition and exiting. The base way to do so is using
 
54
   my_service_thread_sleep() and my_service_thread_signal_end()
 
55
*/
 
56
 
 
57
void ma_service_thread_control_end(MA_SERVICE_THREAD_CONTROL *control)
 
58
{
 
59
  DBUG_ENTER("ma_service_thread_control_end");
 
60
  DBUG_PRINT("init", ("control 0x%lx", (ulong) control));
 
61
  DBUG_ASSERT(control->inited);
 
62
  mysql_mutex_lock(control->LOCK_control);
 
63
  if (control->status != THREAD_DEAD) /* thread was started OK */
 
64
  {
 
65
    DBUG_PRINT("info",("killing Maria background thread"));
 
66
    control->status= THREAD_DYING; /* kill it */
 
67
    do /* and wait for it to be dead */
 
68
    {
 
69
      /* wake it up if it was in a sleep */
 
70
      mysql_cond_broadcast(control->COND_control);
 
71
      DBUG_PRINT("info",("waiting for Maria background thread to die"));
 
72
      mysql_cond_wait(control->COND_control, control->LOCK_control);
 
73
    }
 
74
    while (control->status != THREAD_DEAD);
 
75
  }
 
76
  mysql_mutex_unlock(control->LOCK_control);
 
77
  mysql_mutex_destroy(control->LOCK_control);
 
78
  mysql_cond_destroy(control->COND_control);
 
79
  control->inited= FALSE;
 
80
  DBUG_VOID_RETURN;
 
81
}
 
82
 
 
83
 
 
84
/**
 
85
   Sleep for given number of nanoseconds with reaction on thread kill
 
86
 
 
87
   @param control        control block
 
88
   @param sleep_time     time of sleeping
 
89
 
 
90
   @return Operation status
 
91
    @retval FALSE Time out
 
92
    @retval TRUE  Thread should be killed
 
93
*/
 
94
 
 
95
my_bool my_service_thread_sleep(MA_SERVICE_THREAD_CONTROL *control,
 
96
                                ulonglong sleep_time)
 
97
{
 
98
  struct timespec abstime;
 
99
  my_bool res= FALSE;
 
100
  DBUG_ENTER("my_service_thread_sleep");
 
101
  DBUG_PRINT("init", ("control 0x%lx", (ulong) control));
 
102
  mysql_mutex_lock(control->LOCK_control);
 
103
  if (control->status == THREAD_DYING)
 
104
  {
 
105
    mysql_mutex_unlock(control->LOCK_control);
 
106
    DBUG_RETURN(TRUE);
 
107
  }
 
108
#if 0 /* good for testing, to do a lot of checkpoints, finds a lot of bugs */
 
109
  mysql_mutex_unlock(&control->LOCK_control);
 
110
  my_sleep(100000); /* a tenth of a second */
 
111
  mysql_mutex_lock(&control->LOCK_control);
 
112
#else
 
113
    /* To have a killable sleep, we use timedwait like our SQL GET_LOCK() */
 
114
  DBUG_PRINT("info", ("sleeping %llu nano seconds", sleep_time));
 
115
  if (sleep_time)
 
116
  {
 
117
    set_timespec_nsec(abstime, sleep_time);
 
118
    mysql_cond_timedwait(control->COND_control,
 
119
                           control->LOCK_control, &abstime);
 
120
  }
 
121
#endif
 
122
  if (control->status == THREAD_DYING)
 
123
    res= TRUE;
 
124
  mysql_mutex_unlock(control->LOCK_control);
 
125
  DBUG_RETURN(res);
 
126
}
 
127
 
 
128
 
 
129
/**
 
130
  inform about thread exiting
 
131
 
 
132
  @param control        control block
 
133
*/
 
134
 
 
135
void my_service_thread_signal_end(MA_SERVICE_THREAD_CONTROL *control)
 
136
{
 
137
  DBUG_ENTER("my_service_thread_signal_end");
 
138
  DBUG_PRINT("init", ("control 0x%lx", (ulong) control));
 
139
  mysql_mutex_lock(control->LOCK_control);
 
140
  control->status = THREAD_DEAD; /* indicate that we are dead */
 
141
  /*
 
142
    wake up ma_service_thread_control_end which may be waiting for
 
143
    our death
 
144
  */
 
145
  mysql_cond_broadcast(control->COND_control);
 
146
  /*
 
147
    broadcast was inside unlock because ma_service_thread_control_end
 
148
    destroys mutex
 
149
  */
 
150
  mysql_mutex_unlock(control->LOCK_control);
 
151
  DBUG_VOID_RETURN;
 
152
}