~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/net_serv.c

  • Committer: Brian Aker
  • Date: 2008-07-10 18:40:16 UTC
  • mfrom: (77.1.63 codestyle)
  • Revision ID: brian@tangent.org-20080710184016-9dbmgqzl1diwrj82
Merge.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
  can't normally do this the client should have a bigger max_allowed_packet.
38
38
*/
39
39
 
40
 
#if !defined(MYSQL_SERVER)
41
 
#define NO_ALARM
42
 
#endif
43
40
 
44
 
#ifndef NO_ALARM
45
 
#include "my_pthread.h"
46
 
void sql_print_error(const char *format,...);
47
 
#else
48
41
#define DONT_USE_THR_ALARM
49
 
#endif /* NO_ALARM */
50
42
 
51
43
#include "thr_alarm.h"
52
44
 
53
 
#ifdef MYSQL_SERVER
54
 
/*
55
 
  The following variables/functions should really not be declared
56
 
  extern, but as it's hard to include mysql_priv.h here, we have to
57
 
  live with this for a while.
58
 
*/
59
 
extern uint test_flags;
60
 
extern ulong bytes_sent, bytes_received, net_big_packet_count;
61
 
#define update_statistics(A) A
62
 
#endif /* defined(MYSQL_SERVER) */
63
45
 
64
 
#if !defined(MYSQL_SERVER)
65
46
#define update_statistics(A)
66
47
#define thd_increment_bytes_sent(N)
67
 
#endif
68
48
 
69
49
#define TEST_BLOCKING           8
70
50
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
96
76
  if (vio != 0)                                 /* If real connection */
97
77
  {
98
78
    net->fd  = vio_fd(vio);                     /* For perl DBI/DBD */
99
 
#if defined(MYSQL_SERVER)
100
 
    if (!(test_flags & TEST_BLOCKING))
101
 
    {
102
 
      my_bool old_mode;
103
 
      vio_blocking(vio, FALSE, &old_mode);
104
 
    }
105
 
#endif
106
79
    vio_fastsend(vio);
107
80
  }
108
81
  DBUG_RETURN(0);
134
107
    /* @todo: 1 and 2 codes are identical. */
135
108
    net->error= 1;
136
109
    net->last_errno= ER_NET_PACKET_TOO_LARGE;
137
 
#ifdef MYSQL_SERVER
138
 
    my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
139
 
#endif
140
110
    DBUG_RETURN(1);
141
111
  }
142
112
  pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); 
496
466
  size_t length;
497
467
  const uchar *pos,*end;
498
468
  thr_alarm_t alarmed;
499
 
#ifndef NO_ALARM
500
 
  ALARM alarm_buff;
501
 
#endif
502
469
  uint retry_count=0;
503
470
  my_bool net_blocking = vio_is_blocking(net->vio);
504
471
  DBUG_ENTER("net_real_write");
536
503
  DBUG_DUMP("data", packet, len);
537
504
#endif
538
505
 
539
 
#ifndef NO_ALARM
540
 
  thr_alarm_init(&alarmed);
541
 
  if (net_blocking)
542
 
    thr_alarm(&alarmed, net->write_timeout, &alarm_buff);
543
 
#else
544
506
  alarmed=0;
545
507
  /* Write timeout is set in my_net_set_write_timeout */
546
 
#endif /* NO_ALARM */
547
508
 
548
509
  pos= packet;
549
510
  end=pos+len;
568
529
#endif /* EXTRA_DEBUG */
569
530
            net->error= 2;                     /* Close socket */
570
531
            net->last_errno= ER_NET_PACKET_TOO_LARGE;
571
 
#ifdef MYSQL_SERVER
572
 
            my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
573
 
#endif
574
532
            goto end;
575
533
          }
576
534
          retry_count=0;
588
546
                  my_progname);
589
547
#endif /* EXTRA_DEBUG */
590
548
      }
591
 
#if !defined(MYSQL_SERVER)
592
549
      if (vio_errno(net->vio) == SOCKET_EINTR)
593
550
      {
594
551
        DBUG_PRINT("warning",("Interrupted write. Retrying..."));
595
552
        continue;
596
553
      }
597
 
#endif /* !defined(MYSQL_SERVER) */
598
554
      net->error= 2;                            /* Close socket */
599
555
      net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
600
556
                               ER_NET_ERROR_ON_WRITE);
601
 
#ifdef MYSQL_SERVER
602
 
      my_error(net->last_errno, MYF(0));
