forked from KolibriOS/kolibrios
Fixed SOCKET_process_end (broken in #3264), Use mutexes for ring buffer reading/writing.
git-svn-id: svn://kolibrios.org@3307 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
088f181657
commit
1b65aa6050
@ -136,7 +136,9 @@ struct TCP_SOCKET IP_SOCKET
|
||||
|
||||
ts_ecr dd ? ; timestamp echo reply
|
||||
ts_val dd ?
|
||||
|
||||
temp_bits db ?
|
||||
rb 3 ; align
|
||||
|
||||
ends
|
||||
|
||||
@ -158,6 +160,7 @@ ends
|
||||
|
||||
struct RING_BUFFER
|
||||
|
||||
mutex MUTEX
|
||||
start_ptr dd ? ; Pointer to start of buffer
|
||||
end_ptr dd ? ; pointer to end of buffer
|
||||
read_ptr dd ? ; Read pointer
|
||||
@ -1402,6 +1405,12 @@ SOCKET_ring_create:
|
||||
pop edx
|
||||
|
||||
DEBUGF 1,"SOCKET_ring_created: %x\n", eax
|
||||
|
||||
pusha
|
||||
lea ecx, [esi + RING_BUFFER.mutex]
|
||||
call mutex_init
|
||||
popa
|
||||
|
||||
mov [esi + RING_BUFFER.start_ptr], eax
|
||||
mov [esi + RING_BUFFER.write_ptr], eax
|
||||
mov [esi + RING_BUFFER.read_ptr], eax
|
||||
@ -1431,15 +1440,36 @@ SOCKET_ring_write:
|
||||
|
||||
DEBUGF 1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
|
||||
|
||||
add [eax + RING_BUFFER.size], ecx
|
||||
jc .way_too_large
|
||||
cmp [eax + RING_BUFFER.size], SOCKET_MAXDATA
|
||||
ja .too_large
|
||||
; lock mutex
|
||||
pusha
|
||||
lea ecx, [eax + RING_BUFFER.mutex]
|
||||
call mutex_lock ; TODO: check what registers this function actually destroys
|
||||
popa
|
||||
|
||||
; calculate available size
|
||||
mov edi, SOCKET_MAXDATA
|
||||
sub edi, [eax + RING_BUFFER.size] ; available buffer size in edi
|
||||
cmp ecx, edi
|
||||
jbe .copy
|
||||
mov ecx, edi
|
||||
.copy:
|
||||
mov edi, [eax + RING_BUFFER.write_ptr]
|
||||
DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
|
||||
|
||||
; update write ptr
|
||||
push edi
|
||||
add edi, ecx
|
||||
cmp edi, [eax + RING_BUFFER.end_ptr]
|
||||
jb @f
|
||||
sub edi, SOCKET_MAXDATA ; WRAP
|
||||
@@:
|
||||
mov [eax + RING_BUFFER.write_ptr], edi
|
||||
pop edi
|
||||
|
||||
; update size
|
||||
add [eax + RING_BUFFER.size], ecx
|
||||
|
||||
; copy the data
|
||||
push ecx
|
||||
shr ecx, 1
|
||||
jnc .nb
|
||||
@ -1455,38 +1485,14 @@ SOCKET_ring_write:
|
||||
.nd:
|
||||
pop ecx
|
||||
|
||||
cmp edi, [eax + RING_BUFFER.end_ptr]
|
||||
jae .wrap
|
||||
mov [eax + RING_BUFFER.write_ptr], edi
|
||||
; unlock mutex
|
||||
push eax ecx
|
||||
lea ecx, [eax + RING_BUFFER.mutex]
|
||||
call mutex_unlock ; TODO: check what registers this function actually destroys
|
||||
pop ecx eax
|
||||
|
||||
ret
|
||||
|
||||
.wrap:
|
||||
sub edi, SOCKET_MAXDATA
|
||||
mov [eax + RING_BUFFER.write_ptr], edi
|
||||
|
||||
ret
|
||||
|
||||
.too_large: ; update size, we will fill buffer completely
|
||||
sub [eax + RING_BUFFER.size], SOCKET_MAXDATA
|
||||
sub ecx, [eax + RING_BUFFER.size]
|
||||
mov [eax + RING_BUFFER.size], SOCKET_MAXDATA
|
||||
ja .copy
|
||||
|
||||
.full:
|
||||
DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n"
|
||||
xor ecx, ecx
|
||||
ret
|
||||
|
||||
.way_too_large:
|
||||
sub [eax + RING_BUFFER.size], ecx
|
||||
mov ecx, SOCKET_MAXDATA
|
||||
sub ecx, [eax + RING_BUFFER.size]
|
||||
ja .copy
|
||||
jmp .full
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; SOCKET_ring_read
|
||||
@ -1508,6 +1514,11 @@ SOCKET_ring_read:
|
||||
|
||||
DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx
|
||||
|
||||
pusha
|
||||
lea ecx, [eax + RING_BUFFER.mutex]
|
||||
call mutex_lock ; TODO: check what registers this function actually destroys
|
||||
popa
|
||||
|
||||
mov esi, [eax + RING_BUFFER.read_ptr]
|
||||
add esi, edx ; esi = start_ptr + offset
|
||||
|
||||
@ -1515,6 +1526,11 @@ SOCKET_ring_read:
|
||||
add edx, [eax + RING_BUFFER.size] ; edx = snd.size - offset
|
||||
jle .no_data_at_all
|
||||
|
||||
pusha
|
||||
lea ecx, [eax + RING_BUFFER.mutex]
|
||||
call mutex_unlock ; TODO: check what registers this function actually destroys
|
||||
popa
|
||||
|
||||
cmp ecx, edx
|
||||
ja .less_data
|
||||
|
||||
@ -1537,6 +1553,11 @@ SOCKET_ring_read:
|
||||
ret
|
||||
|
||||
.no_data_at_all:
|
||||
pusha
|
||||
lea ecx, [eax + RING_BUFFER.mutex]
|
||||
call mutex_unlock ; TODO: check what registers this function actually destroys
|
||||
popa
|
||||
|
||||
DEBUGF 1,"SOCKET_ring_read: no data at all!\n"
|
||||
xor ecx, ecx
|
||||
ret
|
||||
@ -1563,6 +1584,11 @@ SOCKET_ring_free:
|
||||
|
||||
DEBUGF 1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
|
||||
|
||||
push eax ecx
|
||||
lea ecx, [eax + RING_BUFFER.mutex]
|
||||
call mutex_lock ; TODO: check what registers this function actually destroys
|
||||
pop ecx eax
|
||||
|
||||
sub [eax + RING_BUFFER.size], ecx
|
||||
jb .error
|
||||
add [eax + RING_BUFFER.read_ptr], ecx
|
||||
@ -1572,11 +1598,23 @@ SOCKET_ring_free:
|
||||
jb @f
|
||||
sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
|
||||
@@:
|
||||
|
||||
push eax ecx
|
||||
lea ecx, [eax + RING_BUFFER.mutex] ; TODO: check what registers this function actually destroys
|
||||
call mutex_unlock
|
||||
pop ecx eax
|
||||
|
||||
ret
|
||||
|
||||
.error: ; we could free all available bytes, but that would be stupid, i guess..
|
||||
DEBUGF 1,"SOCKET_ring_free: buffer=%x error!\n", eax
|
||||
add [eax + RING_BUFFER.size], ecx
|
||||
|
||||
push eax
|
||||
lea ecx, [eax + RING_BUFFER.mutex]
|
||||
call mutex_unlock ; TODO: check what registers this function actually destroys
|
||||
pop eax
|
||||
|
||||
xor ecx, ecx
|
||||
ret
|
||||
|
||||
@ -2066,6 +2104,7 @@ SOCKET_process_end:
|
||||
|
||||
.next_socket:
|
||||
mov ebx, [ebx + SOCKET.NextPtr]
|
||||
.next_socket_test:
|
||||
test ebx, ebx
|
||||
jz .done
|
||||
|
||||
@ -2076,10 +2115,11 @@ SOCKET_process_end:
|
||||
|
||||
mov [ebx + SOCKET.PID], 0
|
||||
mov eax, ebx
|
||||
mov ebx, [ebx + SOCKET.NextPtr]
|
||||
pusha
|
||||
call SOCKET_close.socket
|
||||
popa
|
||||
jmp .next_socket
|
||||
jmp .next_socket_test
|
||||
|
||||
.done:
|
||||
pop ebx
|
||||
|
Loading…
Reference in New Issue
Block a user