~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
612.2.6 by Monty Taylor
OpenSolaris builds.
16
#include "mysys_priv.h"
17
18
#if !defined(DONT_USE_THR_ALARM)
19
#include <mysys/my_pthread.h>
20
#include <mysys/my_sys.h>
21
#include <mystrings/m_string.h>
22
#include <mysys/queues.h>
23
#include <mysys/thr_alarm.h>
24
595 by Brian Aker
Fix, partial, for Sun Studio.
25
#include <stdio.h>
612.2.6 by Monty Taylor
OpenSolaris builds.
26
#include <signal.h>
1 by brian
clean slate
27
#include <errno.h>
28
29
#ifdef HAVE_SYS_SELECT_H
30
#include <sys/select.h>				/* AIX needs this for fd_set */
31
#endif
32
481.1.15 by Monty Taylor
Removed time.h and sys/time.h from global.h.
33
#if TIME_WITH_SYS_TIME
34
# include <sys/time.h>
35
# include <time.h>
36
#else
37
# if HAVE_SYS_TIME_H
38
#  include <sys/time.h>
39
# else
40
#  include <time.h>
41
# endif
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
42
#endif
481.1.15 by Monty Taylor
Removed time.h and sys/time.h from global.h.
43
44
1 by brian
clean slate
45
#ifndef ETIME
46
#define ETIME ETIMEDOUT
47
#endif
48
482 by Brian Aker
Remove uint.
49
uint32_t thr_client_alarm;
1 by brian
clean slate
50
static int alarm_aborted=1;			/* No alarm thread */
146 by Brian Aker
my_bool cleanup.
51
bool thr_alarm_inited= 0;
52
volatile bool alarm_thread_running= 0;
1 by brian
clean slate
53
time_t next_alarm_expire_time= ~ (time_t) 0;
779.2.11 by Monty Taylor
General build cleanup - removed cruft, removed depreated checks.
54
static void process_alarm_part2(int sig);
1 by brian
clean slate
55
56
static pthread_mutex_t LOCK_alarm;
57
static pthread_cond_t COND_alarm;
58
static sigset_t full_signal_set;
59
static QUEUE alarm_queue;
482 by Brian Aker
Remove uint.
60
static uint32_t max_used_alarms=0;
1 by brian
clean slate
61
pthread_t alarm_thread;
62
63
#ifdef USE_ALARM_THREAD
64
static void *alarm_handler(void *arg);
65
#define reschedule_alarms() pthread_cond_signal(&COND_alarm)
66
#else
67
#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM)
68
#endif
69
632.1.11 by Monty Taylor
Fixed Sun Studio warnings in mysys.
70
int compare_uint32_t(void *, unsigned char *a_ptr,unsigned char* b_ptr)
1 by brian
clean slate
71
{
298 by Brian Aker
ulong conversion.
72
  uint32_t a=*((uint32_t*) a_ptr),b= *((uint32_t*) b_ptr);
1 by brian
clean slate
73
  return (a < b) ? -1  : (a == b) ? 0 : 1;
74
}
75
482 by Brian Aker
Remove uint.
76
void init_thr_alarm(uint32_t max_alarms)
1 by brian
clean slate
77
{
78
  sigset_t s;
79
  alarm_aborted=0;
80
  next_alarm_expire_time= ~ (time_t) 0;
81
  init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0,
461 by Monty Taylor
Removed NullS. bu-bye.
82
	     compare_uint32_t,NULL);
1 by brian
clean slate
83
  sigfillset(&full_signal_set);			/* Neaded to block signals */
84
  pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
85
  pthread_cond_init(&COND_alarm,NULL);
86
  if (thd_lib_detected == THD_LIB_LT)
87
    thr_client_alarm= SIGALRM;
88
  else
89
    thr_client_alarm= SIGUSR1;
90
#ifndef USE_ALARM_THREAD
91
  if (thd_lib_detected != THD_LIB_LT)
92
#endif
93
  {
94
    my_sigset(thr_client_alarm, thread_alarm);
95
  }
96
  sigemptyset(&s);