603
 
#endif /* MYSQL_SERVER */
604
557
      break;
605
558
    }
606
559
    pos+=length;
620
573
}
621
574
 
622
575
 
623
 
/*****************************************************************************
624
 
** Read something from server/clinet
625
 
*****************************************************************************/
626
 
 
627
 
#ifndef NO_ALARM
628
 
 
629
 
static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
630
 
                             thr_alarm_t *alarmed)
631
 
{
632
 
  uint retry_count=0;
633
 
  while (length > 0)
634
 
  {
635
 
    size_t tmp;
636
 
    if ((long) (tmp= vio_read(net->vio, buff, length)) <= 0)
637
 
    {
638
 
      my_bool interrupted = vio_should_retry(net->vio);
639
 
      if (!thr_got_alarm(alarmed) && interrupted)
640
 
      {                                 /* Probably in MIT threads */
641
 
        if (retry_count++ < net->retry_count)
642
 
          continue;
643
 
      }
644
 
      return 1;
645
 
    }
646
 
    length-= tmp;
647
 
    buff+= tmp;
648
 
  }
649
 
  return 0;
650
 
}
651
 
 
652
 
/**
653
 
  Help function to clear the commuication buffer when we get a too big packet.
654
 
 
655
 
  @param net            Communication handle
656
 
  @param remain Bytes to read
657
 
  @param alarmed        Parameter for thr_alarm()
658
 
  @param alarm_buff     Parameter for thr_alarm()
659
 
 
660
 
  @retval
661
 
   0    Was able to read the whole packet
662
 
  @retval
663
 
   1    Got mailformed packet from client
664
 
*/
665
 
 
666
 
static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
667
 
                                ALARM *alarm_buff)
668
 
{
669
 
  uint32 old=remain;
670
 
  DBUG_ENTER("my_net_skip_rest");
671
 
  DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
672
 
 
673
 
  /* The following is good for debugging */
674
 
  update_statistics(thd_increment_net_big_packet_count(1));
675
 
 
676
 
  if (!thr_alarm_in_use(alarmed))
677
 
  {
678
 
    my_bool old_mode;
679
 
    if (thr_alarm(alarmed,net->read_timeout, alarm_buff) ||
680
 
        vio_blocking(net->vio, TRUE, &old_mode) < 0)
681
 
      DBUG_RETURN(1);                           /* Can't setup, abort */
682
 
  }
683
 
  for (;;)
684
 
  {
685
 
    while (remain > 0)
686
 
    {
687
 
      size_t length= min(remain, net->max_packet);
688
 
      if (net_safe_read(net, net->buff, length, alarmed))
689
 
        DBUG_RETURN(1);
690
 
      update_statistics(thd_increment_bytes_received(length));
691
 
      remain -= (uint32) length;
692
 
    }
693
 
    if (old != MAX_PACKET_LENGTH)
694
 
      break;
695
 
    if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
696
 
      DBUG_RETURN(1);
697
 
    old=remain= uint3korr(net->buff);
698
 
    net->pkt_nr++;
699
 
  }
700
 
  DBUG_RETURN(0);
701
 
}
702
 
#endif /* NO_ALARM */
703
 
 
704
 
 
705
576
/**
706
577
  Reads one packet to net->buff + net->where_b.
707
578
  Long packets are handled by my_net_read().
719
590
  uint i,retry_count=0;
720
591
  ulong len=packet_error;
721
592
  thr_alarm_t alarmed;
722
 
#ifndef NO_ALARM
723
 
  ALARM alarm_buff;
724
 
#endif
725
593
  my_bool net_blocking=vio_is_blocking(net->vio);
726
594
  uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
727
595
                  NET_HEADER_SIZE);
729
597
 
730
598
  net->reading_or_writing=1;
731
599
  thr_alarm_init(&alarmed);
732
 
#ifndef NO_ALARM
733
 
  if (net_blocking)
734
 
    thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
735
 
#else
736
600
  /* Read timeout is set in my_net_set_read_timeout */
737
 
#endif /* NO_ALARM */
738
601
 
739
602
    pos = net->buff + net->where_b;             /* net->packet -4 */
740
603
    for (i=0 ; i < 2 ; i++)
748
611
 
749
612
          DBUG_PRINT("info",("vio_read returned %ld  errno: %d",
750
613
                             (long) length, vio_errno(net->vio)));
751
 
