Changeset 391 for python/trunk/Mac/Modules/autoGIL.c
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Mac/Modules/autoGIL.c
r2 r391 17 17 18 18 static void autoGILCallback(CFRunLoopObserverRef observer, 19 20 21 19 CFRunLoopActivity activity, 20 void *info) { 21 PyThreadState **p_tstate = (PyThreadState **)info; 22 22 23 24 25 23 switch (activity) { 24 case kCFRunLoopBeforeWaiting: 25 /* going to sleep, release GIL */ 26 26 #ifdef AUTOGIL_DEBUG 27 27 fprintf(stderr, "going to sleep, release GIL\n"); 28 28 #endif 29 30 31 32 29 *p_tstate = PyEval_SaveThread(); 30 break; 31 case kCFRunLoopAfterWaiting: 32 /* waking up, acquire GIL */ 33 33 #ifdef AUTOGIL_DEBUG 34 34 fprintf(stderr, "waking up, acquire GIL\n"); 35 35 #endif 36 37 38 39 40 41 36 PyEval_RestoreThread(*p_tstate); 37 *p_tstate = NULL; 38 break; 39 default: 40 break; 41 } 42 42 } 43 43 44 44 static void infoRelease(const void *info) { 45 46 47 45 /* XXX This should get called when the run loop is deallocated, 46 but this doesn't seem to happen. So for now: leak. */ 47 PyMem_Free((void *)info); 48 48 } 49 49 … … 51 51 autoGIL_installAutoGIL(PyObject *self) 52 52 { 53 54 55 56 57 58 53 PyObject *tstate_dict = PyThreadState_GetDict(); 54 PyObject *v; 55 CFRunLoopRef rl; 56 PyThreadState **p_tstate; /* for use in the info field */ 57 CFRunLoopObserverContext context = {0, NULL, NULL, NULL, NULL}; 58 CFRunLoopObserverRef observer; 59 59 60 61 62 63 64 65 66 67 60 if (tstate_dict == NULL) 61 return NULL; 62 v = PyDict_GetItemString(tstate_dict, "autoGIL.InstalledAutoGIL"); 63 if (v != NULL) { 64 /* we've already installed a callback for this thread */ 65 Py_INCREF(Py_None); 66 return Py_None; 67 } 68 68 69 70 71 72 73 74 69 rl = CFRunLoopGetCurrent(); 70 if (rl == NULL) { 71 PyErr_SetString(AutoGILError, 72 "can't get run loop for current thread"); 73 return NULL; 74 } 75 75 76 77 78 79 80 81 82 83 84 85 76 p_tstate = PyMem_Malloc(sizeof(PyThreadState *)); 77 if (p_tstate == NULL) { 78 PyErr_SetString(PyExc_MemoryError, 79 "not enough memory to allocate " 80 "tstate pointer"); 81 return NULL; 82 } 83 *p_tstate = NULL; 84 context.info = (void *)p_tstate; 85 context.release = infoRelease; 86 86 87 88 89 90 91 92 93 94 95 96 97 87 observer = CFRunLoopObserverCreate( 88 NULL, 89 kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting, 90 1, 0, autoGILCallback, &context); 91 if (observer == NULL) { 92 PyErr_SetString(AutoGILError, 93 "can't create event loop observer"); 94 return NULL; 95 } 96 CFRunLoopAddObserver(rl, observer, kCFRunLoopDefaultMode); 97 /* XXX how to check for errors? */ 98 98 99 100 101 102 99 /* register that we have installed a callback for this thread */ 100 if (PyDict_SetItemString(tstate_dict, "autoGIL.InstalledAutoGIL", 101 Py_None) < 0) 102 return NULL; 103 103 104 105 104 Py_INCREF(Py_None); 105 return Py_None; 106 106 } 107 107 … … 115 115 116 116 static PyMethodDef autoGIL_methods[] = { 117 118 119 120 121 122 123 117 { 118 "installAutoGIL", 119 (PyCFunction)autoGIL_installAutoGIL, 120 METH_NOARGS, 121 autoGIL_installAutoGIL_doc 122 }, 123 { 0, 0, 0, 0 } /* sentinel */ 124 124 }; 125 125 … … 133 133 initautoGIL(void) 134 134 { 135 135 PyObject *mod; 136 136 137 138 137 if (PyErr_WarnPy3k("In 3.x, the autoGIL module is removed.", 1) < 0) 138 return; 139 139 140 141 142 143 144 145 146 147 148 149 150 151 140 mod = Py_InitModule4("autoGIL", autoGIL_methods, autoGIL_docs, 141 NULL, PYTHON_API_VERSION); 142 if (mod == NULL) 143 return; 144 AutoGILError = PyErr_NewException("autoGIL.AutoGILError", 145 PyExc_Exception, NULL); 146 if (AutoGILError == NULL) 147 return; 148 Py_INCREF(AutoGILError); 149 if (PyModule_AddObject(mod, "AutoGILError", 150 AutoGILError) < 0) 151 return; 152 152 }
Note:
See TracChangeset
for help on using the changeset viewer.