~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/oldlibdrizzle/net_serv.cc

  • Committer: Brian Aker
  • Date: 2009-04-27 14:36:40 UTC
  • Revision ID: brian@gaz-20090427143640-f6zjmtt9vm55qgm2
Patch on show processlist from  davi@apache.org

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
 
#define __need_timeval 1
22
 
 
 
21
#include <drizzled/global.h>
 
22
#include <drizzled/session.h>
23
23
#include "libdrizzle.h"
24
24
#include "libdrizzle_priv.h"
25
 
#include <libdrizzle/errmsg.h>
26
 
#include <vio/violite.h>
 
25
#include "errmsg.h"
 
26
#include "vio.h"
27
27
#include <assert.h>
28
28
#include <stdio.h>
29
29
#include <stdlib.h>
34
34
#include <sys/poll.h>
35
35
#include <zlib.h>
36
36
 
 
37
using namespace std;
 
38
 
37
39
/*
38
40
  The following handles the differences when this is linked between the
39
41
  client and the server.
44
46
*/
45
47
 
46
48
 
47
 
#define update_statistics(A)
48
 
#define thd_increment_bytes_sent(N)
49
 
 
50
 
#define TEST_BLOCKING        8
51
49
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
52
 
#define MIN_COMPRESS_LENGTH             50      /* Don't compress small bl. */
53
50
 
54
51
static bool net_write_buff(NET *net, const unsigned char *packet, uint32_t len);
55
52
 
 
53
void drizzleclient_net_local_init(NET *net)
 
54
{
 
55
  net->max_packet= (uint32_t) global_system_variables.net_buffer_length;
 
56
 
 
57
  drizzleclient_net_set_read_timeout(net,
 
58
                          (uint32_t)global_system_variables.net_read_timeout);
 
59
  drizzleclient_net_set_write_timeout(net,
 
60
                         (uint32_t)global_system_variables.net_write_timeout);
 
61
 
 
62
  net->retry_count=  (uint32_t) global_system_variables.net_retry_count;
 
63
  net->max_packet_size= cmax(global_system_variables.net_buffer_length,
 
64
                             global_system_variables.max_allowed_packet);
 
65
}
56
66
 
57
67
/** Init with packet info. */
58
68
 
59
 
bool my_net_init(NET *net, Vio* vio)
 
69
bool drizzleclient_net_init(NET *net, Vio* vio)
60
70
{
61
71
  net->vio = vio;
62
 
  my_net_local_init(net);            /* Set some limits */
 
72
  drizzleclient_net_local_init(net);            /* Set some limits */
63
73
  if (!(net->buff=(unsigned char*) malloc((size_t) net->max_packet+
64
 
                                  NET_HEADER_SIZE + COMP_HEADER_SIZE)))
 
74
                                          NET_HEADER_SIZE + COMP_HEADER_SIZE)))
65
75
    return(1);
66
76
  net->buff_end=net->buff+net->max_packet;
67
77
  net->error=0; net->return_status=0;
75
85
 
76
86
  if (vio != 0)                    /* If real connection */
77
87
  {
78
 
    net->fd  = vio_fd(vio);            /* For perl DBI/DBD */
79
 
    vio_fastsend(vio);
 
88
    net->fd  = drizzleclient_vio_fd(vio);            /* For perl DBI/DBD */
 
89
    drizzleclient_vio_fastsend(vio);
80
90
  }
81
91
  return(0);
82
92
}
83
93
 
84
 
bool net_init_sock(NET * net, int sock, int flags)
 