97
  sigaddset(&s, THR_SERVER_ALARM);
98
  alarm_thread=pthread_self();
99
#if defined(USE_ALARM_THREAD)
100
  {
101
    pthread_attr_t thr_attr;
102
    pthread_attr_init(&thr_attr);
103
    pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
104
    pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
105
    pthread_attr_setstacksize(&thr_attr,8196);
106
107
    my_pthread_attr_setprio(&thr_attr,100);	/* Very high priority */
398.1.10 by Monty Taylor
Actually removed VOID() this time.
108
    pthread_create(&alarm_thread,&thr_attr,alarm_handler,NULL);
109
    pthread_attr_destroy(&thr_attr);
1 by brian
clean slate
110
  }
111
#elif defined(USE_ONE_SIGNAL_HAND)
112
  pthread_sigmask(SIG_BLOCK, &s, NULL);		/* used with sigwait() */
113
  if (thd_lib_detected == THD_LIB_LT)
114
  {
115
    my_sigset(thr_client_alarm, process_alarm);        /* Linuxthreads */
116
    pthread_sigmask(SIG_UNBLOCK, &s, NULL);
117
  }
118
#else
119
  my_sigset(THR_SERVER_ALARM, process_alarm);
120
  pthread_sigmask(SIG_UNBLOCK, &s, NULL);
121
#endif /* USE_ALARM_THREAD */
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
122
  return;
