Armin Rigo avatar Armin Rigo committed acc8154

Consolidate again the enter/exit functions in a single '_thread.atomic' object.

Comments (0)

Files changed (1)

Modules/_threadmodule.c

     Py_RETURN_NONE;
 }
 
+
+/* The type of the "atomic" singleton */
+
+static PyObject *atomic_enter(PyObject *self)
+{
+    if (ts_atomic_counter == 0) {
+        assert(_PyEval_GetWithAtomic() == NULL);
+        _PyEval_SetWithAtomic(PyThreadState_Get());
+    }
+    else
+        assert(_PyEval_GetWithAtomic() == PyThreadState_Get());
+    ts_atomic_counter++;
+    Py_RETURN_NONE;
+}
+
+static PyObject *atomic_exit(PyObject *self)
+{
+    if (ts_atomic_counter == 0) {
+        PyErr_SetString(ThreadError,
+            "_thread.atomic_exit() called more often that atomic_enter()");
+        return NULL;
+    }
+    assert(_PyEval_GetWithAtomic() == PyThreadState_Get());
+    ts_atomic_counter--;
+    if (ts_atomic_counter == 0)
+        _PyEval_SetWithAtomic(NULL);
+    Py_RETURN_NONE;
+}
+
+static PyMethodDef atomic_methods[] = {
+    {"__enter__", (PyCFunction)atomic_enter, METH_NOARGS},
+    {"__exit__",  (PyCFunction)atomic_exit,  METH_VARARGS},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyTypeObject atomic_type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    /* tp_name           */ "_thread.Atomic",
+    /* tp_size           */ sizeof(PyObject),
+    /* tp_itemsize       */ 0,
+    /* tp_dealloc        */ 0,
+    /* tp_print          */ 0,
+    /* tp_getattr        */ 0,
+    /* tp_setattr        */ 0,
+    /* reserved          */ 0,
+    /* tp_repr           */ 0,
+    /* tp_as_number      */ 0,
+    /* tp_as_sequence    */ 0,
+    /* tp_as_mapping     */ 0,
+    /* tp_hash           */ 0,
+    /* tp_call           */ 0,
+    /* tp_str            */ 0,
+    /* tp_getattro       */ 0,
+    /* tp_setattro       */ 0,
+    /* tp_as_buffer      */ 0,
+    /* tp_flags          */ Py_TPFLAGS_DEFAULT,
+    /* tp_doc            */ "Type of _thread.atomic",
+    /* tp_traverse       */ 0,
+    /* tp_clear          */ 0,
+    /* tp_richcompare    */ 0,
+    /* tp_weaklistoffset */ 0,
+    /* tp_iter           */ 0,
+    /* tp_iternext       */ 0,
+    /* tp_methods        */ atomic_methods,
+};
+
+static PyObject atomic_object;
+
 /* Module functions */
 
 struct bootstate {
 (4kB pages are common; using multiples of 4096 for the stack size is\n\
 the suggested approach in the absence of more specific information).");
 
-static PyObject *
-thread_atomic_enter(PyObject *self)
-{
-    if (ts_atomic_counter == 0) {
-        assert(_PyEval_GetWithAtomic() == NULL);
-        _PyEval_SetWithAtomic(PyThreadState_Get());
-    }
-    else
-        assert(_PyEval_GetWithAtomic() == PyThreadState_Get());
-    ts_atomic_counter++;
-    Py_RETURN_NONE;
-}
-
-static PyObject *
-thread_atomic_exit(PyObject *self)
-{
-    if (ts_atomic_counter == 0) {
-        PyErr_SetString(ThreadError,
-            "_thread.atomic_exit() called more often that atomic_enter()");
-        return NULL;
-    }
-    assert(_PyEval_GetWithAtomic() == PyThreadState_Get());
-    ts_atomic_counter--;
-    if (ts_atomic_counter == 0)
-        _PyEval_SetWithAtomic(NULL);
-    Py_RETURN_NONE;
-}
-
 static PyMethodDef thread_methods[] = {
     {"start_new_thread",        (PyCFunction)thread_PyThread_start_new_thread,
      METH_VARARGS, start_new_doc},
      METH_NOARGS, _count_doc},
     {"stack_size",              (PyCFunction)thread_stack_size,
      METH_VARARGS, stack_size_doc},
-    {"atomic_enter",            (PyCFunction)thread_atomic_enter,
-     METH_NOARGS, NULL},
-    {"atomic_exit",             (PyCFunction)thread_atomic_exit,
-     METH_NOARGS, NULL},
     {NULL,                      NULL}           /* sentinel */
 };
 
     if (str_dict == NULL)
         return NULL;
 
+    /* Set up "atomic" */
+    if (PyType_Ready(&atomic_type) < 0)
+        return NULL;
+    if (PyObject_Init(&atomic_object, &atomic_type) == NULL)
+        return NULL;
+    Py_INCREF(&atomic_object);
+    if (PyModule_AddObject(m, "atomic", &atomic_object) < 0)
+        return NULL;
+
     /* Initialize the C thread library */
     PyThread_init_thread();
     return m;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.