client buffer ##########++++++++A++++++A+++A++.......... ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | | | | | +-- end of buffer | | | | | | | | | | | +-- end of read(2) bytes | | | | | | | +-- newlines | | | +-- start of line scanning | +-- start of line # original idea - consume many lines in client__pollin - problem: in the echo server case, we want to write each line but a call to write(2) may block, so we can't do line processing in client__pollin - solution: process lines in client__pollout i = scan_start while i < buffer_end: byte = mem[i] i += 1 if byte == '\n': handle(line_start, i - line_start) line_start = i scan_start = i if line_start + read(2)_length >= buffer_end: out_of_memory() return i = line_start while i < line_start + read(2)_length: mem[i - line_start + buffer_start] = mem[i] i += 1 # better idea in pollin handler, just read once indicate to the caller: - we read a complete line (ie 0x0a is present) - we read an incomplete non-empty line - we read nothing (EOF) - error from read(2)