1 by brian
clean slate
123
}
124
125
482 by Brian Aker
Remove uint.
126
void resize_thr_alarm(uint32_t max_alarms)
1 by brian
clean slate
127
{
128
  pthread_mutex_lock(&LOCK_alarm);
129
  /*
130
    It's ok not to shrink the queue as there may be more pending alarms than
131
    than max_alarms
132
  */
133
  if (alarm_queue.elements < max_alarms)
134
    resize_queue(&alarm_queue,max_alarms+1);
135
  pthread_mutex_unlock(&LOCK_alarm);
136
}
137
138
139
/*
140
  Request alarm after sec seconds.
141
142
  SYNOPSIS
143
    thr_alarm()
144
    alrm		Pointer to alarm detection
145
    alarm_data		Structure to store in alarm queue
146
147
  NOTES
148
    This function can't be called from the alarm-handling thread.
149
150
  RETURN VALUES
151
    0 ok
152
    1 If no more alarms are allowed (aborted by process)
153
154
    Stores in first argument a pointer to a non-zero int which is set to 0
155
    when the alarm has been given
156
*/
157
482 by Brian Aker
Remove uint.
158
bool thr_alarm(thr_alarm_t *alrm, uint32_t sec, ALARM *alarm_data)
1 by brian
clean slate
159
{
160
  time_t now;
161
#ifndef USE_ONE_SIGNAL_HAND
162
  sigset_t old_mask;
163
#endif
146 by Brian Aker
my_bool cleanup.
164
  bool reschedule;
1 by brian
clean slate
165
  struct st_my_thread_var *current_my_thread_var= my_thread_var;
166
685.3.4 by Toru Maesaka
Fixed the issues pointed out by Jay's code review
167
  now= time(NULL);
168
  if(now == (time_t)-1)
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
169
  {
170
    fprintf(stderr, "%s: Warning: time() call failed\n", my_progname);
171
    return 1;
172
  }
173
1 by brian
clean slate
174
#ifndef USE_ONE_SIGNAL_HAND
175
  pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
176
#endif
177
  pthread_mutex_lock(&LOCK_alarm);        /* Lock from threads & alarms */
178
  if (alarm_aborted > 0)
179
  {					/* No signal thread */
180
    *alrm= 0;					/* No alarm */
181
    pthread_mutex_unlock(&LOCK_alarm);
182
#ifndef USE_ONE_SIGNAL_HAND
183
    pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
184
#endif
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
185
    return(1);
1 by brian
clean slate
186
  }
187
  if (alarm_aborted < 0)
188
    sec= 1;					/* Abort mode */
189
190
  if (alarm_queue.elements >= max_used_alarms)
191
  {
192
    if (alarm_queue.elements == alarm_queue.max_elements)
193
    {
194
      fprintf(stderr,"Warning: thr_alarm queue is full\n");
195
      *alrm= 0;					/* No alarm */
196
      pthread_mutex_unlock(&LOCK_alarm);
197
#ifndef USE_ONE_SIGNAL_HAND
198
      pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
199
#endif
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
200
      return(1);
1 by brian
clean slate
201
    }
202
    max_used_alarms=alarm_queue.elements+1;
203
  }
298 by Brian Aker
ulong conversion.
204
  reschedule= (uint32_t) next_alarm_expire_time > (uint32_t) now + sec;
1 by brian
clean slate
205
  if (!alarm_data)
206
  {
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
207
    if (!(alarm_data=(ALARM*) malloc(sizeof(ALARM))))
1 by brian
clean slate
208
    {
209
      *alrm= 0;					/* No alarm */
210
      pthread_mutex_unlock(&LOCK_alarm);
211
#ifndef USE_ONE_SIGNAL_HAND
212
      pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
213
#endif
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
214
      return(1);
1 by brian
clean slate
215
    }
216
    alarm_data->malloced=1;
217
  }
218
  else
219
    alarm_data->malloced=0;
220
  alarm_data->expire_time=now+sec;
221
  alarm_data->alarmed=0;
222
  alarm_data->thread=    current_my_thread_var->pthread_self;
223
  alarm_data->thread_id= current_my_thread_var->id;
481 by Brian Aker
Remove all of uchar.
224
  queue_insert(&alarm_queue,(unsigned char*) alarm_data);
1 by brian
clean slate
225
226
  /* Reschedule alarm if the current one has more than sec left */
227
  if (reschedule)
228
  {
229
    if (pthread_equal(pthread_self(),alarm_thread))
230
    {
231
      alarm(sec);				/* purecov: inspected */
232
      next_alarm_expire_time= now + sec;
233
    }
234
    else
235
      reschedule_alarms();			/* Reschedule alarms */
236
  }
237
  pthread_mutex_unlock(&LOCK_alarm);
238
#ifndef USE_ONE_SIGNAL_HAND
239
  pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
240
#endif
241
  (*alrm)= &alarm_data->alarmed;
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
242
  return(0);
1 by brian
clean slate
243
}
244
245
246
/*
247
  Remove alarm from list of alarms
248
*/
249
250
void thr_end_alarm(thr_alarm_t *alarmed)
251
{
252
  ALARM *alarm_data;
253
#ifndef USE_ONE_SIGNAL_HAND
254
  sigset_t old_mask;
255
#endif
482 by Brian Aker
Remove uint.
256
  uint32_t i, found=0;
1 by brian
clean slate
257
258
#ifndef USE_ONE_SIGNAL_HAND
259
  pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
260
#endif
261
  pthread_mutex_lock(&LOCK_alarm);
262
481 by Brian Aker
Remove all of uchar.
263
  alarm_data= (ALARM*) ((unsigned char*) *alarmed - offsetof(ALARM,alarmed));
1 by brian
clean slate
264
  for (i=0 ; i < alarm_queue.elements ; i++)
265
  {
266
    if ((ALARM*) queue_element(&alarm_queue,i) == alarm_data)
267
    {
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
268
      queue_remove(&alarm_queue,i);
1 by brian
clean slate
269
      if (alarm_data->malloced)
481 by Brian Aker
Remove all of uchar.
270
	free((unsigned char*) alarm_data);
1 by brian
clean slate
271
      found++;
272
      break;
273
    }
274
  }
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
275
  assert(!*alarmed || found == 1);
1 by brian
clean slate
276
  if (!found)
277
  {
278
    if (*alarmed)
279
      fprintf(stderr,"Warning: Didn't find alarm 0x%lx in queue of %d alarms\n",
280
	      (long) *alarmed, alarm_queue.elements);
281
  }
282
  pthread_mutex_unlock(&LOCK_alarm);
283
#ifndef USE_ONE_SIGNAL_HAND
284
  pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
285
#endif
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
286
  return;
1 by brian
clean slate
287
}
288
289
/*
290
  Come here when some alarm in queue is due.
291
  Mark all alarms with are finnished in list.
292
  Shedule alarms to be sent again after 1-10 sec (many alarms at once)
293
  If alarm_aborted is set then all alarms are given and resent
294
  every second.
295
*/
296
779.2.11 by Monty Taylor
General build cleanup - removed cruft, removed depreated checks.
297
void process_alarm(int sig __attribute__((unused)))
1 by brian
clean slate
298
{
299
  sigset_t old_mask;
300
301
  if (thd_lib_detected == THD_LIB_LT &&
302
      !pthread_equal(pthread_self(),alarm_thread))
303
  {
447 by Monty Taylor
Removed DONT_REMEMBER_SIGNAL define.
304
#ifndef HAVE_BSD_SIGNALS
1 by brian
clean slate
305
    my_sigset(thr_client_alarm, process_alarm);	/* int. thread system calls */
306
#endif
307
    return;
308
  }
309
310
#ifndef USE_ALARM_THREAD
311
  pthread_sigmask(SIG_SETMASK,&full_signal_set,&old_mask);
312
  pthread_mutex_lock(&LOCK_alarm);
313
#endif
314
  process_alarm_part2(sig);
315
#ifndef USE_ALARM_THREAD
447 by Monty Taylor
Removed DONT_REMEMBER_SIGNAL define.
316
#if !defined(HAVE_BSD_SIGNALS) && !defined(USE_ONE_SIGNAL_HAND)
1 by brian
clean slate
317
  my_sigset(THR_SERVER_ALARM,process_alarm);
318
#endif
319
  pthread_mutex_unlock(&LOCK_alarm);
320
  pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
321
#endif
322
  return;
323
}
324
325
779.2.11 by Monty Taylor
General build cleanup - removed cruft, removed depreated checks.
326
static void process_alarm_part2(int)
1 by brian
clean slate
327
{
328
  ALARM *alarm_data;
329
330
  if (alarm_queue.elements)
331
  {
332
    if (alarm_aborted)
333
    {
482 by Brian Aker
Remove uint.
334
      uint32_t i;
1 by brian
clean slate
335
      for (i=0 ; i < alarm_queue.elements ;)
336
      {
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
337
        alarm_data=(ALARM*) queue_element(&alarm_queue,i);
338
        alarm_data->alarmed=1;			/* Info to thread */
339
        if (pthread_equal(alarm_data->thread,alarm_thread) ||
340
            pthread_kill(alarm_data->thread, thr_client_alarm))
341
        {
342
          queue_remove(&alarm_queue,i);		/* No thread. Remove alarm */
343
        }
344
        else
345
          i++;					/* Signal next thread */
1 by brian
clean slate
346
      }
347
#ifndef USE_ALARM_THREAD
348
      if (alarm_queue.elements)
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
349
        alarm(1);				/* Signal soon again */
1 by brian
clean slate
350
#endif
351
    }
352
    else
353
    {
685.3.4 by Toru Maesaka
Fixed the issues pointed out by Jay's code review
354
      time_t now= time(NULL);
713.1.11 by Monty Taylor
Fixed a time_t thing.
355
      time_t next= now+10-(now%10);
356
      while ((alarm_data= (ALARM*) queue_top(&alarm_queue))->expire_time <= now)
1 by brian
clean slate
357
      {
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
358
        alarm_data->alarmed=1;			/* Info to thread */
359
        if (pthread_equal(alarm_data->thread,alarm_thread) ||
360
            pthread_kill(alarm_data->thread, thr_client_alarm))
361
        {
362
          queue_remove(&alarm_queue,0);		/* No thread. Remove alarm */
363
          if (!alarm_queue.elements)
364
            break;
365
        }
366
        else
367
        {
368
          alarm_data->expire_time=next;
369
          queue_replaced(&alarm_queue);
370
        }
1 by brian
clean slate
371
      }
372
#ifndef USE_ALARM_THREAD
373
      if (alarm_queue.elements)
374
      {
713.1.11 by Monty Taylor
Fixed a time_t thing.
375
        alarm((uint32_t) (alarm_data->expire_time-now));
1 by brian
clean slate
376
        next_alarm_expire_time= alarm_data->expire_time;
377
      }
378
#endif
379
    }
380
  }
381
  else
382
  {
383
    /*
384
      Ensure that next time we call thr_alarm(), we will schedule a new alarm
385
    */
386
    next_alarm_expire_time= ~(time_t) 0;
387
  }
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
388
  return;
1 by brian
clean slate
389
}
390
391
392
/*
393
  Schedule all alarms now and optionally free all structures
394
395
  SYNPOSIS
396
    end_thr_alarm()
397
      free_structures		Set to 1 if we should free memory used for
398
				the alarm queue.
399
				When we call this we should KNOW that there
400
				is no active alarms
401
  IMPLEMENTATION
402
    Set alarm_abort to -1 which will change the behavior of alarms as follows:
403
    - All old alarms will be rescheduled at once
404
    - All new alarms will be rescheduled to one second
405
*/
406
146 by Brian Aker
my_bool cleanup.
407
void end_thr_alarm(bool free_structures)
1 by brian
clean slate
408
{
409
  if (alarm_aborted != 1)			/* If memory not freed */
410
  {
411
    pthread_mutex_lock(&LOCK_alarm);
412
    alarm_aborted= -1;				/* mark aborted */
413
    if (alarm_queue.elements || (alarm_thread_running && free_structures))
414
    {
415
      if (pthread_equal(pthread_self(),alarm_thread))
416
	alarm(1);				/* Shut down everything soon */
417
      else
418
	reschedule_alarms();
419
    }
420
    if (free_structures)
421
    {
422
      struct timespec abstime;
423
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
424
      assert(!alarm_queue.elements);
1 by brian
clean slate
425
426
      /* Wait until alarm thread dies */
427
      set_timespec(abstime, 10);		/* Wait up to 10 seconds */
428
      while (alarm_thread_running)
429
      {
430
	int error= pthread_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime);
431
	if (error == ETIME || error == ETIMEDOUT)
432
	  break;				/* Don't wait forever */
433
      }
434
      delete_queue(&alarm_queue);
435
      alarm_aborted= 1;
436
      pthread_mutex_unlock(&LOCK_alarm);
437
      if (!alarm_thread_running)              /* Safety */
438
      {
439
        pthread_mutex_destroy(&LOCK_alarm);
440
        pthread_cond_destroy(&COND_alarm);
441
      }
442
    }
443
    else
444
      pthread_mutex_unlock(&LOCK_alarm);
445
  }
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
446
  return;
