forked from KolibriOS/kolibrios
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 ebx, saverd_fileinfo
|
||||||
mov [saverd_fileinfo.name], ecx
|
mov [saverd_fileinfo.name], ecx
|
||||||
pushad
|
pushad
|
||||||
call file_system_lfn ;in ebx
|
call file_system_lfn_protected ;in ebx
|
||||||
popad
|
popad
|
||||||
mov [esp+32], eax
|
mov [esp+32], eax
|
||||||
ret
|
ret
|
||||||
|
@ -103,7 +103,7 @@ endg
|
|||||||
read_image:
|
read_image:
|
||||||
mov ebx, read_image_fsinfo
|
mov ebx, read_image_fsinfo
|
||||||
pushad
|
pushad
|
||||||
call file_system_lfn
|
call file_system_lfn_protected
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
|
|||||||
|
|
||||||
pushad
|
pushad
|
||||||
lea ebx, [cmd]
|
lea ebx, [cmd]
|
||||||
call file_system_lfn
|
call file_system_lfn_protected
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
@ -707,3 +707,78 @@ restore .slot
|
|||||||
; mov esi,boot_sched_2
|
; mov esi,boot_sched_2
|
||||||
; call boot_log
|
; call boot_log
|
||||||
; ret
|
; 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 syscall_move_window ; 67-Window move or resize
|
||||||
dd f68 ; 68-Some internal services
|
dd f68 ; 68-Some internal services
|
||||||
dd sys_debug_services ; 69-Debug
|
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 syscall_window_settings ; 71-Window settings
|
||||||
dd sys_sendwindowmsg ; 72-Send window message
|
dd sys_sendwindowmsg ; 72-Send window message
|
||||||
dd blit_32 ; 73-blitter;
|
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.fpu_state], edi
|
||||||
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
|
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
|
||||||
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
|
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
|
||||||
|
mov [eax+SLOT_BASE+APPDATA.terminate_protection], 80000001h
|
||||||
|
|
||||||
;set default io permission map
|
;set default io permission map
|
||||||
mov ecx, [SLOT_BASE+256+APPDATA.io_map]
|
mov ecx, [SLOT_BASE+256+APPDATA.io_map]
|
||||||
|
@ -103,6 +103,17 @@ fs_additional_handlers:
|
|||||||
dd 0
|
dd 0
|
||||||
|
|
||||||
endg
|
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:
|
file_system_lfn:
|
||||||
; in: ebx->fileinfo block
|
; in: ebx->fileinfo block
|
||||||
; operation codes:
|
; operation codes:
|
||||||
|
@ -612,6 +612,52 @@ no_mode_0x12:
|
|||||||
mov [mem_BACKGROUND], 4
|
mov [mem_BACKGROUND], 4
|
||||||
mov [img_background], static_background_data
|
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
|
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE
|
||||||
|
|
||||||
stdcall kernel_alloc, 0x10000/8
|
stdcall kernel_alloc, 0x10000/8
|
||||||
@ -752,7 +798,6 @@ end if
|
|||||||
|
|
||||||
mov [pci_access_enabled], 1
|
mov [pci_access_enabled], 1
|
||||||
|
|
||||||
|
|
||||||
; SET PRELIMINARY WINDOW STACK AND POSITIONS
|
; SET PRELIMINARY WINDOW STACK AND POSITIONS
|
||||||
|
|
||||||
mov esi, boot_windefs
|
mov esi, boot_windefs
|
||||||
@ -772,52 +817,6 @@ end if
|
|||||||
call boot_log
|
call boot_log
|
||||||
call reserve_irqs_ports
|
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
|
call init_display
|
||||||
mov eax, [def_cursor]
|
mov eax, [def_cursor]
|
||||||
mov [SLOT_BASE+APPDATA.cursor], eax
|
mov [SLOT_BASE+APPDATA.cursor], eax
|
||||||
@ -931,8 +930,8 @@ end if
|
|||||||
call fs_execute_from_sysdir
|
call fs_execute_from_sysdir
|
||||||
|
|
||||||
; cmp eax,2 ; continue if a process has been loaded
|
; cmp eax,2 ; continue if a process has been loaded
|
||||||
sub eax, 2
|
test eax, eax
|
||||||
jz first_app_found
|
jns first_app_found
|
||||||
|
|
||||||
mov esi, boot_failed
|
mov esi, boot_failed
|
||||||
call boot_log
|
call boot_log
|
||||||
@ -2110,6 +2109,12 @@ sysfn_terminate: ; 18.2 = TERMINATE
|
|||||||
add ecx, CURRENT_TASK+TASKDATA.state
|
add ecx, CURRENT_TASK+TASKDATA.state
|
||||||
cmp byte [ecx], 9
|
cmp byte [ecx], 9
|
||||||
jz noprocessterminate
|
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
|
cmp [_display.select_cursor], 0
|
||||||
je .restore_end
|
je .restore_end
|
||||||
@ -3489,7 +3494,14 @@ nobackgr:
|
|||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
markz:
|
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
|
mov [edx+TASKDATA.state], byte 3
|
||||||
|
@@:
|
||||||
add edx, 0x20
|
add edx, 0x20
|
||||||
loop markz
|
loop markz
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
|
@ -137,7 +137,7 @@ struct APPDATA
|
|||||||
ipc_size dd ?
|
ipc_size dd ?
|
||||||
event_mask dd ?
|
event_mask dd ?
|
||||||
debugger_slot dd ?
|
debugger_slot dd ?
|
||||||
dd ?
|
terminate_protection dd ?
|
||||||
keyboard_mode db ?
|
keyboard_mode db ?
|
||||||
rb 3
|
rb 3
|
||||||
dir_table dd ?
|
dir_table dd ?
|
||||||
|
Loading…
Reference in New Issue
Block a user