src/Network/Buffer.cc
changeset 378 5589abf5e61b
parent 329 42ad4965424f
child 380 d193dd1d8a7e
equal deleted inserted replaced
377:01d3c340b372 378:5589abf5e61b
     6 #include <cstdlib>
     6 #include <cstdlib>
     7 
     7 
     8 /*
     8 /*
     9  * NetworkBufferBase
     9  * NetworkBufferBase
    10  */
    10  */
    11 NetworkBufferBase::NetworkBufferBase (NetworkSocket &socket, size_t size_hint) :
    11 NetworkBufferBase::NetworkBufferBase (NetworkSocket *socket, size_t size_hint) :
    12     socket(socket), buf(0), size(0), offset(0) {
    12     socket(socket), buf(0), size(0), offset(0) {
    13     
    13     
    14     // allocate initial buffer
    14     // allocate initial buffer
    15     if ((buf = (char *) malloc(size_hint)) == NULL)
    15     if ((buf = (char *) malloc(size_hint)) == NULL)
    16        throw NetworkBufferError("malloc failed");
    16        throw NetworkBufferError("malloc failed");
    57 }
    57 }
    58 
    58 
    59 /*
    59 /*
    60  * NetworkBufferInput
    60  * NetworkBufferInput
    61  */
    61  */
    62 NetworkBufferInput::NetworkBufferInput (NetworkSocket &socket, size_t size_hint) :
    62 NetworkBufferInput::NetworkBufferInput (NetworkSocket *socket, size_t size_hint) :
    63     NetworkBufferBase(socket, size_hint)
    63     NetworkBufferBase(socket, size_hint)
    64 {
    64 {
    65 
    65 
    66 }
    66 }
    67 
    67 
    68 bool NetworkBufferInput::try_read (size_t item_size) {
    68 bool NetworkBufferInput::try_read (size_t item_size) {
    69     int ret;
    69     size_t ret, to_read = item_size;
    70     size_t to_read = item_size;
       
    71 
    70 
    72     // keept reads at at least NETWORK_BUFFER_CHUNK_SIZE bytes
    71     // keept reads at at least NETWORK_BUFFER_CHUNK_SIZE bytes
    73     if (to_read < NETWORK_BUFFER_CHUNK_SIZE)
    72     if (to_read < NETWORK_BUFFER_CHUNK_SIZE)
    74         to_read = NETWORK_BUFFER_CHUNK_SIZE;
    73         to_read = NETWORK_BUFFER_CHUNK_SIZE;
    75 
    74 
    76     // resize buffer if needed
    75     // resize buffer if needed
    77     resize(to_read);
    76     resize(to_read);
    78 
    77 
    79     // read once
    78     // read once
    80     try {
    79     ret = socket->recv(buf + offset, to_read);
    81         ret = socket.recv(buf + offset, to_read);
       
    82 
    80 
    83     } catch (CL_Error &e) {
    81     // nothing left?
    84         if (errno == EAGAIN)
       
    85             return false;
       
    86 
       
    87         else
       
    88             throw NetworkSocketOSError(socket, "recv");
       
    89     }
       
    90     
       
    91     // handle EOF
       
    92     if (ret == 0)
    82     if (ret == 0)
    93         throw NetworkSocketEOFError(socket, "recv");
    83         return false;
    94 
       
    95     assert(ret >= 0);
       
    96 
    84 
    97     // update offset
    85     // update offset
    98     offset += ret;
    86     offset += ret;
    99 
    87 
   100     // did we get enough?
    88     // did we get enough?
   127 }
   115 }
   128    
   116    
   129 /*
   117 /*
   130  * NetworkBufferOutput
   118  * NetworkBufferOutput
   131  */
   119  */
   132 NetworkBufferOutput::NetworkBufferOutput (NetworkSocket &socket, size_t size_hint) :
   120 NetworkBufferOutput::NetworkBufferOutput (NetworkSocket *socket, size_t size_hint) :
   133     NetworkBufferBase(socket, size_hint)
   121     NetworkBufferBase(socket, size_hint)
   134 {
   122 {
   135 
   123 
   136 }
   124 }
   137 
   125 
   138 
   126 
   139 void NetworkBufferOutput::push_write (char *buf_ptr, size_t buf_size) {
   127 void NetworkBufferOutput::push_write (char *buf_ptr, size_t buf_size) {
   140     int ret;
   128     size_t ret;
   141 
   129 
   142     // try and short-circuit writes unless we have already buffered data
   130     // try and short-circuit writes unless we have already buffered data
   143     if (offset == 0) {
   131     if (offset == 0) {
   144         try {
   132         // attempt to send something
   145             // attempt to send something
   133         ret = socket->send(buf_ptr, buf_size);
   146             ret = socket.send(buf_ptr, buf_size);
       
   147 
   134 
   148         } catch (CL_Error &e) {
       
   149             // ignore EAGAIN, detect this by setting ret to -1
       
   150             if (errno != EAGAIN)
       
   151                 throw NetworkSocketOSError(socket, "send");
       
   152 
       
   153             ret = -1;
       
   154         }
       
   155         
       
   156         // if we managed to send something, adjust buf/size and buffer
   135         // if we managed to send something, adjust buf/size and buffer
   157         if (ret > 0) {
   136         if (ret > 0) {
   158             // sanity-check
   137             // sanity-check
   159             assert(buf_size >= (unsigned int) ret);
   138             assert(buf_size >= (unsigned int) ret);
   160 
   139 
   173     // copy into our internal buffer
   152     // copy into our internal buffer
   174     memcpy(buf + offset, buf_ptr, buf_size);
   153     memcpy(buf + offset, buf_ptr, buf_size);
   175 }
   154 }
   176         
   155         
   177 void NetworkBufferOutput::flush_write (void) {
   156 void NetworkBufferOutput::flush_write (void) {
   178     int ret;
   157     size_t ret;
   179 
   158 
   180     // ignore if we don't have any data buffered
   159     // ignore if we don't have any data buffered
   181     if (offset == 0)
   160     if (offset == 0)
   182         return;
   161         return;
   183     
   162     
   184     // attempt to write as much as possible
   163     // attempt to write as much as possible
   185     try {
   164     ret = socket->send(buf, offset);
   186         ret = socket.send(buf, offset);
       
   187 
   165 
   188     } catch (CL_Error &e) {
   166     // busy?
   189         // ignore EAGAIN and just return
   167     if (ret == 0)
   190         if (errno == EAGAIN)
   168         return;
   191             return;
       
   192 
       
   193         else
       
   194             throw NetworkSocketOSError(socket, "send");
       
   195     }
       
   196 
   169 
   197     // trim the buffer
   170     // trim the buffer
   198     trim(ret);
   171     trim(ret);
   199 }
   172 }
   200         
   173