1 by brian
clean slate
447
}
448
449
450
/*
451
  Remove another thread from the alarm
452
*/
453
454
void thr_alarm_kill(my_thread_id thread_id)
455
{
482 by Brian Aker
Remove uint.
456
  uint32_t i;
1 by brian
clean slate
457
  if (alarm_aborted)
458
    return;
459
  pthread_mutex_lock(&LOCK_alarm);
460
  for (i=0 ; i < alarm_queue.elements ; i++)
461
  {
462
    if (((ALARM*) queue_element(&alarm_queue,i))->thread_id == thread_id)
463
    {
464
      ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
465
      tmp->expire_time=0;
481 by Brian Aker
Remove all of uchar.
466
      queue_insert(&alarm_queue,(unsigned char*) tmp);
1 by brian
clean slate
467
      reschedule_alarms();
468
      break;
469
    }
470
  }
471
  pthread_mutex_unlock(&LOCK_alarm);
472
}
473
474
475
void thr_alarm_info(ALARM_INFO *info)
476
{
477
  pthread_mutex_lock(&LOCK_alarm);
478
  info->next_alarm_time= 0;
479
  info->max_used_alarms= max_used_alarms;
480
  if ((info->active_alarms=  alarm_queue.elements))
481
  {
685.3.4 by Toru Maesaka
Fixed the issues pointed out by Jay's code review
482
    time_t now= time(NULL);
1 by brian
clean slate
483
    long time_diff;
484
    ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
485
    time_diff= (long) (alarm_data->expire_time - now);
298 by Brian Aker
ulong conversion.
486
    info->next_alarm_time= (uint32_t) (time_diff < 0 ? 0 : time_diff);
1 by brian
clean slate
487
  }
488
  pthread_mutex_unlock(&LOCK_alarm);
489
}
490
491
/*
492
  This is here for thread to get interruptet from read/write/fcntl
493
  ARGSUSED
494
*/
495
496
779.2.11 by Monty Taylor
General build cleanup - removed cruft, removed depreated checks.
497
void thread_alarm(int sig)
1 by brian
clean slate
498
{
447 by Monty Taylor
Removed DONT_REMEMBER_SIGNAL define.
499
#ifndef HAVE_BSD_SIGNALS
1 by brian
clean slate
500
  my_sigset(sig,thread_alarm);		/* int. thread system calls */
501
#endif
502
}
503
504
505
#ifdef HAVE_TIMESPEC_TS_SEC
506
#define tv_sec ts_sec
507
#define tv_nsec ts_nsec
508
#endif
509
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
510
/* 
511
   Set up a alarm thread which uses 'sleep' to sleep between alarms
512
513
  RETURNS
514
    NULL on time() failure
515
*/
1 by brian
clean slate
516
517
#ifdef USE_ALARM_THREAD
518
static void *alarm_handler(void *arg __attribute__((unused)))
519
{
520
  int error;
521
  struct timespec abstime;
522
  my_thread_init();
523
  alarm_thread_running= 1;
524
  pthread_mutex_lock(&LOCK_alarm);
525
  for (;;)
526
  {
527
    if (alarm_queue.elements)
528
    {
685.3.4 by Toru Maesaka
Fixed the issues pointed out by Jay's code review
529
      uint32_t sleep_time;
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
530
685.3.4 by Toru Maesaka
Fixed the issues pointed out by Jay's code review
531
      time_t now= time(NULL);
532
      if (now == (time_t)-1)
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
533
      {
534
        pthread_mutex_unlock(&LOCK_alarm);
535
        return NULL;
536
      }
537
1 by brian
clean slate
538
      if (alarm_aborted)
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
539
        sleep_time=now+1;
1 by brian
clean slate
540
      else
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
541
        sleep_time= ((ALARM*) queue_top(&alarm_queue))->expire_time;
1 by brian
clean slate
542
      if (sleep_time > now)
543
      {
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
544
        abstime.tv_sec=sleep_time;
545
        abstime.tv_nsec=0;
1 by brian
clean slate
546
        next_alarm_expire_time= sleep_time;
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
547
        if ((error=pthread_cond_timedwait(&COND_alarm,&LOCK_alarm,&abstime)) &&
548
            error != ETIME && error != ETIMEDOUT)
549
        {
657 by Brian Aker
Random cleanup, removed dead mysys call for hw address creation.
550
          assert(1);
685.3.2 by Toru Maesaka
Removed my_time() and added error checking
551
        }
1 by brian
clean slate
552
      }
553
    }
554
    else if (alarm_aborted == -1)
555
      break;
556
    else
557
    {
558
      next_alarm_expire_time= ~ (time_t) 0;
657 by Brian Aker
Random cleanup, removed dead mysys call for hw address creation.
559
      error= pthread_cond_wait(&COND_alarm,&LOCK_alarm);
560
561
      assert(error == 0);
1 by brian
clean slate
562
    }
563
    process_alarm(0);
564
  }
212.6.14 by Mats Kindahl
Removing redundant use of casts in mysys for memcmp(), memcpy(), memset(), and memmove().
565
  memset(&alarm_thread, 0, sizeof(alarm_thread)); /* For easy debugging */
1 by brian
clean slate
566
  alarm_thread_running= 0;
567
  pthread_cond_signal(&COND_alarm);
568
  pthread_mutex_unlock(&LOCK_alarm);
569
  pthread_exit(0);
570
  return 0;					/* Impossible */
571
}
572
#endif /* USE_ALARM_THREAD */
573
574
#endif /* THREAD */