#if defined(MYSQL_SERVER)
752
 
          /*
753
 
            We got an error that there was no data on the socket. We now set up
754
 
            an alarm to not 'read forever', change the socket to non blocking
755
 
            mode and try again
756
 
          */
757
 
          if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
758
 
          {
759
 
            if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
760
 
            {
761
 
              my_bool old_mode;
762
 
              while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
763
 
              {
764
 
                if (vio_should_retry(net->vio) &&
765
 
                    retry_count++ < net->retry_count)
766
 
                  continue;
767
 
                DBUG_PRINT("error",
768
 
                           ("fcntl returned error %d, aborting thread",
769
 
                            vio_errno(net->vio)));
770
 
#ifdef EXTRA_DEBUG
771
 
                fprintf(stderr,
772
 
                        "%s: read: fcntl returned error %d, aborting thread\n",
773
 
                        my_progname,vio_errno(net->vio));
774
 
#endif /* EXTRA_DEBUG */
775
 
                len= packet_error;
776
 
                net->error= 2;                 /* Close socket */
777
 
                net->last_errno= ER_NET_FCNTL_ERROR;
778
 
#ifdef MYSQL_SERVER
779
 
                my_error(ER_NET_FCNTL_ERROR, MYF(0));
780
 
#endif
781
 
                goto end;
782
 
              }
783
 
              retry_count=0;
784
 
              continue;
785
 
            }
786
 
          }
787
 
#endif /* defined(MYSQL_SERVER) */
788
614
          if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
789
615
              interrupted)
790
616
          {                                     /* Probably in MIT threads */
795
621
                    my_progname,vio_errno(net->vio));
796
622
#endif /* EXTRA_DEBUG */
797
623
          }
798
 
#if !defined(MYSQL_SERVER)
799
624
          if (vio_errno(net->vio) == SOCKET_EINTR)
800
625
          {
801
626
            DBUG_PRINT("warning",("Interrupted read. Retrying..."));
802
627
            continue;
803
628
          }
804
 
#endif
805
629
          DBUG_PRINT("error",("Couldn't read packet: remain: %u  errno: %d  length: %ld",
806
630
                              remain, vio_errno(net->vio), (long) length));
807
631
          len= packet_error;
809
633
          net->last_errno= (vio_was_interrupted(net->vio) ?
810
634
                                   ER_NET_READ_INTERRUPTED :
811
635
                                   ER_NET_READ_ERROR);
812
 
#ifdef MYSQL_SERVER
813
 
          my_error(net->last_errno, MYF(0));
814
 
#endif
815
636
          goto end;
816
637
        }
817
638
        remain -= (uint32) length;
842
663
          }
843
664
          len= packet_error;
844
665
          /* Not a NET error on the client. XXX: why? */
845
 
#ifdef MYSQL_SERVER
846
 
          my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
847
 
#endif
848
666
          goto end;
849
667
        }
850
668
        net->compress_pkt_nr= ++net->pkt_nr;
866
684
        {
867
685
          if (net_realloc(net,helping))
868
686
          {
869
 
#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
870
 
            if (!net->compress &&
871
 
                !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
872
 
              net->error= 3;            /* Successfully skiped packet */
873
 
#endif
874
687
            len= packet_error;          /* Return error and close connection */
875
688
            goto end;
876
689
          }
1026
839
      {
1027
840
        net->error= 2;                  /* caller will close socket */
1028
841
        net->last_errno= ER_NET_UNCOMPRESS_ERROR;
1029
 
#ifdef MYSQL_SERVER
1030
 
        my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
1031
 
#endif
1032
842
        return packet_error;
1033
843
      }
1034
844
      buf_length+= complen;
1051
861
  DBUG_ENTER("my_net_set_read_timeout");
1052
862
  DBUG_PRINT("enter", ("timeout: %d", timeout));
1053
863
  net->read_timeout= timeout;
1054
 
#ifdef NO_ALARM
1055
864
  if (net->vio)
1056
865
    vio_timeout(net->vio, 0, timeout);
1057
 
#endif
1058
866
  DBUG_VOID_RETURN;
1059
867
}
1060
868
 
1064
872
  DBUG_ENTER("my_net_set_write_timeout");
1065
873
  DBUG_PRINT("enter", ("timeout: %d", timeout));
1066
874
  net->write_timeout= timeout;
1067
 
#ifdef NO_ALARM
1068
875
  if (net->vio)
1069
876
    vio_timeout(net->vio, 1, timeout);
1070
 
#endif
1071
877
  DBUG_VOID_RETURN;
1072
878
}