[Python-checkins] python/dist/src/Python import.c,2.216,2.217

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Wed, 12 Feb 2003 13:45:32 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv1603

Modified Files:
	import.c 
Log Message:
Provide access to the import lock, fixing SF bug #580952.  This is
mostly from SF patch #683257, but I had to change unlock_import() to
return an error value to avoid fatal error.

Should this be backported?  The patch requested this, but it's a new
feature.


Index: import.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/import.c,v
retrieving revision 2.216
retrieving revision 2.217
diff -C2 -d -r2.216 -r2.217
*** import.c	24 Jan 2003 16:15:45 -0000	2.216
--- import.c	12 Feb 2003 21:45:27 -0000	2.217
***************
*** 253,257 ****
  		return;
  	}
! 	if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0)) {
  		PyThreadState *tstate = PyEval_SaveThread();
  		PyThread_acquire_lock(import_lock, 1);
--- 253,258 ----
  		return;
  	}
! 	if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0))
! 	{
  		PyThreadState *tstate = PyEval_SaveThread();
  		PyThread_acquire_lock(import_lock, 1);
***************
*** 262,273 ****
  }
  
! static void
  unlock_import(void)
  {
  	long me = PyThread_get_thread_ident();
  	if (me == -1)
! 		return; /* Too bad */
  	if (import_lock_thread != me)
! 		Py_FatalError("unlock_import: not holding the import lock");
  	import_lock_level--;
  	if (import_lock_level == 0) {
--- 263,274 ----
  }
  
! static int
  unlock_import(void)
  {
  	long me = PyThread_get_thread_ident();
  	if (me == -1)
! 		return 0; /* Too bad */
  	if (import_lock_thread != me)
! 		return -1;
  	import_lock_level--;
  	if (import_lock_level == 0) {
***************
*** 275,278 ****
--- 276,280 ----
  		PyThread_release_lock(import_lock);
  	}
+ 	return 1;
  }
  
***************
*** 280,284 ****
  
  #define lock_import()
! #define unlock_import()
  
  #endif
--- 282,286 ----
  
  #define lock_import()
! #define unlock_import() 0
  
  #endif
***************
*** 296,299 ****
--- 298,327 ----
  }
  
+ static PyObject *
+ imp_acquire_lock(PyObject *self, PyObject *args)
+ {
+ 	if (!PyArg_ParseTuple(args, ":acquire_lock"))
+ 		return NULL;
+ #ifdef WITH_THREAD
+ 	lock_import();
+ #endif
+     return Py_None;
+ }
+ 
+ static PyObject *
+ imp_release_lock(PyObject *self, PyObject *args)
+ {
+ 	if (!PyArg_ParseTuple(args, ":release_lock"))
+ 		return NULL;
+ #ifdef WITH_THREAD
+ 	if (unlock_import() < 0) {
+ 		PyErr_SetString(PyExc_RuntimeError,
+ 				"not holding the import lock");
+ 		return NULL;
+ 	}
+ #endif
+     return Py_None;
+ }
+ 
  /* Helper for sys */
  
***************
*** 1971,1975 ****
  	lock_import();
  	result = import_module_ex(name, globals, locals, fromlist);
! 	unlock_import();
  	return result;
  }
--- 1999,2008 ----
  	lock_import();
  	result = import_module_ex(name, globals, locals, fromlist);
! 	if (unlock_import() < 0) {
! 		Py_XDECREF(result);
! 		PyErr_SetString(PyExc_RuntimeError,
! 				"not holding the import lock");
! 		return NULL;
! 	}
  	return result;
  }
***************
*** 2744,2747 ****
--- 2777,2791 ----
  On platforms without threads, return 0.");
  
+ PyDoc_STRVAR(doc_acquire_lock,
+ "acquire_lock() -> None\n\
+ Acquires the interpreter's import lock for the current thread.  This lock
+ should be used by import hooks to ensure thread-safety when importing modules.
+ On platforms without threads, this function does nothing.");
+ 
+ PyDoc_STRVAR(doc_release_lock,
+ "release_lock() -> None\n\
+ Release the interpreter's import lock.\n\
+ On platforms without threads, this function does nothing.");
+ 
  static PyMethodDef imp_methods[] = {
  	{"find_module",		imp_find_module, METH_VARARGS, doc_find_module},
***************
*** 2751,2754 ****
--- 2795,2800 ----
  	{"new_module",		imp_new_module,	 METH_VARARGS, doc_new_module},
  	{"lock_held",		imp_lock_held,	 METH_VARARGS, doc_lock_held},
+ 	{"acquire_lock",    imp_acquire_lock, METH_VARARGS, doc_acquire_lock},
+ 	{"release_lock",    imp_release_lock, METH_VARARGS, doc_release_lock},
  	/* The rest are obsolete */
  	{"get_frozen_object",	imp_get_frozen_object,	METH_VARARGS},