~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/thr_alarm.c

  • Committer: Jay Pipes
  • Date: 2008-07-21 17:52:33 UTC
  • mto: (201.2.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: jay@mysql.com-20080721175233-mtyz298j8xl3v63y
cleanup of FAQ file

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include "mysys_priv.h"
 
16
#include <my_global.h>
17
17
 
18
18
#if !defined(DONT_USE_THR_ALARM)
19
19
#include <errno.h>
20
20
#include <my_pthread.h>
21
21
#include <signal.h>
22
22
#include <my_sys.h>
23
 
#include <mystrings/m_string.h>
 
23
#include <m_string.h>
24
24
#include <queues.h>
25
25
#include "thr_alarm.h"
26
26
 
28
28
#include <sys/select.h>                         /* AIX needs this for fd_set */
29
29
#endif
30
30
 
31
 
#if TIME_WITH_SYS_TIME
32
 
# include <sys/time.h>
33
 
# include <time.h>
34
 
#else
35
 
# if HAVE_SYS_TIME_H
36
 
#  include <sys/time.h>
37
 
# else
38
 
#  include <time.h>
39
 
# endif
40
 
#endif  
41
 
 
42
 
 
43
31
#ifndef ETIME
44
32
#define ETIME ETIMEDOUT
45
33
#endif
46
34
 
47
 
uint32_t thr_client_alarm;
 
35
uint thr_client_alarm;
48
36
static int alarm_aborted=1;                     /* No alarm thread */
49
37
bool thr_alarm_inited= 0;
50
38
volatile bool alarm_thread_running= 0;
51
39
time_t next_alarm_expire_time= ~ (time_t) 0;
52
 
static RETSIGTYPE process_alarm_part2(int sig);
 
40
static sig_handler process_alarm_part2(int sig);
53
41
 
54
42
static pthread_mutex_t LOCK_alarm;
55
43
static pthread_cond_t COND_alarm;
56
44
static sigset_t full_signal_set;
57
45
static QUEUE alarm_queue;
58
 
static uint32_t max_used_alarms=0;
 
46
static uint max_used_alarms=0;
59
47
pthread_t alarm_thread;
60
48
 
61
49
#ifdef USE_ALARM_THREAD
65
53
#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM)
66
54
#endif
67
55
 
68
 
static RETSIGTYPE thread_alarm(int sig __attribute__((unused)));
 
56
static sig_handler thread_alarm(int sig __attribute__((unused)));
69
57
 
70
 
static int compare_uint32_t(void *not_used __attribute__((unused)),
71
 
                         unsigned char *a_ptr,unsigned char* b_ptr)
 
58
static int compare_ulong(void *not_used __attribute__((unused)),
 
59
                         uchar *a_ptr,uchar* b_ptr)
72
60
{
73
 
  uint32_t a=*((uint32_t*) a_ptr),b= *((uint32_t*) b_ptr);
 
61
  ulong a=*((ulong*) a_ptr),b= *((ulong*) b_ptr);
74
62
  return (a < b) ? -1  : (a == b) ? 0 : 1;
75
63
}
76
64
 
77
 
void init_thr_alarm(uint32_t max_alarms)
 
65
void init_thr_alarm(uint max_alarms)
78
66
{
79
67
  sigset_t s;
80
68
  alarm_aborted=0;
81
69
  next_alarm_expire_time= ~ (time_t) 0;
82
70
  init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0,
83
 
             compare_uint32_t,NULL);
 
71
             compare_ulong,NullS);
84
72
  sigfillset(&full_signal_set);                 /* Neaded to block signals */
85
73
  pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
86
74
  pthread_cond_init(&COND_alarm,NULL);
106
94
    pthread_attr_setstacksize(&thr_attr,8196);
107
95
 
108
96
    my_pthread_attr_setprio(&thr_attr,100);     /* Very high priority */
109
 
    pthread_create(&alarm_thread,&thr_attr,alarm_handler,NULL);
110
 
    pthread_attr_destroy(&thr_attr);
 
97
    VOID(pthread_create(&alarm_thread,&thr_attr,alarm_handler,NULL));
 
98
    VOID(pthread_attr_destroy(&thr_attr));
111
99
  }
112
100
#elif defined(USE_ONE_SIGNAL_HAND)
113
101
  pthread_sigmask(SIG_BLOCK, &s, NULL);         /* used with sigwait() */
124
112
}
125
113
 
126
114
 
127
 
void resize_thr_alarm(uint32_t max_alarms)
 
115
void resize_thr_alarm(uint max_alarms)
128
116
{
129
117
  pthread_mutex_lock(&LOCK_alarm);
130
118
  /*
156
144
    when the alarm has been given
157
145
*/
158
146
 
159
 
bool thr_alarm(thr_alarm_t *alrm, uint32_t sec, ALARM *alarm_data)
 
147
bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
160
148
{
161
149
  time_t now;
162
150
#ifndef USE_ONE_SIGNAL_HAND
196
184
    }
197
185
    max_used_alarms=alarm_queue.elements+1;
198
186
  }
