client__pollin: read as much as possible; client__pollout: do processing
This commit is contained in:
parent
8ab750ba97
commit
484d81baa8
3 changed files with 149 additions and 92 deletions
173
client.s
173
client.s
|
@ -1,75 +1,146 @@
|
|||
; Returns:
|
||||
; rax - 0
|
||||
; Errors (in rax):
|
||||
; 0 - EOF
|
||||
; -1024 - line too long
|
||||
; other negative - from read(2)
|
||||
; rax - 0 - EOF
|
||||
; rax - -1024 - line too long
|
||||
; rax - other negative - from read(2)
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - address of client within clients array
|
||||
; rdx - pollfds index
|
||||
; Variables:
|
||||
; rbx - pollfds index
|
||||
; r12 - client buffer
|
||||
; r13 - start of line scanning
|
||||
; r14 - client buffer end
|
||||
client__pollin:
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
push rbx
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
|
||||
mov r10, 0
|
||||
mov r10b, [rsi + 4 + 2] ; buffer_len
|
||||
mov rbx, rdx
|
||||
mov r12, rsi
|
||||
add r12, OFFSET_CLIENT_BUFFER
|
||||
mov r13, 0
|
||||
mov r13b, [rsi + OFFSET_CLIENT_BUFFER_LEN]
|
||||
add r13, r12
|
||||
mov r14, r12
|
||||
add r14, 255
|
||||
|
||||
mov rdx, 0
|
||||
mov dl, 255
|
||||
sub dl, r10b ; rdx = 255 - buffer_len
|
||||
add rsi, 8
|
||||
add rsi, r10
|
||||
call readline
|
||||
|
||||
mov r10, rdi
|
||||
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
mov rax, SYS_READ
|
||||
mov rsi, r13
|
||||
mov rdx, 255
|
||||
sub rdx, [rsi + OFFSET_CLIENT_BUFFER_LEN]
|
||||
syscall
|
||||
|
||||
cmp rax, 0
|
||||
jle return
|
||||
jle client__pollin__return ; TODO verify this shit
|
||||
|
||||
add [rsi + 4 + 2], al ; buffer_len += rax
|
||||
; buffer_len += read(2) length
|
||||
add [rsi + OFFSET_CLIENT_BUFFER_LEN], al
|
||||
|
||||
cmp r10, 0
|
||||
jg client__pollin__complete_line
|
||||
mov rdi, r13
|
||||
mov rsi, rax
|
||||
call scanline
|
||||
|
||||
add [rsi + 4 + 1], al ; line_len += rax
|
||||
ret
|
||||
cmp rax, 0
|
||||
je client__pollin__no_line
|
||||
|
||||
client__pollin__complete_line:
|
||||
add [rsi + 4 + 1], r10b ; line_len += r10
|
||||
mov rax, 1
|
||||
mov word [pollfds + rdx * pollfd_size + 4], POLLOUT
|
||||
|
||||
client__pollin__return:
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbx
|
||||
ret
|
||||
|
||||
client__pollin__no_line:
|
||||
mov r10, r13
|
||||
add r10, rax
|
||||
cmp r10, r14
|
||||
jge client__pollin__line_too_long
|
||||
mov rax, 1
|
||||
jmp client__pollin__return
|
||||
|
||||
client__pollin__line_too_long:
|
||||
mov rax, -1024
|
||||
jmp client__pollin__return
|
||||
|
||||
client__pollin__line:
|
||||
pop rdx
|
||||
mov word [pollfds + rdx * pollfd_size + 4], POLLOUT
|
||||
push rdx
|
||||
; TODO do something to the line
|
||||
; problem: we can't write here because the socket may
|
||||
; block;
|
||||
; how do we deal with multiple lines?
|
||||
; XXX call read(2) trying to fill the whole buffer
|
||||
; - if we have at least 1 line,
|
||||
; update the state and go back to main loop;
|
||||
; do whatever logic is necessary until we need to
|
||||
; call read(2) or write(2) next, ie nothing;
|
||||
; set POLLOUT and process line(s) in write(2) block
|
||||
; - if we have no line and we filled the buffer,
|
||||
; return -1024
|
||||
; - if we have no line, go back to main loop
|
||||
; we could have multiple lines, and that's okay
|
||||
; XXX so this plan will work actually
|
||||
; XXX should we do logic here or in the write(2) block?
|
||||
; probably there, so here we just accumulate lines
|
||||
ret
|
||||
|
||||
; Returns:
|
||||
; rax - non-negative from write(2)
|
||||
; Errors:
|
||||
; rax - -1024 - no line was buffered
|
||||
; rax - other negative - from write(2)
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - address of client within clients array
|
||||
; rdx - pollfds index
|
||||
; Variables:
|
||||
; rbx - pollfds index
|
||||
; r12 - address of client within clients array
|
||||
; r13 - line length
|
||||
; r11 - client buffer end of text after call to write(2)
|
||||
client__pollout:
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
push rbx
|
||||
push r12
|
||||
push r13
|
||||
|
||||
mov rbx, rdx
|
||||
mov r12, rsi
|
||||
|
||||
mov rdi, r12
|
||||
mov rsi, 255
|
||||
call scanline
|
||||
|
||||
; poll(2)'d for POLLOUT but we had no line buffered;
|
||||
; should be impossible
|
||||
cmp rax, 0
|
||||
mov rax, -1024
|
||||
je client__pollout__return
|
||||
|
||||
mov r13, rax
|
||||
|
||||
mov rax, SYS_WRITE
|
||||
mov rdx, 0
|
||||
mov dl, [rsi + 4 + 1]
|
||||
add rsi, 8
|
||||
mov rsi, r12
|
||||
add rsi, OFFSET_CLIENT_BUFFER
|
||||
mov rdx, r13
|
||||
syscall
|
||||
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
|
||||
; error from write(2)
|
||||
cmp rax, 0
|
||||
jl return
|
||||
jl client__pollout__return
|
||||
|
||||
mov r10, rsi
|
||||
add r10, 8
|
||||
mov r10, r12
|
||||
mov r11, 0
|
||||
mov r11b, [rsi + 4 + 2]
|
||||
mov r11b, [r12 + OFFSET_CLIENT_BUFFER_LEN]
|
||||
add r11, r12
|
||||
sub r11, rax
|
||||
add r11, r10
|
||||
|
||||
client__pollout__shunt:
|
||||
cmp r10, r11
|
||||
|
@ -80,14 +151,16 @@ client__pollout__shunt:
|
|||
jmp client__pollout__shunt
|
||||
|
||||
client__pollout__shunt__finished:
|
||||
sub [rsi + 4 + 2], al ; buffer_len -= rax
|
||||
sub [rsi + 4 + 1], al ; line_len -= rax
|
||||
cmp byte [rsi + 4 + 1], 0
|
||||
je client__pollout__wrote_line
|
||||
ret
|
||||
; 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
|
||||
|
||||
client__pollout__wrote_line:
|
||||
mov word [pollfds + rdx * pollfd_size + 4], POLLIN
|
||||
client__pollout__return:
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbx
|
||||
ret
|
||||
|
||||
; rdi - fd
|
||||
|
|
17
main.s
17
main.s
|
@ -30,11 +30,18 @@ SHUT_RDWR equ 2
|
|||
;STATE_READING equ 0
|
||||
;STATE_WRITING equ 1
|
||||
|
||||
; offsets into client struct
|
||||
OFFSET_CLIENT_FD equ 0
|
||||
OFFSET_CLIENT_STATE equ 4
|
||||
OFFSET_CLIENT_BUFFER_LEN equ 5
|
||||
OFFSET_CLIENT_BUFFER equ 6
|
||||
|
||||
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
|
||||
pollfds_capacity equ 100
|
||||
|
||||
; fd, state, line_len, buffer_len, uri_len, buffer, uri
|
||||
client_size equ 4 + 4 + 255 + 255
|
||||
client_buffer_size equ 255
|
||||
; fd, state, buffer_len, buffer
|
||||
client_size equ 4 + 2 + client_buffer_size
|
||||
clients_capacity equ pollfds_capacity - 1
|
||||
|
||||
SECTION .data
|
||||
|
@ -109,7 +116,7 @@ scan__found__client:
|
|||
mov r10w, r14w
|
||||
and r10w, POLLERR | POLLNVAL
|
||||
cmp r10w, 0
|
||||
jne _client__error
|
||||
jne _client__error_or_eof
|
||||
|
||||
mov r10w, r14w
|
||||
and r10w, POLLIN
|
||||
|
@ -125,7 +132,7 @@ scan__found__client:
|
|||
add r15, 1
|
||||
jmp scan__loop
|
||||
|
||||
_client__error:
|
||||
_client__error_or_eof:
|
||||
mov rdi, r12
|
||||
call clients__remove
|
||||
|
||||
|
@ -142,7 +149,7 @@ _client__pollin:
|
|||
mov rdx, r15
|
||||
call client__pollin
|
||||
cmp rax, 0
|
||||
jle _client__error
|
||||
jle _client__error_or_eof
|
||||
add r15, rax
|
||||
jmp scan__loop
|
||||
|
||||
|
|
51
readline.s
51
readline.s
|
@ -1,43 +1,20 @@
|
|||
; Returns:
|
||||
; rax - read(2) length
|
||||
; rdi - if line is complete, line length;
|
||||
; if line was incomplete, 0;
|
||||
; if EOF or read(2) returned an error, undefined
|
||||
; Errors (in rax):
|
||||
; -1024 - line too long
|
||||
; other negative - error from read(2)
|
||||
; 0 - EOF from read(2)
|
||||
; rax - if line: line length; otherwise: 0
|
||||
; Arguments:
|
||||
; rdi - fd
|
||||
; rsi - buffer
|
||||
; rdx - max length
|
||||
readline:
|
||||
push rsi
|
||||
push rdx
|
||||
mov rax, SYS_READ
|
||||
syscall
|
||||
pop rdx
|
||||
pop rsi
|
||||
cmp rax, 0
|
||||
jl return
|
||||
mov r10, 0
|
||||
; rdi - buffer
|
||||
; rsi - max length
|
||||
scanline:
|
||||
mov rax, 0
|
||||
|
||||
readline__scan:
|
||||
cmp r10, rdx
|
||||
jge readline__overflow
|
||||
cmp r10, rax
|
||||
jge readline__incomplete_line
|
||||
mov r11b, [rsi + r10]
|
||||
add r10, 1
|
||||
cmp r11b, 0x0a ; '\n'
|
||||
jne readline__scan
|
||||
mov rdi, r10
|
||||
scanline__loop:
|
||||
cmp rax, rsi
|
||||
jge scanline__incomplete_line
|
||||
mov r10b, [rdi + rax]
|
||||
add rax, 1
|
||||
cmp r10b, 0x0a ; '\n'
|
||||
jne scanline__loop
|
||||
ret
|
||||
|
||||
readline__incomplete_line:
|
||||
mov rdi, 0
|
||||
ret
|
||||
|
||||
readline__overflow:
|
||||
mov rax, -1024
|
||||
scanline__incomplete_line:
|
||||
mov rax, 0
|
||||
ret
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue