? autom4te.cache ? build-debug ? build-debug-o ? range-warnings-fixes.diff ? warning-range-fixes.diff Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.457 diff -c -r1.457 configure.in *** configure.in 8 Jun 2004 08:17:41 -0000 1.457 --- configure.in 12 Jun 2004 10:14:42 -0000 *************** *** 2765,2770 **** --- 2765,2775 ---- [Define this if you have flockfile(), getc_unlocked(), and funlockfile()]) fi + # check for readline 2.1 + AC_CHECK_LIB(readline, rl_callback_handler_install, + AC_DEFINE(HAVE_RL_CALLBACK, 1, + [Define if you have readline 2.1]), , -ltermcap) + # check for readline 2.2 AC_TRY_CPP([#include ], have_readline=yes, have_readline=no) *************** *** 2786,2791 **** --- 2791,2807 ---- AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, [Define if you have readline 4.2]), , -ltermcap) + # also in readline 4.2 + AC_TRY_CPP([#include ], + have_readline=yes, have_readline=no) + if test $have_readline = yes + then + AC_EGREP_HEADER([extern int rl_catch_signals;], + [readline/readline.h], + AC_DEFINE(HAVE_RL_CATCH_SIGNAL, 1, + [Define if you can turn off readline's signal handling.]), ) + fi + AC_MSG_CHECKING(for broken nice()) AC_CACHE_VAL(ac_cv_broken_nice, [ AC_TRY_RUN([ Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.97 diff -c -r1.97 pyconfig.h.in *** pyconfig.h.in 8 Jun 2004 08:17:41 -0000 1.97 --- pyconfig.h.in 12 Jun 2004 10:14:42 -0000 *************** *** 359,364 **** --- 359,370 ---- /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH + /* Define if you have readline 2.1 */ + #undef HAVE_RL_CALLBACK + + /* Define if you can turn off readline's signal handling. */ + #undef HAVE_RL_CATCH_SIGNAL + /* Define if you have readline 2.2 */ #undef HAVE_RL_COMPLETION_APPEND_CHARACTER Index: Lib/test/test_threadsignals.py =================================================================== RCS file: Lib/test/test_threadsignals.py diff -N Lib/test/test_threadsignals.py *** /dev/null 1 Jan 1970 00:00:00 -0000 --- Lib/test/test_threadsignals.py 12 Jun 2004 10:14:44 -0000 *************** *** 0 **** --- 1,77 ---- + """PyUnit testing that threads honor our signal semantics""" + + import unittest + import thread + import signal + import os + from test import test_support + + signal_blackboard = { signal.SIGUSR1 : {'tripped': 0, 'tripped_by': 0 }, + signal.SIGUSR2 : {'tripped': 0, 'tripped_by': 0 }, + signal.SIGALRM : {'tripped': 0, 'tripped_by': 0 } } + + process_pid = os.getpid() + signalled_all=thread.allocate_lock() + + + def registerSignals((for_usr1, for_usr2, for_alrm)): + usr1 = signal.signal(signal.SIGUSR1, for_usr1) + usr2 = signal.signal(signal.SIGUSR2, for_usr2) + alrm = signal.signal(signal.SIGALRM, for_alrm) + return usr1, usr2, alrm + + + # The signal handler. Just note that the signal occured and + # from who. + def handle_signals(sig,frame): + signal_blackboard[sig]['tripped'] += 1 + signal_blackboard[sig]['tripped_by'] = thread.get_ident() + + # a function that will be spawned as a separate thread. + def send_signals(): + os.kill(process_pid, signal.SIGUSR1) + os.kill(process_pid, signal.SIGUSR2) + signalled_all.release() + + class ThreadSignals(unittest.TestCase): + """Test signal handling semantics of threads. + We spawn a thread, have the thread send two signals, and + wait for it to finish. Check that we got both signals + and that they were run by the main thread. + """ + def test_signals(self): + signalled_all.acquire() + self.spawnSignallingThread() + signalled_all.acquire() + # the signals that we asked the kernel to send + # will come back, but we don't know when. + # (it might even be after the thread exits + # and might be out of order.) If we haven't seen + # the signals yet, send yet another signal and + # wait for it return. + if signal_blackboard[signal.SIGUSR2]['tripped'] == 0 \ + or signal_blackboard[signal.SIGUSR2]['tripped'] == 0: + signal.alarm(1) + signal.pause() + signal.alarm(0) + + self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped'], 1) + self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped_by'], + thread.get_ident()) + self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped'], 1) + self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped_by'], + thread.get_ident()) + + def spawnSignallingThread(self): + thread.start_new_thread(send_signals, ()) + + + def test_main(): + oldsigs = registerSignals((handle_signals, handle_signals, handle_signals)) + try: + test_support.run_unittest(ThreadSignals) + finally: + registerSignals(oldsigs) + + if __name__ == '__main__': + test_main() Index: Misc/ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.264 diff -c -r1.264 ACKS *** Misc/ACKS 10 Jun 2004 18:42:15 -0000 1.264 --- Misc/ACKS 12 Jun 2004 10:14:45 -0000 *************** *** 323,328 **** --- 323,329 ---- Andrew Kuchling Vladimir Kushnir Cameron Laird + Andrew Langmead Detlef Lannert Soren Larsen Piers Lauder Index: Modules/readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.70 diff -c -r2.70 readline.c *** Modules/readline.c 24 May 2004 14:20:15 -0000 2.70 --- Modules/readline.c 12 Jun 2004 10:14:45 -0000 *************** *** 656,661 **** --- 656,713 ---- #endif } + /* Wrapper around GNU readline that handles signals differently. */ + + + #if defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT) + + static char *completed_input_string; + static void + rlhandler(char *text) + { + completed_input_string = text; + rl_callback_handler_remove(); + } + + static char * + readline_until_enter_or_signal(char *prompt, int *signal) + { + char * not_done_reading = ""; + fd_set selectset; + + *signal = 0; + #ifdef HAVE_RL_CATCH_SIGNAL + rl_catch_signals = 0; + #endif + + rl_callback_handler_install (prompt, rlhandler); + FD_ZERO(&selectset); + FD_SET(fileno(rl_instream), &selectset); + + completed_input_string = not_done_reading; + + while(completed_input_string == not_done_reading) { + int has_input; + + has_input = select(fileno(rl_instream) + 1, &selectset, + NULL, NULL, NULL); + if(has_input > 0) { + rl_callback_read_char(); + } + else if (errno == EINTR) { + rl_free_line_state(); + rl_cleanup_after_signal(); + rl_callback_handler_remove(); + *signal = 1; + return NULL; + } + } + + return completed_input_string; + } + + + #else /* Interrupt handler */ *************** *** 669,682 **** } - /* Wrapper around GNU readline that handles signals differently. */ - static char * ! call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt) { - size_t n; - char *p, *q; PyOS_sighandler_t old_inthandler; old_inthandler = PyOS_setsig(SIGINT, onintr); if (setjmp(jbuf)) { --- 721,733 ---- } static char * ! readline_until_enter_or_signal(char *prompt, int *signal) { PyOS_sighandler_t old_inthandler; + char *p; + + *signal = 0; old_inthandler = PyOS_setsig(SIGINT, onintr); if (setjmp(jbuf)) { *************** *** 685,692 **** --- 736,759 ---- sigrelse(SIGINT); #endif PyOS_setsig(SIGINT, old_inthandler); + *signal = 1; return NULL; } + p = readline(prompt); + PyOS_setsig(SIGINT, old_inthandler); + + return p; + } + #endif /*defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT) */ + + + static char * + call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt) + { + size_t n; + char *p, *q; + int signal; + rl_event_hook = PyOS_InputHook; if (sys_stdin != rl_instream || sys_stdout != rl_outstream) { *************** *** 697,712 **** #endif } ! p = readline(prompt); ! PyOS_setsig(SIGINT, old_inthandler); ! /* We must return a buffer allocated with PyMem_Malloc. */ if (p == NULL) { p = PyMem_Malloc(1); if (p != NULL) *p = '\0'; return p; } n = strlen(p); if (n > 0) { char *line; --- 764,785 ---- #endif } ! p = readline_until_enter_or_signal(prompt, &signal); ! ! /* we got an interrupt signal */ ! if(signal) { ! return NULL; ! } ! /* We got an EOF, return a empty string. */ if (p == NULL) { p = PyMem_Malloc(1); if (p != NULL) *p = '\0'; return p; } + + /* we have a valid line */ n = strlen(p); if (n > 0) { char *line; Index: Parser/myreadline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/myreadline.c,v retrieving revision 2.30 diff -c -r2.30 myreadline.c *** Parser/myreadline.c 19 Nov 2003 15:24:46 -0000 2.30 --- Parser/myreadline.c 12 Jun 2004 10:14:45 -0000 *************** *** 176,180 **** --- 176,183 ---- rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, prompt); Py_END_ALLOW_THREADS + + PyErr_CheckSignals(); + return rv; } Index: Python/ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.399 diff -c -r2.399 ceval.c *** Python/ceval.c 8 Jun 2004 08:17:43 -0000 2.399 --- Python/ceval.c 12 Jun 2004 10:14:46 -0000 *************** *** 320,326 **** int Py_AddPendingCall(int (*func)(void *), void *arg) { ! static int busy = 0; int i, j; /* XXX Begin critical section */ /* XXX If you want this to be safe against nested --- 320,326 ---- int Py_AddPendingCall(int (*func)(void *), void *arg) { ! static volatile int busy = 0; int i, j; /* XXX Begin critical section */ /* XXX If you want this to be safe against nested Index: Python/thread_pthread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_pthread.h,v retrieving revision 2.52 diff -c -r2.52 thread_pthread.h *** Python/thread_pthread.h 4 Mar 2004 06:35:57 -0000 2.52 --- Python/thread_pthread.h 12 Jun 2004 10:14:46 -0000 *************** *** 119,125 **** { pthread_t th; int status; - sigset_t oldmask, newmask; #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) pthread_attr_t attrs; #endif --- 119,124 ---- *************** *** 137,149 **** pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); #endif - /* Mask all signals in the current thread before creating the new - * thread. This causes the new thread to start with all signals - * blocked. - */ - sigfillset(&newmask); - SET_THREAD_SIGMASK(SIG_BLOCK, &newmask, &oldmask); - status = pthread_create(&th, #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) &attrs, --- 136,141 ---- *************** *** 154,162 **** (void *)arg ); - /* Restore signal mask for original thread */ - SET_THREAD_SIGMASK(SIG_SETMASK, &oldmask, NULL); - #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) pthread_attr_destroy(&attrs); #endif --- 146,151 ----