comparison src/lib/iobuffer.c @ 122:9b87ee7cc19f HEAD

If we're corked, try to buffer the data instead of immediately trying to write it. But is less syscalls faster than memcpy()ing?..
author Timo Sirainen <tss@iki.fi>
date Mon, 02 Sep 2002 23:23:32 +0300
parents a73e43fa20e0
children 788d8536ee18
comparison
equal deleted inserted replaced
121:f9522c8629b8 122:9b87ee7cc19f
367 367
368 void io_buffer_cork(IOBuffer *buf) 368 void io_buffer_cork(IOBuffer *buf)
369 { 369 {
370 i_assert(!buf->receive); 370 i_assert(!buf->receive);
371 371
372 if (!buf->file && !buf->corked) { 372 if (!buf->file && !buf->corked)
373 net_set_cork(buf->fd, TRUE); 373 net_set_cork(buf->fd, TRUE);
374 buf->corked = TRUE; 374 buf->corked = TRUE;
375 }
376 } 375 }
377 376
378 static void buffer_alloc_more(IOBuffer *buf, unsigned int size) 377 static void buffer_alloc_more(IOBuffer *buf, unsigned int size)
379 { 378 {
380 i_assert(!buf->mmaped); 379 i_assert(!buf->mmaped);
408 buf->skip = 0; 407 buf->skip = 0;
409 } 408 }
410 409
411 int io_buffer_send(IOBuffer *buf, const void *data, unsigned int size) 410 int io_buffer_send(IOBuffer *buf, const void *data, unsigned int size)
412 { 411 {
413 int ret; 412 int i, corked, ret;
414 413
415 i_assert(!buf->receive); 414 i_assert(!buf->receive);
416 i_assert(data != NULL); 415 i_assert(data != NULL);
417 i_assert(size < INT_MAX); 416 i_assert(size < INT_MAX);
418 buf->transmit = TRUE; 417 buf->transmit = TRUE;
419 418
420 if (buf->closed) 419 if (buf->closed)
421 return -1; 420 return -1;
422 421
423 if (buf->pos == 0) { 422 /* if we're corked, first try adding it to buffer. if it's larger
424 /* buffer is empty, try to send the data immediately */ 423 than the buffer, send it immediately. */
425 ret = buf->file ? my_write(buf->fd, data, size) : 424 corked = buf->corked;
426 net_transmit(buf->fd, data, size); 425 for (i = 0; i < 2; i++) {
427 if (ret < 0) { 426 if (buf->pos == 0 && !corked) {
428 /* disconnected */ 427 /* buffer is empty, try to send the data immediately */
429 buf->closed = TRUE; 428 ret = buf->file ? my_write(buf->fd, data, size) :
430 return -1; 429 net_transmit(buf->fd, data, size);
431 } 430 if (ret < 0) {
432 431 /* disconnected */
433 buf->offset += ret; 432 buf->closed = TRUE;
434 data = (const char *) data + ret; 433 return -1;
435 size -= ret; 434 }
436 } 435
437 436 buf->offset += ret;
438 if (size == 0) { 437 data = (const char *) data + ret;
439 /* all sent */ 438 size -= ret;
440 return 1; 439 }
441 } 440
442 441 if (size == 0) {
443 if (io_buffer_get_space(buf, size) == NULL) { 442 /* all sent */
444 if (buf->blocking) { 443 return 1;
445 /* if we don't have space, we block */ 444 }
446 return io_buffer_send_blocking(buf, data, size); 445
447 } 446 if (io_buffer_get_space(buf, size) != NULL)
448 return -2; 447 break;
448
449 if (corked)
450 corked = FALSE;
451 else {
452 if (buf->blocking) {
453 /* if we don't have space, we block */
454 return io_buffer_send_blocking(buf, data, size);
455 }
456 return -2;
457 }
449 } 458 }
450 459
451 /* add to buffer */ 460 /* add to buffer */
452 memcpy(buf->buffer + buf->pos, data, size); 461 memcpy(buf->buffer + buf->pos, data, size);
453 buf->pos += size; 462 buf->pos += size;
875 int ret; 884 int ret;
876 885
877 i_assert(size <= INT_MAX); 886 i_assert(size <= INT_MAX);
878 i_assert(!buf->receive); 887 i_assert(!buf->receive);
879 888
880 if (buf->pos == 0) { 889 if (buf->pos == 0 && !buf->corked) {
881 /* buffer is empty, try to send the data immediately */ 890 /* buffer is empty, try to send the data immediately */
882 ret = buf->file ? my_write(buf->fd, buf->buffer, size) : 891 ret = buf->file ? my_write(buf->fd, buf->buffer, size) :
883 net_transmit(buf->fd, buf->buffer, size); 892 net_transmit(buf->fd, buf->buffer, size);
884 if (ret < 0) { 893 if (ret < 0) {
885 /* disconnected */ 894 /* disconnected */