git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 02/10] pkt-line: add direct_packet_write() and direct_packet_write_data()

From
Lars Schneider <larsxschneider@gmail.com>
Date
Aug 1, 2016, 12:00 UTC
Message-ID
<64783AA5-D579-4783-88E7-E0B3BDE5FDEB@gmail.com>
In-Reply-To
<58e4737b-6e0e-565c-2468-05c705dea426@gmail.com>
Show 25 quoted lines
> On 30 Jul 2016, at 12:49, Jakub Narębski <jnareb@gmail.com> wrote:
> 
> W dniu 30.07.2016 o 01:37, larsxschneider@gmail.com pisze:
>> From: Lars Schneider <larsxschneider@gmail.com>
>> 
>> Sometimes pkt-line data is already available in a buffer and it would
>> be a waste of resources to write the packet using packet_write() which
>> would copy the existing buffer into a strbuf before writing it.
>> 
>> If the caller has control over the buffer creation then the
>> PKTLINE_DATA_START macro can be used to skip the header and write
>> directly into the data section of a pkt-line (PKTLINE_DATA_LEN bytes
>> would be the maximum). direct_packet_write() would take this buffer,
>> adjust the pkt-line header and write it.
>> 
>> If the caller has no control over the buffer creation then
>> direct_packet_write_data() can be used. This function creates a pkt-line
>> header. Afterwards the header and the data buffer are written using two
>> consecutive write calls.
> 
> I don't quite understand what do you mean by "caller has control
> over the buffer creation".  Do you mean that caller either can write
> over the buffer, or cannot overwrite the buffer?  Or do you mean that
> caller either can allocate buffer to hold header, or is getting
> only the data?
How about this:
[...]

If the caller creates the buffer then a proper pkt-line buffer with header and data section can be created. The PKTLINE_DATA_START macro can be used to skip the header section and write directly to the data section (PKTLINE_DATA_LEN bytes would be the maximum). direct_packet_write() would take this buffer, fill the pkt-line header section with the appropriate data length value and write the entire buffer.

If the caller does not create the buffer, and consequently cannot leave room for the pkt-line header, then direct_packet_write_data() can be used. This function creates an extra buffer for the pkt-line header and afterwards writes the header buffer and the data buffer with two consecutive write calls.

--- Is that more clear?

Show 9 quoted lines
> 
>> 
>> Both functions have a gentle parameter that indicates if Git should die
>> in case of a write error (gentle set to 0) or return with a error (gentle
>> set to 1).
> 
> So they are *_maybe_gently(), isn't it ;-)?  Are there any existing
> functions in Git codebase that take 'gently' / 'strict' / 'die_on_error'
> parameter?
Yes, git grep "gentle" reveals:

wrapper.c:static int memory_limit_check(size_t size, int gentle) object.c:int type_from_string_gently(const char *str, ssize_t len, int gentle)

Show 39 quoted lines
>> 
>> Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
>> ---
>> pkt-line.c | 30 ++++++++++++++++++++++++++++++
>> pkt-line.h |  5 +++++
>> 2 files changed, 35 insertions(+)
>> 
>> diff --git a/pkt-line.c b/pkt-line.c
>> index 445b8e1..6fae508 100644
>> --- a/pkt-line.c
>> +++ b/pkt-line.c
>> @@ -135,6 +135,36 @@ void packet_write(int fd, const char *fmt, ...)
>> 	write_or_die(fd, buf.buf, buf.len);
>> }
>> 
>> +int direct_packet_write(int fd, char *buf, size_t size, int gentle)
>> +{
>> +	int ret = 0;
>> +	packet_trace(buf + 4, size - 4, 1);
>> +	set_packet_header(buf, size);
>> +	if (gentle)
>> +		ret = !write_or_whine_pipe(fd, buf, size, "pkt-line");
>> +	else
>> +		write_or_die(fd, buf, size);
> 
> Hmmm... in gently case we get the information in the warning that
> it is about "pkt-line", which is missing from !gently case.  But
> it is probably not important.
> 
>> +	return ret;
>> +}
> 
> Nice clean function, thanks to extracting set_packet_header().
> 
>> +
>> +int direct_packet_write_data(int fd, const char *buf, size_t size, int gentle)
> 
> I would name the parameter 'data', rather than 'buf'; IMVHO it
> better describes it.
Agreed!
Show 12 quoted lines
> 
>> +{
>> +	int ret = 0;
>> +	char hdr[4];
>> +	set_packet_header(hdr, sizeof(hdr) + size);
>> +	packet_trace(buf, size, 1);
>> +	if (gentle) {
>> +		ret = (
>> +			!write_or_whine_pipe(fd, hdr, sizeof(hdr), "pkt-line header") ||
> 
> You can write '4' here, no need for sizeof(hdr)... though compiler would
> optimize it away.

Right, it would be optimized. However, I don't like the 4 there either. OK to use a macro instead? PKTLINE_HEADER_LEN ?

Show 10 quoted lines
>> +			!write_or_whine_pipe(fd, buf, size, "pkt-line data")
>> +		);
> 
> Do we want to try to write "pkt-line data" if "pkt-line header" failed?
> If not, perhaps De Morgan-ize it
> 
>  +		ret = !(
>  +			write_or_whine_pipe(fd, hdr, sizeof(hdr), "pkt-line header") &&
>  +			write_or_whine_pipe(fd, buf, size, "pkt-line data")
>  +		);
Original:
		ret = (
			!write_or_whine_pipe(fd, hdr, sizeof(hdr), "pkt-line header") ||
			!write_or_whine_pipe(fd, data, size, "pkt-line data")
		);

Well, if the first write call fails (return == 0), then it is negated and evaluates to true. I would think the second call is not evaluated, then?!

CPP reference: "For the built-in logical OR operator, the result is true if either the first or the second operand (or both) is true. If the firstoperand is true, the second operand is not evaluated." http://en.cppreference.com/w/cpp/language/operator_logical

Should I make this more explicit with a if clause?
 
Show 5 quoted lines
>> +	} else {
>> +		write_or_die(fd, hdr, sizeof(hdr));
>> +		write_or_die(fd, buf, size);
> 
> I guess these two writes (here and in 'gently' case) are unavoidable...
I think so, too.
Show 31 quoted lines
> 
>> +	}
>> +	return ret;
>> +}
>> +
>> void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
>> {
>> 	va_list args;
>> diff --git a/pkt-line.h b/pkt-line.h
>> index 3cb9d91..02dcced 100644
>> --- a/pkt-line.h
>> +++ b/pkt-line.h
>> @@ -23,6 +23,8 @@ void packet_flush(int fd);
>> void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
>> void packet_buf_flush(struct strbuf *buf);
>> void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
>> +int direct_packet_write(int fd, char *buf, size_t size, int gentle);
>> +int direct_packet_write_data(int fd, const char *buf, size_t size, int gentle);
>> 
>> /*
>>  * Read a packetized line into the buffer, which must be at least size bytes
>> @@ -77,6 +79,9 @@ char *packet_read_line_buf(char **src_buf, size_t *src_len, int *size);
>> 
>> #define DEFAULT_PACKET_MAX 1000
>> #define LARGE_PACKET_MAX 65520
>> +#define PKTLINE_HEADER_LEN 4
>> +#define PKTLINE_DATA_START(pkt) ((pkt) + PKTLINE_HEADER_LEN)
>> +#define PKTLINE_DATA_LEN (LARGE_PACKET_MAX - PKTLINE_HEADER_LEN)
> 
> Those are not used in direct_packet_write() and direct_packet_write_data();
> but they would make them more verbose and less readable.
Good point, I should use them to check for the maximal packet length!

Thanks, Lars

Show 6 quoted lines
> 
>> extern char packet_buffer[LARGE_PACKET_MAX];
>> 
>> #endif
>> 
> 
Previous: Jakub NarębskiNext: Jakub Narębski
Message 9 of 100 in “Git filter protocol”
  1. 00/10 Git filter protocollarsxschneider@gmail.com, Jul 29, 2016
  2. 01/10 pkt-line: extract set_packet_header()larsxschneider@gmail.com, Jul 29, 2016
  3. Jakub NarębskiJul 30, 2016
  4. Lars SchneiderAug 1, 2016
  5. Jakub NarębskiAug 3, 2016
  6. Lars SchneiderAug 5, 2016
  7. 02/10 pkt-line: add direct_packet_write() and direct_packet_write_data()larsxschneider@gmail.com, Jul 29, 2016
  8. Jakub NarębskiJul 30, 2016
  9. Lars SchneiderAug 1, 2016
  10. Jakub NarębskiAug 3, 2016
  11. Lars SchneiderAug 5, 2016
  12. 03/10 pkt-line: add packet_flush_gentle()larsxschneider@gmail.com, Jul 29, 2016
  13. Jakub NarębskiJul 30, 2016
  14. Lars SchneiderAug 1, 2016
  15. Torstem BögershausenJul 31, 2016
  16. Lars SchneiderJul 31, 2016
  17. Torsten BögershausenAug 2, 2016
  18. Lars SchneiderAug 5, 2016
  19. 04/10 pkt-line: call packet_trace() only if a packet is actually sendlarsxschneider@gmail.com, Jul 29, 2016
  20. Jakub NarębskiJul 30, 2016
  21. Lars SchneiderAug 1, 2016
  22. Jakub NarębskiAug 3, 2016
  23. 05/10 pack-protocol: fix maximum pkt-line sizelarsxschneider@gmail.com, Jul 29, 2016
  24. Jakub NarębskiJul 30, 2016
  25. Lars SchneiderAug 1, 2016
  26. 07/10 convert: quote filter names in error messageslarsxschneider@gmail.com, Jul 29, 2016
  27. 06/10 run-command: add clean_on_exit_handlerlarsxschneider@gmail.com, Jul 29, 2016
  28. Johannes SixtJul 30, 2016
  29. Lars SchneiderAug 1, 2016
  30. Johannes SixtAug 2, 2016
  31. Lars SchneiderAug 2, 2016
  32. 08/10 convert: modernize testslarsxschneider@gmail.com, Jul 29, 2016
  33. 09/10 convert: generate large test files only oncelarsxschneider@gmail.com, Jul 29, 2016
  34. 10/10 convert: add filter.<driver>.process optionlarsxschneider@gmail.com, Jul 29, 2016
  35. Jakub NarębskiJul 30, 2016
  36. Jakub NarębskiJul 31, 2016
  37. Lars SchneiderJul 31, 2016
  38. Jakub NarębskiJul 31, 2016
  39. Lars SchneiderAug 1, 2016
  40. Designing the filter process protocol (was: Re: [PATCH v3 10/10] convert: add filter.<driver>.process option)Jakub Narębski, Aug 3, 2016
  41. Lars SchneiderAug 5, 2016
  42. Lars SchneiderAug 6, 2016
  43. Jakub NarębskiAug 3, 2016
  44. Jakub NarębskiJul 31, 2016
  45. Lars SchneiderAug 1, 2016
  46. Jakub NarębskiAug 4, 2016
  47. Lars SchneiderAug 3, 2016
  48. Jakub NarębskiAug 4, 2016
  49. Lars SchneiderAug 5, 2016
  50. 00/12 Git filter protocollarsxschneider@gmail.com, Aug 3, 2016
  51. 01/12 pkt-line: extract set_packet_header()larsxschneider@gmail.com, Aug 3, 2016
  52. Junio C HamanoAug 3, 2016
  53. Jeff KingAug 3, 2016
  54. Jeff KingAug 3, 2016
  55. Junio C HamanoAug 4, 2016
  56. Lars SchneiderAug 5, 2016
  57. Junio C HamanoAug 5, 2016
  58. Lars SchneiderAug 5, 2016
  59. Junio C HamanoAug 5, 2016
  60. Lars SchneiderAug 3, 2016
  61. 07/12 run-command: add clean_on_exit_handlerlarsxschneider@gmail.com, Aug 3, 2016
  62. Jeff KingAug 3, 2016
  63. Lars SchneiderAug 3, 2016
  64. Jeff KingAug 3, 2016
  65. Lars SchneiderAug 3, 2016
  66. Jeff KingAug 3, 2016
  67. Lars SchneiderAug 5, 2016
  68. Torsten BögershausenAug 5, 2016
  69. Lars SchneiderAug 5, 2016
  70. 03/12 pkt-line: add packet_flush_gentle()larsxschneider@gmail.com, Aug 3, 2016
  71. Jeff KingAug 3, 2016
  72. Junio C HamanoAug 4, 2016
  73. 02/12 pkt-line: add direct_packet_write() and direct_packet_write_data()larsxschneider@gmail.com, Aug 3, 2016
  74. 08/12 convert: quote filter names in error messageslarsxschneider@gmail.com, Aug 3, 2016
  75. 05/12 pkt-line: add functions to read/write flush terminated packet streamslarsxschneider@gmail.com, Aug 3, 2016
  76. 09/12 convert: modernize testslarsxschneider@gmail.com, Aug 3, 2016
  77. 12/12 convert: add filter.<driver>.process shutdown command optionlarsxschneider@gmail.com, Aug 3, 2016
  78. 06/12 pack-protocol: fix maximum pkt-line sizelarsxschneider@gmail.com, Aug 3, 2016
  79. 04/12 pkt-line: call packet_trace() only if a packet is actually sendlarsxschneider@gmail.com, Aug 3, 2016
  80. 11/12 convert: add filter.<driver>.process optionlarsxschneider@gmail.com, Aug 3, 2016
  81. Junio C HamanoAug 3, 2016
  82. Lars SchneiderAug 3, 2016
  83. Jeff KingAug 3, 2016
  84. Lars SchneiderAug 5, 2016
  85. Junio C HamanoAug 3, 2016
  86. Lars SchneiderAug 3, 2016
  87. Junio C HamanoAug 3, 2016
  88. Lars SchneiderAug 3, 2016
  89. Torsten BögershausenAug 5, 2016
  90. Lars SchneiderAug 5, 2016
  91. Junio C HamanoAug 5, 2016
  92. Jeff KingAug 5, 2016
  93. Lars SchneiderAug 6, 2016
  94. Jeff KingAug 6, 2016
  95. Lars SchneiderAug 6, 2016
  96. Jeff KingAug 8, 2016
  97. Lars SchneiderAug 8, 2016
  98. Jeff KingAug 8, 2016
  99. Torsten BögershausenAug 6, 2016
  100. 10/12 convert: generate large test files only oncelarsxschneider@gmail.com, Aug 3, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.