~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/thr_alarm.cc

MergedĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
295
295
  if (thd_lib_detected == THD_LIB_LT &&
296
296
      !pthread_equal(pthread_self(),alarm_thread))
297
297
  {
298
 
#if defined(MAIN) && !defined(__bsdi__)
299
 
    printf("thread_alarm in process_alarm\n"); fflush(stdout);
300
 
#endif
301
298
#ifndef HAVE_BSD_SIGNALS
302
299
    my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */
303
300
#endif
324
321
{
325
322
  ALARM *alarm_data;
326
323
 
327
 
#if defined(MAIN)
328
 
  printf("process_alarm\n"); fflush(stdout);
329
 
#endif
330
324
  if (alarm_queue.elements)
331
325
  {
332
326
    if (alarm_aborted)
339
333
        if (pthread_equal(alarm_data->thread,alarm_thread) ||
340
334
            pthread_kill(alarm_data->thread, thr_client_alarm))
341
335
        {
342
 
#ifdef MAIN
343
 
          printf("Warning: pthread_kill couldn't find thread!!!\n");
344
 
#endif
345
336
          queue_remove(&alarm_queue,i);         /* No thread. Remove alarm */
346
337
        }
347
338
        else
362
353
        if (pthread_equal(alarm_data->thread,alarm_thread) ||
363
354
            pthread_kill(alarm_data->thread, thr_client_alarm))
364
355
        {
365
 
#ifdef MAIN
366
 
          printf("Warning: pthread_kill couldn't find thread!!!\n");
367
 
#endif
368
356
          queue_remove(&alarm_queue,0);         /* No thread. Remove alarm */
369
357
          if (!alarm_queue.elements)
370
358
            break;
502
490
 
503
491
RETSIGTYPE thread_alarm(int sig)
504
492
{
505
 
#ifdef MAIN
506
 
  printf("thread_alarm\n"); fflush(stdout);
507
 
#endif
508
493
#ifndef HAVE_BSD_SIGNALS
509
494
  my_sigset(sig,thread_alarm);          /* int. thread system calls */
510
495
#endif
523
508
{
524
509
  int error;
525
510
  struct timespec abstime;
526
 
#ifdef MAIN
527
 
  puts("Starting alarm thread");
528
 
#endif
529
511
  my_thread_init();
530
512
  alarm_thread_running= 1;
531
513
  pthread_mutex_lock(&LOCK_alarm);
546
528
        if ((error=pthread_cond_timedwait(&COND_alarm,&LOCK_alarm,&abstime)) &&
547
529
            error != ETIME && error != ETIMEDOUT)
548
530
        {
549
 
#ifdef MAIN
550
 
          printf("Got error: %d from ptread_cond_timedwait (errno: %d)\n",
551
 
                 error,errno);
552
 
#endif
 
531
          assert(1);
553
532
        }
554
533
      }
555
534
    }
558
537
    else
559
538
    {
560
539
      next_alarm_expire_time= ~ (time_t) 0;
561
 
      if ((error=pthread_cond_wait(&COND_alarm,&LOCK_alarm)))
562
 
      {
563
 
#ifdef MAIN
564
 
        printf("Got error: %d from ptread_cond_wait (errno: %d)\n",
565
 
               error,errno);
566
 
#endif
567
 
      }
 
540
      error= pthread_cond_wait(&COND_alarm,&LOCK_alarm);
 
541
 
 
542
      assert(error == 0);
568
543
    }
569
544
    process_alarm(0);
570
545
  }
578
553
#endif /* USE_ALARM_THREAD */
579
554
 
580
555
#endif /* THREAD */
581
 
 
582
 
 
583
 
/****************************************************************************
584
 
  Handling of test case (when compiled with -DMAIN)
585
 
***************************************************************************/
586
 
 
587
 
#ifdef MAIN
588
 
#if !defined(DONT_USE_THR_ALARM)
589
 
 
590
 
static pthread_cond_t COND_thread_count;
591
 
static pthread_mutex_t LOCK_thread_count;
592
 
static uint32_t thread_count;
593
 
 
594
 
#ifdef HPUX10
595
 
typedef int * fd_set_ptr;
596
 
#else
597
 
typedef fd_set * fd_set_ptr;
598
 
#endif /* HPUX10 */
599
 
 
600
 
static void *test_thread(void *arg)
601
 
{
602
 
  int i,param=*((int*) arg),wait_time,retry;
603
 
  time_t start_time;
604
 
  thr_alarm_t got_alarm;
605
 
  fd_set fd;
606
 
  FD_ZERO(&fd);
607
 
  my_thread_init();
608
 
  printf("Thread %d (%s) started\n",param,my_thread_name()); fflush(stdout);
609
 
  for (i=1 ; i <= 10 ; i++)
610
 
  {
611
 
    wait_time=param ? 11-i : i;
612
 
    start_time= my_time(0);
613
 
    if (thr_alarm(&got_alarm,wait_time,0))
614
 
    {
615
 
      printf("Thread: %s  Alarms aborted\n",my_thread_name());
616
 
      break;
617
 
    }
618
 
    if (wait_time == 3)
619
 
    {
620
 
      printf("Thread: %s  Simulation of no alarm needed\n",my_thread_name());
621
 
      fflush(stdout);
622
 
    }
623
 
    else
624
 
    {
625
 
      for (retry=0 ; !thr_got_alarm(&got_alarm) && retry < 10 ; retry++)
626
 
      {
627
 
        printf("Thread: %s  Waiting %d sec\n",my_thread_name(),wait_time);
628
 
        select(0,(fd_set_ptr) &fd,0,0,0);
629
 
      }
630
 
      if (!thr_got_alarm(&got_alarm))
631
 
      {
632
 
        printf("Thread: %s  didn't get an alarm. Aborting!\n",
633
 
               my_thread_name());
634
 
        break;
635
 
      }
636
 
      if (wait_time == 7)
637
 
      {                                         /* Simulate alarm-miss */
638
 
        fd_set readFDs;
639
 
        uint32_t max_connection=fileno(stdin);
640
 
        FD_ZERO(&readFDs);
641
 
        FD_SET(max_connection,&readFDs);
642
 
        retry=0;
643
 
        for (;;)
644
 
        {
645
 
          printf("Thread: %s  Simulating alarm miss\n",my_thread_name());
646
 
          fflush(stdout);
647
 
          if (select(max_connection+1, (fd_set_ptr) &readFDs,0,0,0) < 0)
648
 
          {
649
 
            if (errno == EINTR)
650
 
              break;                            /* Got new interrupt */
651
 
            printf("Got errno: %d from select.  Retrying..\n",errno);
652
 
            if (retry++ >= 3)
653
 
            {
654
 
              printf("Warning:  Interrupt of select() doesn't set errno!\n");
655
 
              break;
656
 
            }
657
 
          }
658
 
          else                                  /* This shouldn't happen */
659
 
          {
660
 
            if (!FD_ISSET(max_connection,&readFDs))
661
 
            {
662
 
              printf("Select interrupted, but errno not set\n");
663
 
              fflush(stdout);
664
 
              if (retry++ >= 3)
665
 
                break;
666
 
              continue;
667
 
            }
668
 
            getchar();                  /* Somebody was playing */
669
 
          }
670
 
        }
671
 
      }
672
 
    }
673
 
    printf("Thread: %s  Slept for %d (%d) sec\n",my_thread_name(),
674
 
           (int) (my_time(0)-start_time), wait_time); fflush(stdout);
675
 
    thr_end_alarm(&got_alarm);
676
 
    fflush(stdout);
677
 
  }
678
 
  pthread_mutex_lock(&LOCK_thread_count);
679
 
  thread_count--;
680
 
  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
681
 
  pthread_mutex_unlock(&LOCK_thread_count);
682
 
  free((unsigned char*) arg);
683
 
  return 0;
684
 
}
685
 
 
686
 
#ifdef USE_ONE_SIGNAL_HAND
687
 
static RETSIGTYPE print_signal_warning(int sig)
688
 
{
689
 
  printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name());
690
 
  fflush(stdout);
691
 
#ifndef HAVE_BSD_SIGNALS
692
 
  my_sigset(sig,print_signal_warning);          /* int. thread system calls */
693
 
#endif
694
 
  if (sig == SIGALRM)
695
 
    alarm(2);                                   /* reschedule alarm */
696
 
}
697
 
#endif /* USE_ONE_SIGNAL_HAND */
698
 
 
699
 
 
700
 
static void *signal_hand(void *arg __attribute__((unused)))
701
 
{
702
 
  sigset_t set;
703
 
  int sig,error,err_count=0;;
704
 
 
705
 
  my_thread_init();
706
 
  pthread_detach_this_thread();
707
 
  init_thr_alarm(10);                           /* Setup alarm handler */
708
 
  pthread_mutex_lock(&LOCK_thread_count);       /* Required by bsdi */
709
 
  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
710
 
  pthread_mutex_unlock(&LOCK_thread_count);
711
 
 
712
 
  sigemptyset(&set);                            /* Catch all signals */
713
 
  sigaddset(&set,SIGINT);
714
 
  sigaddset(&set,SIGQUIT);
715
 
  sigaddset(&set,SIGTERM);
716
 
  sigaddset(&set,SIGHUP);
717
 
#ifdef SIGTSTP
718
 
  sigaddset(&set,SIGTSTP);
719
 
#endif
720
 
#ifdef USE_ONE_SIGNAL_HAND
721
 
  sigaddset(&set,THR_SERVER_ALARM);             /* For alarms */
722
 
  puts("Starting signal and alarm handling thread");
723
 
#else
724
 
  puts("Starting signal handling thread");
725
 
#endif
726
 
  printf("server alarm: %d  thread alarm: %d\n",
727
 
         THR_SERVER_ALARM, thr_client_alarm);
728
 
  for(;;)
729
 
  {
730
 
    while ((error=my_sigwait(&set,&sig)) == EINTR)
731
 
      printf("sigwait restarted\n");
732
 
    if (error)
733
 
    {
734
 
      fprintf(stderr,"Got error %d from sigwait\n",error);
735
 
      if (err_count++ > 5)
736
 
        exit(1);                                /* Too many errors in test */
737
 
      continue;
738
 
    }
739
 
#ifdef USE_ONE_SIGNAL_HAND
740
 
    if (sig != THR_SERVER_ALARM)
741
 
#endif
742
 
      printf("Main thread: Got signal %d\n",sig);
743
 
    switch (sig) {
744
 
    case SIGINT:
745
 
    case SIGQUIT:
746
 
    case SIGTERM:
747
 
    case SIGHUP:
748
 
      printf("Aborting nicely\n");
749
 
      end_thr_alarm(0);
750
 
      break;
751
 
#ifdef SIGTSTP
752
 
    case SIGTSTP:
753
 
      printf("Aborting\n");
754
 
      exit(1);
755
 
      return 0;                                 /* Keep some compilers happy */
756
 
#endif
757
 
#ifdef USE_ONE_SIGNAL_HAND
758
 
     case THR_SERVER_ALARM:
759
 
       process_alarm(sig);
760
 
      break;
761
 
#endif
762
 
    }
763
 
  }
764
 
}
765
 
 
766
 
 
767
 
int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
768
 
{
769
 
  pthread_t tid;
770
 
  pthread_attr_t thr_attr;
771
 
  int i,*param,error;
772
 
  sigset_t set;
773
 
  ALARM_INFO alarm_info;
774
 
  MY_INIT(argv[0]);
775
 
 
776
 
  pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
777
 
  pthread_cond_init(&COND_thread_count,NULL);
778
 
 
779
 
  /* Start a alarm handling thread */
780
 
  sigemptyset(&set);
781
 
  sigaddset(&set,SIGINT);
782
 
  sigaddset(&set,SIGQUIT);
783
 
  sigaddset(&set,SIGTERM);
784
 
  sigaddset(&set,SIGHUP);
785
 
  signal(SIGTERM,SIG_DFL);                      /* If it's blocked by parent */
786
 
#ifdef SIGTSTP
787
 
  sigaddset(&set,SIGTSTP);
788
 
#endif
789
 
  sigaddset(&set,THR_SERVER_ALARM);
790
 
  sigdelset(&set, thr_client_alarm);
791
 
  (void) pthread_sigmask(SIG_SETMASK,&set,NULL);
792
 
#ifdef NOT_USED
793
 
  sigemptyset(&set);
794
 
  sigaddset(&set, thr_client_alarm);
795
 
  pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0);
796
 
#endif
797
 
 
798
 
  pthread_attr_init(&thr_attr);
799
 
  pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
800
 
  pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
801
 
  pthread_attr_setstacksize(&thr_attr,65536L);
802
 
 
803
 
  /* Start signal thread and wait for it to start */
804
 
  pthread_mutex_lock(&LOCK_thread_count);
805
 
  pthread_create(&tid,&thr_attr,signal_hand,NULL);
806
 
  pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
807
 
  pthread_mutex_unlock(&LOCK_thread_count);
808
 
 
809
 
  thr_setconcurrency(3);
810
 
  pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
811
 
  printf("Main thread: %s\n",my_thread_name());
812
 
  for (i=0 ; i < 2 ; i++)
813
 
  {
814
 
    param=(int*) malloc(sizeof(int));
815
 
    *param= i;
816
 
    pthread_mutex_lock(&LOCK_thread_count);
817
 
    if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
818
 
    {
819
 
      printf("Can't create thread %d, error: %d\n",i,error);
820
 
      exit(1);
821
 
    }
822
 
    thread_count++;
823
 
    pthread_mutex_unlock(&LOCK_thread_count);
824
 
  }
825
 
 
826
 
  pthread_attr_destroy(&thr_attr);
827
 
  pthread_mutex_lock(&LOCK_thread_count);
828
 
  thr_alarm_info(&alarm_info);
829
 
  printf("Main_thread:  Alarms: %u  max_alarms: %u  next_alarm_time: %lu\n",
830
 
         alarm_info.active_alarms, alarm_info.max_used_alarms,
831
 
         alarm_info.next_alarm_time);
832
 
  while (thread_count)
833
 
  {
834
 
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
835
 
    if (thread_count == 1)
836
 
    {
837
 
      printf("Calling end_thr_alarm. This should cancel the last thread\n");
838
 
      end_thr_alarm(0);
839
 
    }
840
 
  }
841
 
  pthread_mutex_unlock(&LOCK_thread_count);
842
 
  thr_alarm_info(&alarm_info);
843
 
  end_thr_alarm(1);
844
 
  printf("Main_thread:  Alarms: %u  max_alarms: %u  next_alarm_time: %lu\n",
845
 
         alarm_info.active_alarms, alarm_info.max_used_alarms,
846
 
         alarm_info.next_alarm_time);
847
 
  printf("Test succeeded\n");
848
 
  return 0;
849
 
}
850
 
 
851
 
#else /* DONT_USE_THR_ALARM */
852
 
 
853
 
int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
854
 
{
855
 
  printf("thr_alarm disabled with DONT_USE_THR_ALARM\n");
856
 
  exit(1);
857
 
}
858
 
 
859
 
#endif /* DONT_USE_THR_ALARM */
860
 
#endif /* MAIN */