Show
Ignore:
Timestamp:
08/14/10 20:42:42 (22 months ago)
Author:
Antti-Juhani Kaijanaho <antti-juhani@…>
Children:
994811461679afe70ab81e079fd87191d609be9d
Parents:
61975465b66e572def6105480f10917981b1ef0d
git-committer:
Antti-Juhani Kaijanaho <antti-juhani@…> (08/14/10 20:42:42)
Message:

[tls::session] Use ring buffers instead of dynamically growing buffers

This way enbuffering cannot throw bad_alloc.

Closes #69.

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • tls/session_impl.hh

    rae733bf r08f5bd7  
    6666        ssize_t session_impl<Stream>::push(const void *b, size_t n) 
    6767        { 
    68                 const unsigned char *cs = static_cast<const unsigned char *>(b); 
    69                 for (size_t i = 0; i < n; i++) 
    70                 { 
    71                         outs.push_back(cs[i]); 
    72                 } 
    73                 return n; 
     68                if (outs.full()) 
     69                { 
     70                        errno = EAGAIN; 
     71                        return -1; 
     72                } 
     73                return outs.put(static_cast<const unsigned char *>(b), n); 
    7474        } 
    7575 
    7676        /* never call directly!  (called by gnutls) */ 
    7777        template <typename Stream> 
    78         ssize_t session_impl<Stream>::pull(void *b, size_t n_wanted) 
    79         { 
    80                 unsigned char *cs = static_cast<unsigned char *>(b); 
    81                 if (ins_high - ins_low > 0) 
    82                 { 
    83                         size_t n = ins_high - ins_low < n_wanted  
    84                                 ?  ins_high - ins_low  
    85                                 :  n_wanted; 
    86                         for (size_t i = 0; i < n; i++) 
    87                         { 
    88                                 cs[i] = ins[ins_low+i]; 
    89                         } 
    90                         ins_low += n; 
    91                         return n; 
    92                 } 
    93                 errno = EAGAIN; 
    94                 return -1; 
     78        ssize_t session_impl<Stream>::pull(void *b, size_t n) 
     79        { 
     80                if (ins.empty()) 
     81                { 
     82                        errno = EAGAIN; 
     83                        return -1; 
     84                } 
     85                return ins.get(static_cast<unsigned char *>(b), n); 
    9586        } 
    9687 
     
    9990        { 
    10091                if (write_active) return; 
    101                 if (outs_low > 0 && outs_low == outs.size()) 
    102                 { 
    103                         outs.clear(); 
    104                         outs_low = 0; 
    105                 } 
    106                 else if (outs_low > 4096) 
    107                 { 
    108                         outs.erase(outs.begin(), outs.begin() + outs_low); 
    109                         outs_low = 0; 
    110                 } 
    111                 if (outs_low < outs.size()) 
     92                if (!outs.empty()) 
    11293                { 
    11394                        stream.async_write_some 
    114                                 (boost::asio::buffer(outs.data()+outs_low, 
    115                                                      outs.size()-outs_low), 
     95                                (outs.read_area(), 
    11696                                 strand.wrap(boost::bind 
    11797                                             (&sent_some, 
     
    126106        { 
    127107                if (read_active) return; 
    128                 if (ins_low > 0 && ins_low == ins.size()) 
    129                 { 
    130                         ins.clear(); 
    131                         ins_low = 0; 
    132                         ins_high = 0; 
    133                 } 
    134                 else if (ins_low > 4096) 
    135                 { 
    136                         ins.erase(ins.begin(), ins.begin() + ins_low); 
    137                         ins_high -= ins_low; 
    138                         ins_low = 0; 
    139                 } 
    140  
    141                 if (ins_high + 4096 >= ins.size()) ins.resize(ins_high + 4096); 
    142108                stream.async_read_some 
    143                         (boost::asio::buffer(ins.data()+ins_high, 
    144                                              ins.size()-ins_high), 
     109                        (ins.write_area(), 
    145110                         strand.wrap(boost::bind 
    146111                                     (&received_some, this->shared_from_this(), 
     
    171136                self->read_active = false; 
    172137                if (ec == boost::asio::error::operation_aborted) return; 
    173                 if (ec) self->pending_error = ec; else self->ins_high += n; 
     138                if (ec) self->pending_error = ec; else self->ins.written(n); 
    174139                self->post_pending_actions(); 
    175140        } 
     
    183148                if (ec == boost::asio::error::operation_aborted) return; 
    184149                if (ec) { self->pending_error = ec; return; } 
    185                 self->outs_low += n; 
     150                self->outs.read(n); 
    186151                self->post_pending_actions(); 
    187152        }