protect thread from external terminate while running sysfn 70
git-svn-id: svn://kolibrios.org@3296 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
910558ed00
commit
165c453d43
|
@ -24,7 +24,7 @@ sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
|
|||
mov ebx, saverd_fileinfo
|
||||
mov [saverd_fileinfo.name], ecx
|
||||
pushad
|
||||
call file_system_lfn ;in ebx
|
||||
call file_system_lfn_protected ;in ebx
|
||||
popad
|
||||
mov [esp+32], eax
|
||||
ret
|
||||
|
|
|
@ -103,7 +103,7 @@ endg
|
|||
read_image:
|
||||
mov ebx, read_image_fsinfo
|
||||
pushad
|
||||
call file_system_lfn
|
||||
call file_system_lfn_protected
|
||||
popad
|
||||
ret
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
|
|||
|
||||
pushad
|
||||
lea ebx, [cmd]
|
||||
call file_system_lfn
|
||||
call file_system_lfn_protected
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
|
|
@ -707,3 +707,78 @@ restore .slot
|
|||
; mov esi,boot_sched_2
|
||||
; call boot_log
|
||||
; ret
|
||||
|
||||
; Three following procedures are used to guarantee that
|
||||
; some part of kernel code will not be terminated from outside
|
||||
; while it is running.
|
||||
; Note: they do not protect a thread from terminating due to errors inside
|
||||
; the thread; accessing a nonexisting memory would still terminate it.
|
||||
|
||||
; First two procedures must be used in pair by thread-to-be-protected
|
||||
; to signal the beginning and the end of an important part.
|
||||
; It is OK to have nested areas.
|
||||
|
||||
; The last procedure must be used by outside wanna-be-terminators;
|
||||
; if it is safe to terminate the given thread immediately, it returns eax=1;
|
||||
; otherwise, it returns eax=0 and notifies the target thread that it should
|
||||
; terminate itself when leaving a critical area (the last critical area if
|
||||
; they are nested).
|
||||
|
||||
; Implementation. Those procedures use one dword in APPDATA for the thread,
|
||||
; APPDATA.terminate_protection.
|
||||
; * The upper bit is 1 during normal operations and 0 when terminate is requested.
|
||||
; * Other bits form a number = depth of critical regions,
|
||||
; plus 1 if the upper bit is 1.
|
||||
; * When this dword goes to zero, the thread should be destructed,
|
||||
; and the procedure in which it happened becomes responsible for destruction.
|
||||
|
||||
; Enter critical area. Called by thread which wants to be protected.
|
||||
proc protect_from_terminate
|
||||
mov edx, [current_slot]
|
||||
; Atomically increment depth of critical areas and get the old value.
|
||||
mov eax, 1
|
||||
lock xadd [edx+APPDATA.terminate_protection], eax
|
||||
; If the old value was zero, somebody has started to terminate us,
|
||||
; so we are destructing and cannot do anything protected.
|
||||
; Otherwise, return to the caller.
|
||||
test eax, eax
|
||||
jz @f
|
||||
ret
|
||||
@@:
|
||||
; Wait for somebody to finish us.
|
||||
call change_task
|
||||
jmp @b
|
||||
endp
|
||||
|
||||
; Leave critical area. Called by thread which wants to be protected.
|
||||
proc unprotect_from_terminate
|
||||
mov edx, [current_slot]
|
||||
; Atomically decrement depth of critical areas.
|
||||
lock dec [edx+APPDATA.terminate_protection]
|
||||
; If the result of decrement is zero, somebody has requested termination,
|
||||
; but at that moment we were inside a critical area; terminate now.
|
||||
jz sys_end
|
||||
; Otherwise, return to the caller.
|
||||
ret
|
||||
endp
|
||||
|
||||
; Request termination of thread identified by edx = SLOT_BASE + slot*256.
|
||||
; Called by anyone.
|
||||
proc request_terminate
|
||||
xor eax, eax ; set return value
|
||||
; Atomically clear the upper bit. If it was already zero, then
|
||||
; somebody has requested termination before us, so just exit.
|
||||
lock btr [edx+APPDATA.terminate_protection], 31
|
||||
jnc .unsafe
|
||||
; Atomically decrement depth of critical areas.
|
||||
lock dec [edx+APPDATA.terminate_protection]
|
||||
; If the result of decrement is nonzero, the target thread is inside a
|
||||
; critical area; leave termination to leaving that area.
|
||||
jnz .unsafe
|
||||
; Otherwise, it is safe to kill the target now and the caller is responsible
|
||||
; for this. Return eax=1.
|
||||
inc eax
|
||||
.unsafe:
|
||||
ret
|
||||
endp
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ iglobal
|
|||
dd syscall_move_window ; 67-Window move or resize
|
||||
dd f68 ; 68-Some internal services
|
||||
dd sys_debug_services ; 69-Debug
|
||||
dd file_system_lfn ; 70-Common file system interface, version 2
|
||||
dd file_system_lfn_protected; 70-Common file system interface, version 2
|
||||
dd syscall_window_settings ; 71-Window settings
|
||||
dd sys_sendwindowmsg ; 72-Send window message
|
||||
dd blit_32 ; 73-blitter;
|
||||
|
|
|
@ -1023,6 +1023,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
|||
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
|
||||
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
|
||||
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
|
||||
mov [eax+SLOT_BASE+APPDATA.terminate_protection], 80000001h
|
||||
|
||||
;set default io permission map
|
||||
mov ecx, [SLOT_BASE+256+APPDATA.io_map]
|
||||
|
|
|
@ -103,6 +103,17 @@ fs_additional_handlers:
|
|||
dd 0
|
||||
|
||||
endg
|
||||
|
||||
file_system_lfn_protected:
|
||||
pushad
|
||||
call protect_from_terminate
|
||||
call file_system_lfn
|
||||
call unprotect_from_terminate
|
||||
popad
|
||||
mov [image_of_eax], eax
|
||||
mov [image_of_ebx], ebx
|
||||
ret
|
||||
|
||||
file_system_lfn:
|
||||
; in: ebx->fileinfo block
|
||||
; operation codes:
|
||||
|
|
|
@ -612,6 +612,52 @@ no_mode_0x12:
|
|||
mov [mem_BACKGROUND], 4
|
||||
mov [img_background], static_background_data
|
||||
|
||||
; SET UP OS TASK
|
||||
|
||||
mov esi, boot_setostask
|
||||
call boot_log
|
||||
|
||||
xor eax, eax
|
||||
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data
|
||||
mov dword [SLOT_BASE+APPDATA.exc_handler], eax
|
||||
mov dword [SLOT_BASE+APPDATA.except_mask], eax
|
||||
|
||||
; name for OS/IDLE process
|
||||
|
||||
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
|
||||
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
|
||||
mov edi, [os_stack_seg]
|
||||
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi
|
||||
add edi, 0x2000-512
|
||||
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi
|
||||
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi; just for case
|
||||
mov dword [SLOT_BASE+256+APPDATA.terminate_protection], 80000001h
|
||||
|
||||
mov esi, fpu_data
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
|
||||
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax
|
||||
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax
|
||||
|
||||
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET
|
||||
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx
|
||||
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx
|
||||
|
||||
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path
|
||||
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax
|
||||
|
||||
; task list
|
||||
mov dword [TASK_DATA+TASKDATA.mem_start], eax; process base address
|
||||
inc eax
|
||||
mov dword [CURRENT_TASK], eax
|
||||
mov dword [TASK_COUNT], eax
|
||||
mov [current_slot], SLOT_BASE+256
|
||||
mov [TASK_BASE], dword TASK_DATA
|
||||
mov byte[TASK_DATA+TASKDATA.wnd_number], al ; on screen number
|
||||
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number
|
||||
|
||||
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE
|
||||
|
||||
stdcall kernel_alloc, 0x10000/8
|
||||
|
@ -752,7 +798,6 @@ end if
|
|||
|
||||
mov [pci_access_enabled], 1
|
||||
|
||||
|
||||
; SET PRELIMINARY WINDOW STACK AND POSITIONS
|
||||
|
||||
mov esi, boot_windefs
|
||||
|
@ -772,52 +817,6 @@ end if
|
|||
call boot_log
|
||||
call reserve_irqs_ports
|
||||
|
||||
; SET UP OS TASK
|
||||
|
||||
mov esi, boot_setostask
|
||||
call boot_log
|
||||
|
||||
xor eax, eax
|
||||
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data
|
||||
mov dword [SLOT_BASE+APPDATA.exc_handler], eax
|
||||
mov dword [SLOT_BASE+APPDATA.except_mask], eax
|
||||
|
||||
; name for OS/IDLE process
|
||||
|
||||
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
|
||||
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
|
||||
mov edi, [os_stack_seg]
|
||||
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi
|
||||
add edi, 0x2000-512
|
||||
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi
|
||||
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi; just for case
|
||||
; [SLOT_BASE+256+APPDATA.io_map] was set earlier
|
||||
|
||||
mov esi, fpu_data
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
|
||||
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax
|
||||
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax
|
||||
|
||||
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET
|
||||
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx
|
||||
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx
|
||||
|
||||
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path
|
||||
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax
|
||||
|
||||
; task list
|
||||
mov dword [TASK_DATA+TASKDATA.mem_start], eax; process base address
|
||||
inc eax
|
||||
mov dword [CURRENT_TASK], eax
|
||||
mov dword [TASK_COUNT], eax
|
||||
mov [current_slot], SLOT_BASE+256
|
||||
mov [TASK_BASE], dword TASK_DATA
|
||||
mov byte[TASK_DATA+TASKDATA.wnd_number], al ; on screen number
|
||||
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number
|
||||
|
||||
call init_display
|
||||
mov eax, [def_cursor]
|
||||
mov [SLOT_BASE+APPDATA.cursor], eax
|
||||
|
@ -931,8 +930,8 @@ end if
|
|||
call fs_execute_from_sysdir
|
||||
|
||||
; cmp eax,2 ; continue if a process has been loaded
|
||||
sub eax, 2
|
||||
jz first_app_found
|
||||
test eax, eax
|
||||
jns first_app_found
|
||||
|
||||
mov esi, boot_failed
|
||||
call boot_log
|
||||
|
@ -2110,6 +2109,12 @@ sysfn_terminate: ; 18.2 = TERMINATE
|
|||
add ecx, CURRENT_TASK+TASKDATA.state
|
||||
cmp byte [ecx], 9
|
||||
jz noprocessterminate
|
||||
push ecx edx
|
||||
lea edx, [(ecx-(CURRENT_TASK and 1FFFFFFFh)-TASKDATA.state)*8+SLOT_BASE]
|
||||
call request_terminate
|
||||
pop edx ecx
|
||||
test eax, eax
|
||||
jz noprocessterminate
|
||||
;--------------------------------------
|
||||
cmp [_display.select_cursor], 0
|
||||
je .restore_end
|
||||
|
@ -3489,7 +3494,14 @@ nobackgr:
|
|||
;--------------------------------------
|
||||
align 4
|
||||
markz:
|
||||
push ecx edx
|
||||
lea edx, [(edx-(TASK_DATA and 1FFFFFFFh))*8+SLOT_BASE]
|
||||
call request_terminate
|
||||
pop edx ecx
|
||||
test eax, eax
|
||||
jz @f
|
||||
mov [edx+TASKDATA.state], byte 3
|
||||
@@:
|
||||
add edx, 0x20
|
||||
loop markz
|
||||
;--------------------------------------
|
||||
|
|
|
@ -137,7 +137,7 @@ struct APPDATA
|
|||
ipc_size dd ?
|
||||
event_mask dd ?
|
||||
debugger_slot dd ?
|
||||
dd ?
|
||||
terminate_protection dd ?
|
||||
keyboard_mode db ?
|
||||
rb 3
|
||||
dir_table dd ?
|
||||
|
|
Loading…
Reference in New Issue