mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-12 14:29:28 +00:00
Serialize output routine of terminal emulator (te_puts()) by a lock.
- The output routine of low level console is not protected by any lock by default. - Increment and decrement of sc->write_in_progress are not atomic and this may cause console hang. - We also have many other states used by emulator that should be protected by the lock. - This change does not fix interspersed messages which PRINTF_BUFR_SIZE kernel option should fix. Approved by: re (bmah) MFC after: 1 week
This commit is contained in:
parent
5bcb64f20a
commit
a69d19dc33
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=172250
@ -2510,14 +2510,23 @@ exchange_scr(sc_softc_t *sc)
|
|||||||
void
|
void
|
||||||
sc_puts(scr_stat *scp, u_char *buf, int len)
|
sc_puts(scr_stat *scp, u_char *buf, int len)
|
||||||
{
|
{
|
||||||
|
int need_unlock = 0;
|
||||||
|
|
||||||
#ifdef DEV_SPLASH
|
#ifdef DEV_SPLASH
|
||||||
/* make screensaver happy */
|
/* make screensaver happy */
|
||||||
if (!sticky_splash && scp == scp->sc->cur_scp && !sc_saver_keyb_only)
|
if (!sticky_splash && scp == scp->sc->cur_scp && !sc_saver_keyb_only)
|
||||||
run_scrn_saver = FALSE;
|
run_scrn_saver = FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (scp->tsw)
|
if (scp->tsw) {
|
||||||
|
if (!kdb_active && !mtx_owned(&scp->scr_lock)) {
|
||||||
|
need_unlock = 1;
|
||||||
|
mtx_lock_spin(&scp->scr_lock);
|
||||||
|
}
|
||||||
(*scp->tsw->te_puts)(scp, buf, len);
|
(*scp->tsw->te_puts)(scp, buf, len);
|
||||||
|
if (need_unlock)
|
||||||
|
mtx_unlock_spin(&scp->scr_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (scp->sc->delayed_next_scr)
|
if (scp->sc->delayed_next_scr)
|
||||||
sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
|
sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
|
||||||
@ -2895,6 +2904,7 @@ scterm(int unit, int flags)
|
|||||||
(*scp->tsw->te_term)(scp, &scp->ts);
|
(*scp->tsw->te_term)(scp, &scp->ts);
|
||||||
if (scp->ts != NULL)
|
if (scp->ts != NULL)
|
||||||
free(scp->ts, M_DEVBUF);
|
free(scp->ts, M_DEVBUF);
|
||||||
|
mtx_destroy(&scp->scr_lock);
|
||||||
|
|
||||||
/* clear the structure */
|
/* clear the structure */
|
||||||
if (!(flags & SC_KERNEL_CONSOLE)) {
|
if (!(flags & SC_KERNEL_CONSOLE)) {
|
||||||
@ -3078,6 +3088,8 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
|
|||||||
scp->history = NULL;
|
scp->history = NULL;
|
||||||
scp->history_pos = 0;
|
scp->history_pos = 0;
|
||||||
scp->history_size = 0;
|
scp->history_size = 0;
|
||||||
|
|
||||||
|
mtx_init(&scp->scr_lock, "scrlock", NULL, MTX_SPIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -333,6 +333,7 @@ typedef struct scr_stat {
|
|||||||
|
|
||||||
int splash_save_mode; /* saved mode for splash screen */
|
int splash_save_mode; /* saved mode for splash screen */
|
||||||
int splash_save_status; /* saved status for splash screen */
|
int splash_save_status; /* saved status for splash screen */
|
||||||
|
struct mtx scr_lock; /* mutex for sc_puts() */
|
||||||
#ifdef _SCR_MD_STAT_DECLARED_
|
#ifdef _SCR_MD_STAT_DECLARED_
|
||||||
scr_md_stat_t md; /* machine dependent vars */
|
scr_md_stat_t md; /* machine dependent vars */
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user