94
bool drizzleclient_net_init_sock(NET * net, int sock, int flags)
85
95
{
86
96
 
87
 
  Vio *vio_tmp= vio_new(sock, VIO_TYPE_TCPIP, flags);
88
 
  if (vio_tmp == NULL)
 
97
  Vio *drizzleclient_vio_tmp= drizzleclient_vio_new(sock, VIO_TYPE_TCPIP, flags);
 
98
  if (drizzleclient_vio_tmp == NULL)
89
99
    return true;
90
100
  else
91
 
    if (my_net_init(net, vio_tmp))
 
101
    if (drizzleclient_net_init(net, drizzleclient_vio_tmp))
92
102
    {
93
103
      /* Only delete the temporary vio if we didn't already attach it to the
94
104
       * NET object.
95
105
       */
96
 
      if (vio_tmp && (net->vio != vio_tmp))
97
 
        vio_delete(vio_tmp);
 
106
      if (drizzleclient_vio_tmp && (net->vio != drizzleclient_vio_tmp))
 
107
        drizzleclient_vio_delete(drizzleclient_vio_tmp);
98
108
      else
99
109
      {
100
110
        (void) shutdown(sock, SHUT_RDWR);
105
115
  return false;
106
116
}
107
117
 
108
 
void net_end(NET *net)
 
118
void drizzleclient_net_end(NET *net)
109
119
{
110
120
  if (net->buff != NULL)
111
121
    free(net->buff);
112
 
  net->buff=0;
 
122
  net->buff= NULL;
113
123
  return;
114
124
}
115
125
 
116
 
void net_close(NET *net)
 
126
void drizzleclient_net_close(NET *net)
117
127
{
118
128
  if (net->vio != NULL)
119
129
  {
120
 
    vio_delete(net->vio);
 
130
    drizzleclient_vio_delete(net->vio);
121
131
    net->vio= 0;
122
132
  }
123
133
}
124
134
 
125
 
bool net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
126
 
{
127
 
  return vio_peer_addr(net->vio, buf, port, buflen);
128
 
}
129
 
 
130
 
void net_keepalive(NET *net, bool flag)
131
 
{
132
 
  vio_keepalive(net->vio, flag);
133
 
}
134
 
 
135
 
int net_get_sd(NET *net)
 
135
bool drizzleclient_net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
 
136
{
 
137
  return drizzleclient_vio_peer_addr(net->vio, buf, port, buflen);
 
138
}
 
139
 
 
140
void drizzleclient_net_keepalive(NET *net, bool flag)
 
141
{
 
142
  drizzleclient_vio_keepalive(net->vio, flag);
 
143
}
 
144
 
 
145
int drizzleclient_net_get_sd(NET *net)
136
146
{
137
147
  return net->vio->sd;
138
148
}
139
149
 
140
 
bool net_should_close(NET *net)
 
150
bool drizzleclient_net_should_close(NET *net)
141
151
{
142
152
  return net->error || (net->vio == 0);
143
153
}
144
154
 
145
 
bool net_more_data(NET *net)
 
155
bool drizzleclient_net_more_data(NET *net)
146
156
{
147
157
  return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
148
158
}
149
159
 
150
160
/** Realloc the packet buffer. */
151
161
 
152
 
bool net_realloc(NET *net, size_t length)
 
162
bool drizzleclient_net_realloc(NET *net, size_t length)
153
163
{
154
164
  unsigned char *buff;
155
165
  size_t pkt_length;
215
225
   Read from socket until there is nothing more to read. Discard
216
226
   what is read.
217
227
 
218
 
   If there is anything when to read 'net_clear' is called this
 
228
   If there is anything when to read 'drizzleclient_net_clear' is called this
219
229
   normally indicates an error in the protocol.
220
230
 
221
231
   When connection is properly closed (for TCP it means with
226
236
   @param clear_buffer           if <> 0, then clear all data from comm buff
227
237
*/
228
238
 
229
 
void net_clear(NET *net, bool clear_buffer)
 
239
void drizzleclient_net_clear(NET *net, bool clear_buffer)
230
240
{
231
241
  if (clear_buffer)
232
242
  {
233
243
    while (net_data_is_ready(net->vio->sd) > 0)
234
244
    {
235
245
      /* The socket is ready */
236
 
      if (vio_read(net->vio, net->buff,
 
246
      if (drizzleclient_vio_read(net->vio, net->buff,
237
247
                   (size_t) net->max_packet) <= 0)
238
248
      {
239
249
        net->error= 2;
249
259
 
250
260
/** Flush write_buffer if not empty. */
251
261
 
252
 
bool net_flush(NET *net)
 
262
bool drizzleclient_net_flush(NET *net)
253
263
{
254
264
  bool error= 0;
255
265
  if (net->buff != net->write_pos)
256
266
  {
257
 
    error=net_real_write(net, net->buff,
 
267
    error=drizzleclient_net_real_write(net, net->buff,
258
268
                         (size_t) (net->write_pos - net->buff)) ? 1 : 0;
259
269
    net->write_pos=net->buff;
260
270
  }
280
290
*/
281
291
 
282
292
bool
283
 
my_net_write(NET *net,const unsigned char *packet,size_t len)
 
293
drizzleclient_net_write(NET *net,const unsigned char *packet,size_t len)
284
294
{
285
295
  unsigned char buff[NET_HEADER_SIZE];
286
296
  if (unlikely(!net->vio)) /* nowhere to write */
337
347
*/
338
348
 
339
349
bool
340
 
net_write_command(NET *net,unsigned char command,
 
350
drizzleclient_net_write_command(NET *net,unsigned char command,
341
351
                  const unsigned char *header, size_t head_len,
342
352
                  const unsigned char *packet, size_t len)
343
353
{
371
381
  buff[3]= (unsigned char) net->pkt_nr++;
372
382
  return((net_write_buff(net, buff, header_size) ||
373
383
          (head_len && net_write_buff(net, header, head_len)) ||
374
 
          net_write_buff(net, packet, len) || net_flush(net)) ? 1 : 0 );
 
384
          net_write_buff(net, packet, len) || drizzleclient_net_flush(net)) ? 1 : 0 );
375
385
}
376
386
 
377
387
/**
389
399
   @param len        Length of packet
390
400
 
391
401
   @note
392
 
   The cached buffer can be sent as it is with 'net_flush()'.
 
402
   The cached buffer can be sent as it is with 'drizzleclient_net_flush()'.
393
403
   In this code we have to be careful to not send a packet longer than
394
 
   MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
 
404
   MAX_PACKET_LENGTH to drizzleclient_net_real_write() if we are using the compressed
395
405
   protocol as we store the length of the compressed packet in 3 bytes.
396
406
 
397
407
   @retval
415
425
    {
416
426
      /* Fill up already used packet and write it */
417
427
      memcpy(net->write_pos,packet,left_length);
418
 
      if (net_real_write(net, net->buff,
 
428
      if (drizzleclient_net_real_write(net, net->buff,
419
429
                         (size_t) (net->write_pos - net->buff) + left_length))
420
430
        return 1;
421
431
      net->write_pos= net->buff;
431
441
      left_length= MAX_PACKET_LENGTH;
432
442
      while (len > left_length)
433
443
      {
434
 
        if (net_real_write(net, packet, left_length))
 
444
        if (drizzleclient_net_real_write(net, packet, left_length))
435
445
          return 1;
436
446
        packet+= left_length;
437
447
        len-= left_length;
438
448
      }
439
449
    }
440
450
    if (len > net->max_packet)
441
 
      return net_real_write(net, packet, len) ? 1 : 0;
 
451
      return drizzleclient_net_real_write(net, packet, len) ? 1 : 0;
442
452
    /* Send out rest of the blocks as full sized blocks */
443
453
  }
444
454
  memcpy(net->write_pos,packet,len);
460
470
  in the server, yield to another process and come back later.
461
471
*/
462
472
int
463
 
net_real_write(NET *net,const unsigned char *packet, size_t len)
 
473
drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len)
464
474
{
465
475
  size_t length;
466
 
  const unsigned char *pos,*end;
 
476
  const unsigned char *pos, *end;
467
477
  uint32_t retry_count= 0;
468
478
 
469
479
  /* Backup of the original SO_RCVTIMEO timeout */
470
 
#ifndef __sun
471
 
  struct timespec backtime;
472
 
  int error;
473
 
#endif
474
480
 
475
481
  if (net->error == 2)
476
482
    return(-1);                /* socket can't be used */
524
530
    packet= b;
525
531
  }
526
532
 
527
 
#ifndef __sun
528
 
  /* Check for error, currently assert */
529
 
  if (net->write_timeout)
530
 
  {
531
 
    struct timespec waittime;
532
 
    socklen_t length;
533
 
 
534
 
    waittime.tv_sec= net->write_timeout;
535
 
    waittime.tv_nsec= 0;
536
 
 
537
 
    memset(&backtime, 0, sizeof(struct timespec));
538
 
    length= sizeof(struct timespec);
539
 
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
540
 
                      &backtime, &length);
541
 
    if (error != 0)
542
 
    {
543
 
      perror("getsockopt");
544
 
      assert(error == 0);
545
 
    }
546
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
547
 
                      &waittime, (socklen_t)sizeof(struct timespec));
548
 
    assert(error == 0);
549
 
  }
550
 
#endif
551
 
 
552
533
  pos= packet;
553
534
  end=pos+len;
554
535
  /* Loop until we have read everything */
555
536
  while (pos != end)
556
537
  {
557
 
    if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
 
538
    assert(pos);
 
539
    if ((long) (length= drizzleclient_vio_write(net->vio, pos, (size_t) (end-pos))) <= 0)
558
540
    {
559
 
      const bool interrupted= vio_should_retry(net->vio);
 
541
      const bool interrupted= drizzleclient_vio_should_retry(net->vio);
560
542
      /*
561
543
        If we read 0, or we were interrupted this means that
562
544
        we need to switch to blocking mode and wait until the timeout
566
548
      {
567
549
        bool old_mode;
568
550
 
569
 
        while (vio_blocking(net->vio, true, &old_mode) < 0)
 
551
        while (drizzleclient_vio_blocking(net->vio, true, &old_mode) < 0)
570
552
        {
571
 
          if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
 
553
          if (drizzleclient_vio_should_retry(net->vio) && retry_count++ < net->retry_count)
572
554
            continue;
573
555
          net->error= 2;                     /* Close socket */
574
556
          net->last_errno= CR_NET_PACKET_TOO_LARGE;
583
565
          continue;
584
566
      }
585
567
 
586
 
      if (vio_errno(net->vio) == EINTR)
 
568
      if (drizzleclient_vio_errno(net->vio) == EINTR)
587
569
      {
588
570
        continue;
589
571
      }
593
575
      break;
594
576
    }
595
577
    pos+=length;
596
 
    update_statistics(thd_increment_bytes_sent(length));
597
578
  }
598
579
end:
599
580
  if ((net->compress) && (packet != NULL))
600
581
    free((char*) packet);
601
582
  net->reading_or_writing=0;
602
583
 
603
 
#ifndef __sun
604
 
  if (net->write_timeout)
605
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
606
 
                      &backtime, (socklen_t)sizeof(struct timespec));
607
 
#endif
608
 
 
609
584
  return(((int) (pos != end)));
610
585
}
611
586
 
612
587
 
613
588
/**
614
589
   Reads one packet to net->buff + net->where_b.
615
 
   Long packets are handled by my_net_read().
 
590
   Long packets are handled by drizzleclient_net_read().
616
591
   This function reallocates the net->buff buffer if necessary.
617
592
 
618
593
   @return
625
600
  unsigned char *pos;
626
601
  size_t length;
627
602
  uint32_t i,retry_count=0;
628
 
  uint32_t len=packet_error;
 
603
  size_t len=packet_error;
629
604
  uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
630
605
                    NET_HEADER_SIZE);
631
606
 
632
 
#ifndef __sun
633
 
  /* Backup of the original SO_RCVTIMEO timeout */
634
 
  struct timespec backtime;
635
 
  int error= 0;
636
 
#endif
637
 
 
638
607
  *complen = 0;
639
608
 
640
609
  net->reading_or_writing= 1;
641
 
  /* Read timeout is set in my_net_set_read_timeout */
 
610
  /* Read timeout is set in drizzleclient_net_set_read_timeout */
642
611
 
643
612
  pos = net->buff + net->where_b;        /* net->packet -4 */
644
613
 
645
 
 
646
 
#ifndef __sun
647
 
  /* Check for error, currently assert */
648
 
  if (net->read_timeout)
649
 
  {
650
 
    struct timespec waittime;
651
 
    socklen_t length;
652
 
 
653
 
    waittime.tv_sec= net->read_timeout;
654
 
    waittime.tv_nsec= 0;
655
 
 
656
 
    memset(&backtime, 0, sizeof(struct timespec));
657
 
    length= sizeof(struct timespec);
658
 
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
659
 
                      &backtime, &length);
660
 
    if (error != 0)
661
 
    {
662
 
      perror("getsockopt");
663
 
      assert(error == 0);
664
 
    }
665
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
666
 
                      &waittime, (socklen_t)sizeof(struct timespec));
667
 
    assert(error == 0);
668
 
  }
669
 
#endif
670
 
 
671
614
  for (i= 0; i < 2 ; i++)
672
615
  {
673
616
    while (remain > 0)
674
617
    {
675
618
      /* First read is done with non blocking mode */
676
 
      if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L)
 
619
      if ((long) (length= drizzleclient_vio_read(net->vio, pos, remain)) <= 0L)
677
620
      {
678
 
        const bool interrupted = vio_should_retry(net->vio);
 
621
        const bool interrupted = drizzleclient_vio_should_retry(net->vio);
679
622
 
680
623
        if (interrupted)
681
624
        {                    /* Probably in MIT threads */
682
625
          if (retry_count++ < net->retry_count)
683
626
            continue;
684
627
        }
685
 
        if (vio_errno(net->vio) == EINTR)
 
628
        if (drizzleclient_vio_errno(net->vio) == EINTR)
686
629
        {
687
630
          continue;
688
631
        }
689
632
        len= packet_error;
690
633
        net->error= 2;                /* Close socket */
691
 
        net->last_errno= (vio_was_interrupted(net->vio) ?
 
634
        net->last_errno= (drizzleclient_vio_was_interrupted(net->vio) ?
692
635
                          CR_NET_READ_INTERRUPTED :
693
636
                          CR_NET_READ_ERROR);
694
637
        ER(net->last_errno);
696
639
      }
697
640
      remain -= (uint32_t) length;
698
641
      pos+= length;
699
 
      update_statistics(thd_increment_bytes_received(length));
700
642
    }
701
643
    if (i == 0)
702
644
    {                    /* First parts is packet length */
725
667
      /* The necessary size of net->buff */
726
668
      if (helping >= net->max_packet)
727
669
      {
728
 
        if (net_realloc(net,helping))
 
670
        if (drizzleclient_net_realloc(net,helping))
729
671
        {
730
672
          len= packet_error;          /* Return error and close connection */
731
673
          goto end;
737
679
  }
738
680
 
739
681
end:
740
 
#ifndef __sun
741
 
  if  (net->read_timeout)
742
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
743
 
                      &backtime, (socklen_t)sizeof(struct timespec));
744
 
  assert(error == 0);
745
 
#endif
746
682
  net->reading_or_writing= 0;
747
683
 
748
684
  return(len);
766
702
*/
767
703
 
768
704
uint32_t
769
 
my_net_read(NET *net)
 
705
drizzleclient_net_read(NET *net)
770
706
{
771
707
  size_t len, complen;
772
708
 
790
726
    }
791
727
    net->read_pos = net->buff + net->where_b;
792
728
    if (len != packet_error)
793
 
      net->read_pos[len]=0;        /* Safeguard for drizzle_use_result */
 
729
      net->read_pos[len]=0;        /* Safeguard for drizzleclient_use_result */
794
730
    return len;
795
731
  }
796
732
  else
910
846
    len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
911
847
           multi_byte_packet);
912
848
    net->save_char= net->read_pos[len];    /* Must be saved */
913
 
    net->read_pos[len]=0;        /* Safeguard for drizzle_use_result */
 
849
    net->read_pos[len]=0;        /* Safeguard for drizzleclient_use_result */
914
850
  }
915
851
  return len;
916
852
  }
917
853
 
918
854
 
919
 
void my_net_set_read_timeout(NET *net, uint32_t timeout)
 
855
void drizzleclient_net_set_read_timeout(NET *net, uint32_t timeout)
920
856
{
921
857
  net->read_timeout= timeout;
922
858
#ifndef __sun
923
859
  if (net->vio)
924
 
    vio_timeout(net->vio, 0, timeout);
 
860
    drizzleclient_vio_timeout(net->vio, 0, timeout);
925
861
#endif
926
862
  return;
927
863
}
928
864
 
929
865
 
930
 
void my_net_set_write_timeout(NET *net, uint32_t timeout)
 
866
void drizzleclient_net_set_write_timeout(NET *net, uint32_t timeout)
931
867
{
932
868
  net->write_timeout= timeout;
933
869
#ifndef __sun
934
870
  if (net->vio)
935
 
    vio_timeout(net->vio, 1, timeout);
 
871
    drizzleclient_vio_timeout(net->vio, 1, timeout);
936
872
#endif
937
873
  return;
938
874
}
942
878
  @param net  clear the state of the argument
943
879
*/
944
880
 
945
 
void net_clear_error(NET *net)
 
881
void drizzleclient_drizzleclient_net_clear_error(NET *net)
946
882
{
947
883
  net->last_errno= 0;
948
884
  net->last_error[0]= '\0';
949
 
  strcpy(net->sqlstate, sqlstate_get_not_error());
 
885
  strcpy(net->sqlstate, drizzleclient_sqlstate_get_not_error());
950
886
}
951
887