~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/mysql_protocol/net_serv.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-12-17 04:48:59 UTC
  • mto: This revision was merged to the branch mainline in revision 1246.
  • Revision ID: osullivan.padraig@gmail.com-20091217044859-qorpkp4911zypfv3
Added some dtrace probes for tracing the optimizer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#include "config.h"
 
21
#include <drizzled/global.h>
22
22
#include <drizzled/session.h>
23
 
#include <drizzled/error.h>
24
23
 
25
24
#include <assert.h>
26
25
#include <stdio.h>
37
36
#include "vio.h"
38
37
#include "net_serv.h"
39
38
 
40
 
namespace drizzle_plugin
41
 
{
42
 
 
43
39
using namespace std;
44
 
using namespace drizzled;
45
40
 
46
41
/*
47
42
  The following handles the differences when this is linked between the
52
47
  can't normally do this the client should have a bigger max_allowed_packet.
53
48
*/
54
49
 
55
 
  /* Constants when using compression */
56
 
#define NET_HEADER_SIZE 4               /* standard header size */
57
 
#define COMP_HEADER_SIZE 3              /* compression header extra size */
58
50
 
59
51
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
60
52
const char  *not_error_sqlstate= "00000";
68
60
{
69
61
  net->vio = vio;
70
62
  net->max_packet= (uint32_t) buffer_length;
71
 
  net->max_packet_size= max(buffer_length, drizzled::global_system_variables.max_allowed_packet);
 
63
  net->max_packet_size= max(buffer_length, global_system_variables.max_allowed_packet);
72
64
 
73
65
  if (!(net->buff=(unsigned char*) malloc((size_t) net->max_packet+
74
66
                                          NET_HEADER_SIZE + COMP_HEADER_SIZE)))
85
77
 
86
78
  if (vio != 0)                    /* If real connection */
87
79
  {
88
 
    net->fd  = vio->get_fd();            /* For perl DBI/DBD */
89
 
    vio->fastsend();
 
80
    net->fd  = drizzleclient_vio_fd(vio);            /* For perl DBI/DBD */
 
81
    drizzleclient_vio_fastsend(vio);
90
82
  }
91
83
  return(0);
92
84
}
93
85
 
94
 
bool drizzleclient_net_init_sock(NET * net, int sock, uint32_t buffer_length)
 
86
bool drizzleclient_net_init_sock(NET * net, int sock, int flags,
 
87
                                 uint32_t buffer_length)
95
88
{
96
 
  Vio *vio_tmp= new Vio(sock);
97
 
  if (vio_tmp == NULL)
 
89
 
 
90
  Vio *drizzleclient_vio_tmp= drizzleclient_vio_new(sock, VIO_TYPE_TCPIP, flags);
 
91
  if (drizzleclient_vio_tmp == NULL)
98
92
    return true;
99
93
  else
100
 
    if (drizzleclient_net_init(net, vio_tmp, buffer_length))
 
94
    if (drizzleclient_net_init(net, drizzleclient_vio_tmp, buffer_length))
101
95
    {
102
96
      /* Only delete the temporary vio if we didn't already attach it to the
103
97
       * NET object.
104
98
       */
105
 
      if (vio_tmp && (net->vio != vio_tmp))
106
 
        delete vio_tmp;
 
99
      if (drizzleclient_vio_tmp && (net->vio != drizzleclient_vio_tmp))
 
100
        drizzleclient_vio_delete(drizzleclient_vio_tmp);
107
101
      else
108
102
      {
109
103
        (void) shutdown(sock, SHUT_RDWR);
126
120
{
127
121
  if (net->vio != NULL)
128
122
  {
129
 
    delete net->vio;
 
123
    drizzleclient_vio_delete(net->vio);
130
124
    net->vio= 0;
131
125
  }
132
126
}
133
127
 
134
128
bool drizzleclient_net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
135
129
{
136
 
  return net->vio->peer_addr(buf, port, buflen);
 
130
  return drizzleclient_vio_peer_addr(net->vio, buf, port, buflen);
137
131
}
138
132
 
139
133
void drizzleclient_net_keepalive(NET *net, bool flag)
140
134
{
141
 
  net->vio->keepalive(flag);
 
135
  drizzleclient_vio_keepalive(net->vio, flag);
142
136
}
143
137
 
144
138
int drizzleclient_net_get_sd(NET *net)
145
139
{
146
 
  return net->vio->get_fd();
 
140
  return net->vio->sd;
147
141
}
148
142
 
149
143
bool drizzleclient_net_more_data(NET *net)
150
144
{
151
 
  return (net->vio == 0 || net->vio->get_read_pos() < net->vio->get_read_end());
 
145
  return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
152
146
}
153
147
 
154
148
/** Realloc the packet buffer. */
161
155
  if (length >= net->max_packet_size)
162
156
  {
163
157
    /* @todo: 1 and 2 codes are identical. */
164
 
    net->error= 3;
165
 
    net->last_errno= ER_NET_PACKET_TOO_LARGE;
166
 
    my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
 
158
    net->error= 1;
 
159
    net->last_errno= CR_NET_PACKET_TOO_LARGE;
167
160
    return(1);
168
161
  }
169
162
  pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
235
228
{
236
229
  if (clear_buffer)
237
230
  {
238
 
    while (net_data_is_ready(net->vio->get_fd()) > 0)
 
231
    while (net_data_is_ready(net->vio->sd) > 0)
239
232
    {
240
233
      /* The socket is ready */
241
 
      if (net->vio->read(net->buff, (size_t) net->max_packet) <= 0)
 
234
      if (drizzleclient_vio_read(net->vio, net->buff,
 
235
                   (size_t) net->max_packet) <= 0)
242
236
      {
243
237
        net->error= 2;
244
238
        break;
530
524
  while (pos != end)
531
525
  {
532
526
    assert(pos);
533
 
    // TODO - see bug comment below - will we crash now?
534
 
    if ((long) (length= net->vio->write( pos, (size_t) (end-pos))) <= 0)
 
527
    if ((long) (length= drizzleclient_vio_write(net->vio, pos, (size_t) (end-pos))) <= 0)
535
528
    {
536
529
     /*
537
530
      * We could end up here with net->vio == NULL
541
534
      if (net->vio == NULL)
542
535
        break;
543
536
      
544
 
      const bool interrupted= net->vio->should_retry();
 
537
      const bool interrupted= drizzleclient_vio_should_retry(net->vio);
545
538
      /*
546
539
        If we read 0, or we were interrupted this means that
547
540
        we need to switch to blocking mode and wait until the timeout
551
544
      {
552
545
        bool old_mode;
553
546
 
554
 
        while (net->vio->blocking(true, &old_mode) < 0)
 
547
        while (drizzleclient_vio_blocking(net->vio, true, &old_mode) < 0)
555
548
        {
556
 
          if (net->vio->should_retry() && retry_count++ < net->retry_count)
 
549
          if (drizzleclient_vio_should_retry(net->vio) && retry_count++ < net->retry_count)
557
550
            continue;
558
551
          net->error= 2;                     /* Close socket */
559
 
          net->last_errno= ER_NET_PACKET_TOO_LARGE;
560
 
          my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
 
552
          net->last_errno= CR_NET_PACKET_TOO_LARGE;
561
553
          goto end;
562
554
        }
563
555
        retry_count=0;
569
561
          continue;
570
562
      }
571
563
 
572
 
      if (net->vio->get_errno() == EINTR)
 
564
      if (drizzleclient_vio_errno(net->vio) == EINTR)
573
565
      {
574
566
        continue;
575
567
      }
579
571
      break;
580
572
    }
581
573
    pos+=length;
582
 
 
583
 
    /* If this is an error we may not have a current_session any more */
584
 
    if (current_session)
585
 
      current_session->status_var.bytes_sent+= length;
586
574
  }
587
575
end:
588
576
  if ((net->compress) && (packet != NULL))
606
594
my_real_read(NET *net, size_t *complen)
607
595
{
608
596
  unsigned char *pos;
609
 
  size_t length= 0;
 
597
  size_t length;
610
598
  uint32_t i,retry_count=0;
611
599
  size_t len=packet_error;
612
600
  uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
624
612
    while (remain > 0)
625
613
    {
626
614
      /* First read is done with non blocking mode */
627
 
      if ((long) (length= net->vio->read(pos, remain)) <= 0L)
 
615
      if ((long) (length= drizzleclient_vio_read(net->vio, pos, remain)) <= 0L)
628
616
      {
629
617
        if (net->vio == NULL)
630
618
          goto end;
631
619
 
632
 
        const bool interrupted = net->vio->should_retry();
 
620
        const bool interrupted = drizzleclient_vio_should_retry(net->vio);
633
621
 
634
622
        if (interrupted)
635
623
        {                    /* Probably in MIT threads */
636
624
          if (retry_count++ < net->retry_count)
637
625
            continue;
638
626
        }
639
 
        if (net->vio->get_errno() == EINTR)
 
627
        if (drizzleclient_vio_errno(net->vio) == EINTR)
640
628
        {
641
629
          continue;
642
630
        }
643
631
        len= packet_error;
644
632
        net->error= 2;                /* Close socket */
645
 
        net->last_errno= (net->vio->was_interrupted() ?
 
633
        net->last_errno= (drizzleclient_vio_was_interrupted(net->vio) ?
646
634
                          CR_NET_READ_INTERRUPTED :
647
635
                          CR_NET_READ_ERROR);
 
636
        ER(net->last_errno);
648
637
        goto end;
649
638
      }
650
639
      remain -= (uint32_t) length;
651
640
      pos+= length;
652
 
      current_session->status_var.bytes_received+= length;
653
641
    }
654
642
    if (i == 0)
655
643
    {                    /* First parts is packet length */
659
647
      {
660
648
        len= packet_error;
661
649
        /* Not a NET error on the client. XXX: why? */
662
 
        my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
663
650
        goto end;
664
651
      }
665
652
      net->compress_pkt_nr= ++net->pkt_nr;
681
668
      {
682
669
        if (drizzleclient_net_realloc(net,helping))
683
670
        {
684
 
          /* Clear the buffer so libdrizzle doesn't keep retrying */
685
 
          while (len > 0)
686
 
          {
687
 
            length= read(net->vio->get_fd(), net->buff, min((size_t)net->max_packet, len));
688
 
            assert((long)length > 0L);
689
 
            len-= length;
690
 
          }
691
 
            
692
671
          len= packet_error;          /* Return error and close connection */
693
672
          goto end;
694
673
        }
877
856
  net->read_timeout= timeout;
878
857
#ifndef __sun
879
858
  if (net->vio)
880
 
    net->vio->timeout(0, timeout);
 
859
    drizzleclient_vio_timeout(net->vio, 0, timeout);
881
860
#endif
882
861
  return;
883
862
}
888
867
  net->write_timeout= timeout;
889
868
#ifndef __sun
890
869
  if (net->vio)
891
 
    net->vio->timeout(1, timeout);
 
870
    drizzleclient_vio_timeout(net->vio, 1, timeout);
892
871
#endif
893
872
  return;
894
873
}
905
884
  strcpy(net->sqlstate, not_error_sqlstate);
906
885
}
907
886
 
908
 
} /* namespace drizzle_plugin */