rewrite client__pollout
algorithm: 1. call client__pollout__before_fresh_lines 2. if error, return 3. find line length 4. if no line, set POLLIN and goto 8 5. call client__pollout__line 6. if error, goto 7 7. finished with this line; goto 3 8. move the final incomplete line to the start of the client's buffer 9. return
This commit is contained in:
parent
c16c82b15f
commit
fc1cc26b0f
2 changed files with 194 additions and 42 deletions
221
client.s
221
client.s
|
@ -70,83 +70,226 @@ client__pollin__line_too_long:
|
|||
jmp client__pollin__return
|
||||
|
||||
|
||||
; Returns:
|
||||
; rax - non-negative from write(2)
|
||||
; Errors:
|
||||
; rax - -1024 - no line was buffered
|
||||
; rax - other negative - from write(2)
|
||||
; rax - negative or zero - from write(2)
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - address of client within clients array
|
||||
; rdx - pollfds index
|
||||
; Variables:
|
||||
; rbp - fd
|
||||
; rbx - pollfds index
|
||||
; r12 - address of client within clients array
|
||||
; r13 - line length
|
||||
; r11 - client buffer end of text after call to write(2)
|
||||
; r13 - line start
|
||||
; r14 - line end
|
||||
; r15 - client buffer end
|
||||
; r11 - client buffer, length of last incomplete line
|
||||
client__pollout:
|
||||
push rbp
|
||||
push rbx
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
mov rbp, rdi
|
||||
mov rbx, rdx
|
||||
mov r12, rsi
|
||||
mov r13, rsi
|
||||
add r13, OFFSET_CLIENT_BUFFER
|
||||
mov r15, r13
|
||||
add r15, 255
|
||||
|
||||
push rdi
|
||||
mov rdi, r12
|
||||
add rdi, OFFSET_CLIENT_BUFFER
|
||||
mov rsi, 255
|
||||
call scanline
|
||||
pop rdi
|
||||
|
||||
; poll(2)'d for POLLOUT but we had no line buffered;
|
||||
; should be impossible
|
||||
cmp rax, 0
|
||||
je client__pollout__no_line
|
||||
|
||||
mov r13, rax
|
||||
|
||||
mov rax, SYS_WRITE
|
||||
mov rdi, rbp
|
||||
mov rsi, r12
|
||||
add rsi, OFFSET_CLIENT_BUFFER
|
||||
mov rdx, r13
|
||||
syscall
|
||||
call client__pollout__before_fresh_lines
|
||||
|
||||
; error from write(2)
|
||||
cmp rax, 0
|
||||
jl client__pollout__return
|
||||
jle client__pollout__return
|
||||
|
||||
mov r10, r12
|
||||
client__pollout__scan:
|
||||
mov rdi, r13
|
||||
mov rsi, 0
|
||||
mov sil, [r12 + OFFSET_CLIENT_BUFFER_LEN]
|
||||
call scanline
|
||||
|
||||
cmp rax, 0
|
||||
jle client__pollout__set_pollin ; no lines left
|
||||
|
||||
sub [r12 + OFFSET_CLIENT_BUFFER_LEN], al
|
||||
|
||||
; line_end = line_start + line_len
|
||||
mov r14, r13
|
||||
add r14, rax
|
||||
|
||||
mov rdi, rbp
|
||||
mov rsi, r12
|
||||
mov rdx, r13
|
||||
mov rcx, r14
|
||||
sub rcx, r13
|
||||
call client__pollout__line
|
||||
|
||||
mov r13, r14
|
||||
|
||||
cmp rax, 0
|
||||
jle client__pollout__shunt
|
||||
jmp client__pollout__scan
|
||||
|
||||
client__pollout__set_pollin:
|
||||
mov word [pollfds + rbx * pollfd_size + 4], POLLIN
|
||||
mov rax, 1
|
||||
|
||||
client__pollout__shunt:
|
||||
mov r10, 0
|
||||
mov r11, 0
|
||||
mov r11b, [r12 + OFFSET_CLIENT_BUFFER_LEN]
|
||||
add r11, r12
|
||||
sub r11, rax
|
||||
add r11, OFFSET_CLIENT_BUFFER
|
||||
sub r11, r13
|
||||
|
||||
client__pollout__shunt:
|
||||
client__pollout__shunt__loop:
|
||||
cmp r10, r11
|
||||
jge client__pollout__shunt__finished
|
||||
mov r8b, [r10 + rax]
|
||||
mov r8b, [r10 + r13]
|
||||
mov [r10], r8b
|
||||
add r10, 1
|
||||
jmp client__pollout__shunt
|
||||
jmp client__pollout__shunt__loop
|
||||
|
||||
client__pollout__shunt__finished:
|
||||
; buffer_len -= rax
|
||||
sub [r12 + OFFSET_CLIENT_BUFFER_LEN], al
|
||||
cmp rax, r13
|
||||
jl client__pollout__return
|
||||
mov word [pollfds + rbx * pollfd_size + 4], POLLIN
|
||||
mov r10, r13
|
||||
sub r10, r12
|
||||
sub r10, OFFSET_CLIENT_BUFFER
|
||||
|
||||
client__pollout__return:
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbx
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
client__pollout__no_line:
|
||||
mov rax, -1024
|
||||
jmp client__pollout__return
|
||||
; Errors:
|
||||
; rax - -1024 - some scratch buffer bytes remain, stop write(2)ing
|
||||
; rax - other negative or zero - from write(2)
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - address of client within clients array
|
||||
client__pollout__before_fresh_lines:
|
||||
mov rdx, 0
|
||||
mov dl, [rsi + OFFSET_CLIENT_SCRATCH_LEN]
|
||||
|
||||
cmp rdx, 0
|
||||
jle client__pollout__before_fresh_lines__return__succ
|
||||
|
||||
mov rax, SYS_WRITE
|
||||
push rdx
|
||||
add rsi, OFFSET_CLIENT_SCRATCH
|
||||
push rsi
|
||||
syscall
|
||||
|
||||
pop rsi
|
||||
pop rdx
|
||||
|
||||
cmp rax, 0
|
||||
jle return
|
||||
|
||||
sub [rsi - OFFSET_CLIENT_SCRATCH + OFFSET_CLIENT_SCRATCH_LEN], al
|
||||
|
||||
mov r10, rsi
|
||||
mov r11, rsi
|
||||
add r11, rdx
|
||||
sub r11, rax
|
||||
|
||||
client__pollout__before_fresh_lines__shunt:
|
||||
cmp r10, r11
|
||||
jge client__pollout__before_fresh_lines__return
|
||||
mov r8b, [r10 + rax]
|
||||
mov [r10], r8b
|
||||
add r10, 1
|
||||
jmp client__pollout__before_fresh_lines__shunt
|
||||
|
||||
client__pollout__before_fresh_lines__return:
|
||||
cmp rax, rdx
|
||||
jl client__pollout__before_fresh_lines__return__fail
|
||||
|
||||
client__pollout__before_fresh_lines__return__succ:
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
client__pollout__before_fresh_lines__return__fail:
|
||||
mov rax, -1024
|
||||
ret
|
||||
|
||||
; Errors:
|
||||
; rax - negative or zero - from write(2)
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - address of client within clients array
|
||||
; rdx - line start
|
||||
; rcx - line length
|
||||
; Variables:
|
||||
; rsi - client scratch
|
||||
; r10 - line write(2) end
|
||||
; r9 - line end
|
||||
; Assumptions:
|
||||
; scratch is empty, bc it was emptied by client__pollout__before_fresh_lines
|
||||
; we must deal with the whole line we are given
|
||||
client__pollout__line:
|
||||
; TODO we've got a line
|
||||
; - try writing it
|
||||
; - if socket is fucked: return
|
||||
; - if ok: cool
|
||||
; - if couldn't do the whole thing: you have scratch available, if it's needed for the protocol
|
||||
|
||||
push rdx
|
||||
push rcx
|
||||
|
||||
mov rax, SYS_WRITE
|
||||
mov rsi, rdx
|
||||
mov rdx, rcx
|
||||
syscall
|
||||
|
||||
pop rcx
|
||||
pop rdx
|
||||
|
||||
; TODO continue here also not sure calling fn is correct yet
|
||||
; check that changes to server.s haven't fucked anything up
|
||||
|
||||
; error from write(2)
|
||||
cmp rax, 0
|
||||
jl client__pollout__line__error
|
||||
|
||||
cmp rax, rcx
|
||||
jl client__pollout__line__incomplete
|
||||
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
client__pollout__line__error:
|
||||
mov r10, 0
|
||||
jmp client__pollout__line__write_scratch
|
||||
|
||||
client__pollout__line__incomplete:
|
||||
mov r10, rax
|
||||
|
||||
client__pollout__line__write_scratch:
|
||||
add rsi, OFFSET_CLIENT_SCRATCH
|
||||
add r10, rdx
|
||||
mov r11, 0
|
||||
mov r9, rcx
|
||||
add r9, rdx
|
||||
|
||||
client__pollout__line__write_scratch__loop:
|
||||
cmp r10, r9
|
||||
jge return
|
||||
mov r8b, [r10 + r11]
|
||||
mov [rsi + r11], r8b
|
||||
add r11, 1
|
||||
jmp client__pollout__line__write_scratch__loop
|
||||
|
||||
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
client__shutdown_close:
|
||||
mov rax, SYS_SHUTDOWN
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue