[Python-checkins] r59461 - in python/branches/release25-maint: Misc/ACKS Modules/signalmodule.c

guido.van.rossum python-checkins at python.org
Tue Dec 11 00:03:56 CET 2007


Author: guido.van.rossum
Date: Tue Dec 11 00:03:55 2007
New Revision: 59461

Modified:
   python/branches/release25-maint/Misc/ACKS
   python/branches/release25-maint/Modules/signalmodule.c
Log:
Backport patch #1643738.


Modified: python/branches/release25-maint/Misc/ACKS
==============================================================================
--- python/branches/release25-maint/Misc/ACKS	(original)
+++ python/branches/release25-maint/Misc/ACKS	Tue Dec 11 00:03:55 2007
@@ -216,6 +216,7 @@
 Gyro Funch
 Peter Funk
 Geoff Furnish
+Ulisses Furquim
 Lele Gaifax
 Yitzchak Gale
 Raymund Galvin

Modified: python/branches/release25-maint/Modules/signalmodule.c
==============================================================================
--- python/branches/release25-maint/Modules/signalmodule.c	(original)
+++ python/branches/release25-maint/Modules/signalmodule.c	Tue Dec 11 00:03:55 2007
@@ -75,7 +75,8 @@
         PyObject *func;
 } Handlers[NSIG];
 
-static int is_tripped = 0; /* Speed up sigcheck() when none tripped */
+/* Speed up sigcheck() when none tripped */
+static volatile sig_atomic_t is_tripped = 0;
 
 static PyObject *DefaultHandler;
 static PyObject *IgnoreHandler;
@@ -122,8 +123,10 @@
 	/* See NOTES section above */
 	if (getpid() == main_pid) {
 #endif
-		is_tripped++;
 		Handlers[sig_num].tripped = 1;
+                /* Set is_tripped after setting .tripped, as it gets
+                   cleared in PyErr_CheckSignals() before .tripped. */
+		is_tripped = 1;
 		Py_AddPendingCall(checksignals_witharg, NULL);
 #ifdef WITH_THREAD
 	}
@@ -597,13 +600,31 @@
 
 	if (!is_tripped)
 		return 0;
+
 #ifdef WITH_THREAD
 	if (PyThread_get_thread_ident() != main_thread)
 		return 0;
 #endif
+
+	/*
+	 * The is_stripped variable is meant to speed up the calls to
+	 * PyErr_CheckSignals (both directly or via pending calls) when no
+	 * signal has arrived. This variable is set to 1 when a signal arrives
+	 * and it is set to 0 here, when we know some signals arrived. This way
+	 * we can run the registered handlers with no signals blocked.
+	 *
+	 * NOTE: with this approach we can have a situation where is_tripped is
+	 *       1 but we have no more signals to handle (Handlers[i].tripped
+	 *       is 0 for every signal i). This won't do us any harm (except
+	 *       we're gonna spent some cycles for nothing). This happens when
+	 *       we receive a signal i after we zero is_tripped and before we
+	 *       check Handlers[i].tripped.
+	 */
+	is_tripped = 0;
+
 	if (!(f = (PyObject *)PyEval_GetFrame()))
 		f = Py_None;
-	
+
 	for (i = 1; i < NSIG; i++) {
 		if (Handlers[i].tripped) {
 			PyObject *result = NULL;
@@ -621,7 +642,7 @@
 			Py_DECREF(result);
 		}
 	}
-	is_tripped = 0;
+
 	return 0;
 }
 
@@ -632,7 +653,7 @@
 void
 PyErr_SetInterrupt(void)
 {
-	is_tripped++;
+	is_tripped = 1;
 	Handlers[SIGINT].tripped = 1;
 	Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
 }


More information about the Python-checkins mailing list