/kernel/branches/kolibri-process/core/dll.inc |
---|
1492,60 → 1492,11 |
destroy_hdll: |
push ebx ecx esi edi |
push eax |
mov ebx, [eax+HDLL.base] |
mov esi, [eax+HDLL.parent] |
mov edx, [esi+DLLDESCR.size] |
; The following actions require the context of application where HDLL is mapped. |
; However, destroy_hdll can be called in the context of OS thread when |
; cleaning up objects created by the application which is destroyed. |
; So remember current cr3 and set it to page table of target. |
mov eax, [ecx+APPDATA.process] |
; Because we cheat with cr3, disable interrupts: task switch would restore |
; page table from APPDATA of current thread. |
; Also set [current_slot] because it is used by user_free. |
pushf |
cli |
push [current_slot] |
mov [current_slot], ecx |
mov ecx, cr3 |
push ecx |
mov cr3, eax |
push ebx ; argument for user_free |
mov eax, ebx |
shr ebx, 12 |
push ebx |
mov esi, [esi+DLLDESCR.data] |
shr esi, 12 |
.unmap_loop: |
push eax |
mov eax, 2 |
xchg eax, [page_tabs+ebx*4] |
mov ecx, [page_tabs+esi*4] |
and eax, not 0xFFF |
and ecx, not 0xFFF |
cmp eax, ecx |
jz @f |
call free_page |
@@: |
pop eax |
invlpg [eax] |
add eax, 0x1000 |
inc ebx |
inc esi |
sub edx, 0x1000 |
ja .unmap_loop |
pop ebx |
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK |
call user_free |
; Restore context. |
pop eax |
mov cr3, eax |
pop [current_slot] |
popf |
; Ok, cheating is done. |
pop eax |
push eax |
mov esi, [eax+HDLL.parent] |
mov eax, [eax+HDLL.refcount] |
call dereference_dll |
/kernel/branches/kolibri-process/core/sys32.inc |
---|
418,6 → 418,8 |
.slot equ esp+4 ;locals |
.process equ esp ;ptr to parent process |
xchg bx, bx |
push esi ;save .slot |
shl esi, 8 |
751,13 → 753,12 |
bts [thr_slot_map], esi |
mov ebx, [.process] |
add ebx, PROC.thr_list |
cmp ebx, [ebx+LHEAD.next] |
mov ecx, [.process] |
lea eax, [ecx+PROC.thr_list] |
cmp eax, [eax+LHEAD.next] |
jne @F |
DEBUGF 1,"%s",msg_process_destroy |
call destroy_process.internal |
@@: |
sti ; .. and life goes on |
778,9 → 779,6 |
restore .slot |
restore .process |
msg_process_destroy: db 'K: destroy process', 0x0d, 0x0a,0 |
; Three following procedures are used to guarantee that |
; some part of kernel code will not be terminated from outside |
; while it is running. |
/kernel/branches/kolibri-process/core/taskman.inc |
---|
587,6 → 587,8 |
mov eax, [esi] |
test eax, 1 |
jz .next |
test eax, 2 |
jz .next |
test eax, 1 shl 9 |
jnz .next ;skip shared pages |
call free_page |
599,46 → 601,25 |
endp |
align 4 |
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword |
destroy_process: ;fastcall ecx= ptr to process |
xor edx, edx |
push edx |
mov eax, 0x1 |
mov ebx, [pg_dir] |
.loop: |
;eax = current slot of process |
mov ecx, eax |
shl ecx, 5 |
cmp byte [CURRENT_TASK+ecx+0xa], 9;if process running? |
jz @f ;skip empty slots |
shl ecx, 3 |
add ecx, SLOT_BASE |
cmp [ecx+APPDATA.process], ebx;compare page directory addresses |
jnz @f |
mov [ebp-4], ecx |
inc edx ;thread found |
@@: |
inc eax |
cmp eax, [TASK_COUNT] ;exit loop if we look through all processes |
jle .loop |
lea eax, [ecx+PROC.thr_list] |
cmp eax, [eax+LHEAD.next] |
jne .exit |
;edx = number of threads |
;our process is zombi so it isn't counted |
pop ecx |
cmp edx, 1 |
jg .ret |
;if there isn't threads then clear memory. |
mov esi, [dlls_list] |
call destroy_all_hdlls;ecx=APPDATA |
align 4 |
.internal: |
push ecx |
mov ecx, pg_data.mutex |
call mutex_lock |
mov esi, [ecx+PROC.dlls_list_ptr] |
call destroy_all_hdlls |
mov eax, [pg_dir] |
and eax, not 0xFFF |
; stdcall map_page, [tmp_task_pdir], eax, PG_SW |
; mov esi, [tmp_task_pdir] |
mov edi, (OS_BASE shr 20)/4 |
; mov ecx, pg_data.mutex |
; call mutex_lock |
mov esi, [esp] |
add esi, PROC.pdt_0 |
mov edi, (0x80000000 shr 20)/4 |
.destroy: |
mov eax, [esi] |
test eax, 1 |
653,16 → 634,13 |
dec edi |
jnz .destroy |
mov eax, [pg_dir] |
call free_page |
call kernel_free ;ecx still in stack |
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP |
; mov ecx, pg_data.mutex |
; call mutex_unlock |
.exit: |
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP |
; stdcall map_page, [tmp_task_pdir], 0, PG_UNMAP |
mov ecx, pg_data.mutex |
call mutex_unlock |
.ret: |
ret |
endp |
align 4 |
get_pid: |
986,7 → 964,7 |
lea ebx, [edx+APPDATA.list] |
lea ecx, [eax+PROC.thr_list] |
list_add_tail edx, ecx ;add thread to process child's list |
list_add_tail ebx, ecx ;add thread to process child's list |
mov eax, [ebx+APPDATA.tls_base] |
test eax, eax |