Mercurial > dovecot > original-hg > dovecot-1.2
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 */ |