Commit 73fd8884 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Try and avoid blocking callbacks

  The kernel has a 'callback postponement flag' which will be set whenever an X SWI, called from user mode, returns a pointer to an error (and the error block looks like it's in RAM).
  Although this flag will help prevent the error buffer from being overwritten by any errors generated by callbacks, it will also have the effect of blocking Alt-Break and CLib's Escape handler, due to them both being reliant on callbacks.
  Since the flag may persist for a long time, it can be dangerous to leave the OS in this state (the flag can only be cleared by a SWI call from user mode - which may never happen if the program is stuck in a bad state).
  So to combat this, CLib will now make some effort to try and avoid leaving the postponement flag in situations where it shouldn't be needed.
  File changes:
  - c/armsys:
    - Change _sys_flen to return 0 for TTY streams, since calling OS_Args for them isn't going to generate any useful result (previously it was generating an error, causing the postponement flag to be left set on entry to main())
    - Be extra vigilant when entering main() to make sure the callback postponement flag isn't set, just in case other checks don't resolve it
  - kernel/s/k_body:
    - Change CopyError to attempt to clear the callback postponement flag if we suspect it's set. We've just copied the error to our own buffer, so it should be our job to worry about preventing that buffer being prematurely overwritten, not the kernel's.
  Tested on BB-xM
  'while (1) {}' (and similar variants) now multitasks in task windows and is no longer unkillable
  Fixes issue reported on forums:

Version 5.96. Tagged as 'RISC_OSLib-5_96'
parent e4577090
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
GBLS Module_HelpVersion GBLS Module_HelpVersion
GBLS Module_ComponentName GBLS Module_ComponentName
GBLS Module_ComponentPath GBLS Module_ComponentPath
Module_MajorVersion SETS "5.95" Module_MajorVersion SETS "5.96"
Module_Version SETA 595 Module_Version SETA 596
Module_MinorVersion SETS "" Module_MinorVersion SETS ""
Module_Date SETS "14 Apr 2018" Module_Date SETS "10 Jun 2018"
Module_ApplicationDate SETS "14-Apr-18" Module_ApplicationDate SETS "10-Jun-18"
Module_ComponentName SETS "RISC_OSLib" Module_ComponentName SETS "RISC_OSLib"
Module_ComponentPath SETS "castle/RiscOS/Sources/Lib/RISC_OSLib" Module_ComponentPath SETS "castle/RiscOS/Sources/Lib/RISC_OSLib"
Module_FullVersion SETS "5.95" Module_FullVersion SETS "5.96"
Module_HelpVersion SETS "5.95 (14 Apr 2018)" Module_HelpVersion SETS "5.96 (10 Jun 2018)"
/* (5.95) /* (5.96)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1. * Last processed by srccommit version: 1.1.
* *
*/ */
#define Module_MajorVersion_CMHG 5.95 #define Module_MajorVersion_CMHG 5.96
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 14 Apr 2018 #define Module_Date_CMHG 10 Jun 2018
#define Module_MajorVersion "5.95" #define Module_MajorVersion "5.96"
#define Module_Version 595 #define Module_Version 596
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "14 Apr 2018" #define Module_Date "10 Jun 2018"
#define Module_ApplicationDate "14-Apr-18" #define Module_ApplicationDate "10-Jun-18"
#define Module_ComponentName "RISC_OSLib" #define Module_ComponentName "RISC_OSLib"
#define Module_ComponentPath "castle/RiscOS/Sources/Lib/RISC_OSLib" #define Module_ComponentPath "castle/RiscOS/Sources/Lib/RISC_OSLib"
#define Module_FullVersion "5.95" #define Module_FullVersion "5.96"
#define Module_HelpVersion "5.95 (14 Apr 2018)" #define Module_HelpVersion "5.96 (10 Jun 2018)"
#define Module_LibraryVersionInfo "5:95" #define Module_LibraryVersionInfo "5:96"
...@@ -395,6 +395,7 @@ int _sys_seek(FILEHANDLE fh, off64_t pos) ...@@ -395,6 +395,7 @@ int _sys_seek(FILEHANDLE fh, off64_t pos)
off64_t _sys_flen(FILEHANDLE fh) off64_t _sys_flen(FILEHANDLE fh)
{ {
if istty(fh) return 0;
#if 1 #if 1
/* Can't use _kernel_osargs, even for 32-bit file pointers, because it can't handle files of size 4G-2 .*/ /* Can't use _kernel_osargs, even for 32-bit file pointers, because it can't handle files of size 4G-2 .*/
/* Use _kernel_swi instead so that _kernel_last_oserror is set up on failure like it always was. */ /* Use _kernel_swi instead so that _kernel_last_oserror is set up on failure like it always was. */
...@@ -866,6 +867,9 @@ no_redirection: ...@@ -866,6 +867,9 @@ no_redirection:
} }
/* Clear any callback postponement flag in the kernel - otherwise programs which execute no SWIs may be completely uninterruptible */
argv[argc] = 0; /* for ANSI spec */ argv[argc] = 0; /* for ANSI spec */
exit(/* hmm, relies on lots of things, but fast! */ exit(/* hmm, relies on lots of things, but fast! */
(argc > 0 && (*(int *)argv[0] & ~0x20202020) == *(int *)"RUN") ? (argc > 0 && (*(int *)argv[0] & ~0x20202020) == *(int *)"RUN") ?
...@@ -2512,7 +2512,26 @@ CopyErrorString ...@@ -2512,7 +2512,26 @@ CopyErrorString
STRB a3, [a2], #+1 STRB a3, [a2], #+1
BICS a3, a3, #&1F ; replaces CMP a3, #' ' BICS a3, a3, #&1F ; replaces CMP a3, #' '
BNE %B01 ; replaces BCS %B01 BNE %B01 ; replaces BCS %B01
; We're probably here because a SWI returned an error. This probably
; also means that the kernel has set the callback postponement flag -
; a flag designed to prevent global error buffers being clobbered by
; callbacks. However we've just copied the error into our own private
; buffer, so there's no need for the kernel to postpone callbacks. In
; fact, postponing callbacks can be harmful, potentially preventing the
; user from quitting a malfunctioning app, due to both CLib's Escape
; handler and Alt-Break being reliant on callbacks. So if we're in user
; mode, do a dummy SWI to clear the postponement flag.
[ {CONFIG} = 26
TST lr, #PSRIBit+PSRPrivileged
MOVS pc, lr
TST a3, #PSR32IBit+PSR32Privileged
MSR CPSR_c, a3
MOV pc, lr MOV pc, lr
|_kernel_getenv| |_kernel_getenv|
; _kernel_oserror *_kernel_getenv(const char *name, char *buffer, unsigned size); ; _kernel_oserror *_kernel_getenv(const char *name, char *buffer, unsigned size);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment