X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Flib_setup.c;h=33cf2f96195f3ee06010e66b7abbadcf7d4a6346;hp=67a2a0aa828eafcbfd29efc59fd950154ad76ac2;hb=bca50d0d8592defee6c584fdedd25f4b1a31345b;hpb=5e1e572b71ae31a6071daa24e2460a68a6f1003c diff --git a/ncurses/tinfo/lib_setup.c b/ncurses/tinfo/lib_setup.c index 67a2a0aa..33cf2f96 100644 --- a/ncurses/tinfo/lib_setup.c +++ b/ncurses/tinfo/lib_setup.c @@ -48,7 +48,7 @@ #include #endif -MODULE_ID("$Id: lib_setup.c,v 1.178 2017/04/11 23:51:32 tom Exp $") +MODULE_ID("$Id: lib_setup.c,v 1.188 2017/07/01 18:24:50 tom Exp $") /**************************************************************************** * @@ -115,12 +115,12 @@ NCURSES_PUBLIC_VAR(ttytype) (void) if (CURRENT_SCREEN) { TERMINAL *termp = TerminalOf(CURRENT_SCREEN); if (termp != 0) { - result = termp->type.term_names; + result = TerminalType(termp).term_names; } } #else if (cur_term != 0) { - result = cur_term->type.term_names; + result = TerminalType(cur_term).term_names; } #endif return result; @@ -693,7 +693,7 @@ TINFO_SETUP_TERM(TERMINAL **tp, && termp->Filedes == Filedes && termp->_termname != 0 && !strcmp(termp->_termname, tname) - && _nc_name_match(termp->type.term_names, tname, "|")) { + && _nc_name_match(TerminalType(termp).term_names, tname, "|")) { T(("reusing existing terminal information and mode-settings")); code = OK; #ifdef USE_TERM_DRIVER @@ -702,8 +702,9 @@ TINFO_SETUP_TERM(TERMINAL **tp, } else { #ifdef USE_TERM_DRIVER TERMINAL_CONTROL_BLOCK *my_tcb; - my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1); - termp = &(my_tcb->term); + termp = 0; + if ((my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1)) != 0) + termp = &(my_tcb->term); #else int status; @@ -721,6 +722,8 @@ TINFO_SETUP_TERM(TERMINAL **tp, termp->Filedes = (short) Filedes; termp->_termname = strdup(tname); } else { + _nc_free_termtype2(&TerminalType(termp)); + free(my_tcb); ret_error0(errret ? *errret : TGETENT_ERR, "Could not find any driver to handle this terminal.\n"); } @@ -753,9 +756,7 @@ TINFO_SETUP_TERM(TERMINAL **tp, _nc_export_termtype2(&termp->type, &TerminalType(termp)); #endif #if !USE_REENTRANT -#define MY_SIZE (size_t) (NAMESIZE - 1) - _nc_STRNCPY(ttytype, termp->type.term_names, MY_SIZE); - ttytype[MY_SIZE] = '\0'; + save_ttytype(termp); #endif termp->Filedes = (short) Filedes; @@ -818,6 +819,48 @@ TINFO_SETUP_TERM(TERMINAL **tp, returnCode(code); } +#ifdef USE_PTHREADS +/* + * Returns a non-null pointer unless a new screen should be allocated because + * no match was found in the pre-screen cache. + */ +NCURSES_EXPORT(SCREEN *) +_nc_find_prescr(void) +{ + SCREEN *result = 0; + PRESCREEN_LIST *p; + for (p = _nc_prescreen.allocated; p != 0; p = p->next) { + if (p->id == pthread_self()) { + result = p->sp; + break; + } + } + return result; +} + +/* + * Tells ncurses to forget that this thread was associated with the pre-screen + * cache. It does not modify the pre-screen cache itself, since that is used + * for creating new screens. + */ +NCURSES_EXPORT(void) +_nc_forget_prescr(void) +{ + PRESCREEN_LIST *p, *q; + for (p = _nc_prescreen.allocated, q = 0; p != 0; q = p, p = p->next) { + if (p->id == pthread_self()) { + if (q) { + q->next = p->next; + } else { + _nc_prescreen.allocated = p->next; + } + free(p); + break; + } + } +} +#endif /* USE_PTHREADS */ + #if NCURSES_SP_FUNCS /* * In case of handling multiple screens, we need to have a screen before @@ -833,25 +876,41 @@ new_prescr(void) START_TRACE(); T((T_CALLED("new_prescr()"))); - sp = _nc_alloc_screen_sp(); - T(("_nc_alloc_screen_sp %p", (void *) sp)); - if (sp != 0) { - _nc_prescreen.allocated = sp; - sp->rsp = sp->rippedoff; - sp->_filtered = _nc_prescreen.filter_mode; - sp->_use_env = _nc_prescreen.use_env; + _nc_lock_global(screen); + if ((sp = _nc_find_prescr()) == 0) { + sp = _nc_alloc_screen_sp(); + T(("_nc_alloc_screen_sp %p", (void *) sp)); + if (sp != 0) { +#ifdef USE_PTHREADS + PRESCREEN_LIST *p = typeCalloc(PRESCREEN_LIST, 1); + if (p != 0) { + p->id = pthread_self(); + p->sp = sp; + p->next = _nc_prescreen.allocated; + _nc_prescreen.allocated = p; + } +#else + _nc_prescreen.allocated = sp; +#endif + sp->rsp = sp->rippedoff; + sp->_filtered = _nc_prescreen.filter_mode; + sp->_use_env = _nc_prescreen.use_env; #if NCURSES_NO_PADDING - sp->_no_padding = _nc_prescreen._no_padding; + sp->_no_padding = _nc_prescreen._no_padding; #endif - sp->slk_format = 0; - sp->_slk = 0; - sp->_prescreen = TRUE; - SP_PRE_INIT(sp); + sp->slk_format = 0; + sp->_slk = 0; + sp->_prescreen = TRUE; + SP_PRE_INIT(sp); #if USE_REENTRANT - sp->_TABSIZE = _nc_prescreen._TABSIZE; - sp->_ESCDELAY = _nc_prescreen._ESCDELAY; + sp->_TABSIZE = _nc_prescreen._TABSIZE; + sp->_ESCDELAY = _nc_prescreen._ESCDELAY; #endif + } + } else { + T(("_nc_alloc_screen_sp %p (reuse)", (void *) sp)); } + _nc_unlock_global(screen); returnSP(sp); } #endif @@ -867,12 +926,19 @@ _nc_setupterm(NCURSES_CONST char *tname, int *errret, int reuse) { - int res; + int rc = ERR; TERMINAL *termp = 0; - res = TINFO_SETUP_TERM(&termp, tname, Filedes, errret, reuse); - if (ERR != res) - NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN_PRE, termp); - return res; + + _nc_lock_global(prescreen); + START_TRACE(); + if (TINFO_SETUP_TERM(&termp, tname, Filedes, errret, reuse) == OK) { + _nc_forget_prescr(); + if (NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN_PRE, termp) != 0) { + rc = OK; + } + } + _nc_unlock_global(prescreen); + return rc; } #endif