199
 
  reschedule= (uint32_t) next_alarm_expire_time > (uint32_t) now + sec;
 
187
  reschedule= (ulong) next_alarm_expire_time > (ulong) now + sec;
200
188
  if (!alarm_data)
201
189
  {
202
190
    if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
216
204
  alarm_data->alarmed=0;
217
205
  alarm_data->thread=    current_my_thread_var->pthread_self;
218
206
  alarm_data->thread_id= current_my_thread_var->id;
219
 
  queue_insert(&alarm_queue,(unsigned char*) alarm_data);
 
207
  queue_insert(&alarm_queue,(uchar*) alarm_data);
220
208
 
221
209
  /* Reschedule alarm if the current one has more than sec left */
222
210
  if (reschedule)
248
236
#ifndef USE_ONE_SIGNAL_HAND
249
237
  sigset_t old_mask;
250
238
#endif
251
 
  uint32_t i, found=0;
 
239
  uint i, found=0;
252
240
 
253
241
#ifndef USE_ONE_SIGNAL_HAND
254
242
  pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
255
243
#endif
256
244
  pthread_mutex_lock(&LOCK_alarm);
257
245
 
258
 
  alarm_data= (ALARM*) ((unsigned char*) *alarmed - offsetof(ALARM,alarmed));
 
246
  alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed));
259
247
  for (i=0 ; i < alarm_queue.elements ; i++)
260
248
  {
261
249
    if ((ALARM*) queue_element(&alarm_queue,i) == alarm_data)
262
250
    {
263
251
      queue_remove(&alarm_queue,i),MYF(0);
264
252
      if (alarm_data->malloced)
265
 
        free((unsigned char*) alarm_data);
 
253
        my_free((uchar*) alarm_data,MYF(0));
266
254
      found++;
267
255
      break;
268
256
    }
289
277
  every second.
290
278
*/
291
279
 
292
 
RETSIGTYPE process_alarm(int sig __attribute__((unused)))
 
280
sig_handler process_alarm(int sig __attribute__((unused)))
293
281
{
294
282
  sigset_t old_mask;
295
283
 
299
287
#if defined(MAIN) && !defined(__bsdi__)
300
288
    printf("thread_alarm in process_alarm\n"); fflush(stdout);
301
289
#endif
302
 
#ifndef HAVE_BSD_SIGNALS
 
290
#ifdef DONT_REMEMBER_SIGNAL
303
291
    my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */
304
292
#endif
305
293
    return;
311
299
#endif
312
300
  process_alarm_part2(sig);
313
301
#ifndef USE_ALARM_THREAD
314
 
#if !defined(HAVE_BSD_SIGNALS) && !defined(USE_ONE_SIGNAL_HAND)
 
302
#if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND)
315
303
  my_sigset(THR_SERVER_ALARM,process_alarm);
316
304
#endif
317
305
  pthread_mutex_unlock(&LOCK_alarm);
321
309
}
322
310
 
323
311
 
324
 
static RETSIGTYPE process_alarm_part2(int sig __attribute__((unused)))
 
312
static sig_handler process_alarm_part2(int sig __attribute__((unused)))
325
313
{
326
314
  ALARM *alarm_data;
327
315
 
332
320
  {
333
321
    if (alarm_aborted)
334
322
    {
335
 
      uint32_t i;
 
323
      uint i;
336
324
      for (i=0 ; i < alarm_queue.elements ;)
337
325
      {
338
326
        alarm_data=(ALARM*) queue_element(&alarm_queue,i);
355
343
    }
356
344
    else
357
345
    {
358
 
      uint32_t now=(uint32_t) my_time(0);
359
 
      uint32_t next=now+10-(now%10);
 
346
      ulong now=(ulong) my_time(0);
 
347
      ulong next=now+10-(now%10);
360
348
      while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
361
349
      {
362
350
        alarm_data->alarmed=1;                  /* Info to thread */
460
448
 
461
449
void thr_alarm_kill(my_thread_id thread_id)
462
450
{
463
 
  uint32_t i;
 
451
  uint i;
464
452
  if (alarm_aborted)
465
453
    return;
466
454
  pthread_mutex_lock(&LOCK_alarm);
470
458
    {
471
459
      ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
472
460
      tmp->expire_time=0;
473
 
      queue_insert(&alarm_queue,(unsigned char*) tmp);
 
461
      queue_insert(&alarm_queue,(uchar*) tmp);
474
462
      reschedule_alarms();
475
463
      break;
476
464
    }
486
474
  info->max_used_alarms= max_used_alarms;
487
475
  if ((info->active_alarms=  alarm_queue.elements))
488
476
  {
489
 
    uint32_t now=(uint32_t) my_time(0);
 
477
    ulong now=(ulong) my_time(0);
490
478
    long time_diff;
491
479
    ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
492
480
    time_diff= (long) (alarm_data->expire_time - now);
493
 
    info->next_alarm_time= (uint32_t) (time_diff < 0 ? 0 : time_diff);
 
481
    info->next_alarm_time= (ulong) (time_diff < 0 ? 0 : time_diff);
494
482
  }
495
483
  pthread_mutex_unlock(&LOCK_alarm);
496
484
}
501
489
*/
502
490
 
503
491
 
504
 
static RETSIGTYPE thread_alarm(int sig)
 
492
static sig_handler thread_alarm(int sig)
505
493
{
506
494
#ifdef MAIN
507
495
  printf("thread_alarm\n"); fflush(stdout);
508
496
#endif
509
 
#ifndef HAVE_BSD_SIGNALS
 
497
#ifdef DONT_REMEMBER_SIGNAL
510
498
  my_sigset(sig,thread_alarm);          /* int. thread system calls */
511
499
#endif
512
500
}
534
522
  {
535
523
    if (alarm_queue.elements)
536
524
    {
537
 
      uint32_t sleep_time,now= my_time(0);
 
525
      ulong sleep_time,now= my_time(0);
538
526
      if (alarm_aborted)
539
527
        sleep_time=now+1;
540
528
      else
569
557
    }
570
558
    process_alarm(0);
571
559
  }
572
 
  memset(&alarm_thread, 0, sizeof(alarm_thread)); /* For easy debugging */
 
560
  bzero((char*) &alarm_thread,sizeof(alarm_thread)); /* For easy debugging */
573
561
  alarm_thread_running= 0;
574
562
  pthread_cond_signal(&COND_alarm);
575
563
  pthread_mutex_unlock(&LOCK_alarm);
590
578
 
591
579
static pthread_cond_t COND_thread_count;
592
580
static pthread_mutex_t LOCK_thread_count;
593
 
static uint32_t thread_count;
 
581
static uint thread_count;
594
582
 
595
583
#ifdef HPUX10
596
584
typedef int * fd_set_ptr;
637
625
      if (wait_time == 7)
638
626
      {                                         /* Simulate alarm-miss */
639
627
        fd_set readFDs;
640
 
        uint32_t max_connection=fileno(stdin);
 
628
        uint max_connection=fileno(stdin);
641
629
        FD_ZERO(&readFDs);
642
630
        FD_SET(max_connection,&readFDs);
643
631
        retry=0;
666
654
                break;
667
655
              continue;
668
656
            }
669
 
            getchar();                  /* Somebody was playing */
 
657
            VOID(getchar());                    /* Somebody was playing */
670
658
          }
671
659
        }
672
660
      }
678
666
  }
679
667
  pthread_mutex_lock(&LOCK_thread_count);
680
668
  thread_count--;
681
 
  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
 
669
  VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
682
670
  pthread_mutex_unlock(&LOCK_thread_count);
683
 
  free((unsigned char*) arg);
 
671
  free((uchar*) arg);
684
672
  return 0;
685
673
}
686
674
 
687
675
#ifdef USE_ONE_SIGNAL_HAND
688
 
static RETSIGTYPE print_signal_warning(int sig)
 
676
static sig_handler print_signal_warning(int sig)
689
677
{
690
678
  printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name());
691
679
  fflush(stdout);
692
 
#ifndef HAVE_BSD_SIGNALS
 
680
#ifdef DONT_REMEMBER_SIGNAL
693
681
  my_sigset(sig,print_signal_warning);          /* int. thread system calls */
694
682
#endif
695
683
  if (sig == SIGALRM)
707
695
  pthread_detach_this_thread();
708
696
  init_thr_alarm(10);                           /* Setup alarm handler */
709
697
  pthread_mutex_lock(&LOCK_thread_count);       /* Required by bsdi */
710
 
  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
 
698
  VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
711
699
  pthread_mutex_unlock(&LOCK_thread_count);
712
700
 
713
701
  sigemptyset(&set);                            /* Catch all signals */
793
781
#ifdef NOT_USED
794
782
  sigemptyset(&set);
795
783
  sigaddset(&set, thr_client_alarm);
796
 
  pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0);
 
784
  VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0));
797
785
#endif
798
786
 
799
787
  pthread_attr_init(&thr_attr);
802
790
  pthread_attr_setstacksize(&thr_attr,65536L);
803
791
 
804
792
  /* Start signal thread and wait for it to start */
805
 
  pthread_mutex_lock(&LOCK_thread_count);
 
793
  VOID(pthread_mutex_lock(&LOCK_thread_count));
806
794
  pthread_create(&tid,&thr_attr,signal_hand,NULL);
807
 
  pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
808
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
795
  VOID(pthread_cond_wait(&COND_thread_count,&LOCK_thread_count));
 
796
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
809
797
 
810
798
  thr_setconcurrency(3);
811
799
  pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
832
820
         alarm_info.next_alarm_time);
833
821
  while (thread_count)
834
822
  {
835
 
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
823
    VOID(pthread_cond_wait(&COND_thread_count,&LOCK_thread_count));
836
824
    if (thread_count == 1)
837
825
    {
838
826
      printf("Calling end_thr_alarm. This should cancel the last thread\n");