Changeset 34


Ignore:
Timestamp:
12/27/05 15:52:07 (9 years ago)
Author:
xi
Message:

Release the GIL before doing blocking calls (fix #35).
Note that this fix makes _syck incompatible with Python 2.2 and earlier.

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/ext/_syckmodule.c

    r25 r34  
    10301030PySyckParser_node_handler(SyckParser *parser, SyckNode *node) 
    10311031{ 
     1032    PyGILState_STATE gs; 
     1033 
    10321034    PySyckParserObject *self = (PySyckParserObject *)parser->bonus; 
    10331035 
     
    10401042    if (self->halt) 
    10411043        return -1; 
     1044 
     1045    gs = PyGILState_Ensure(); 
    10421046 
    10431047    switch (node->kind) { 
     
    10991103 
    11001104    index = PyList_GET_SIZE(self->symbols); 
     1105    PyGILState_Release(gs); 
    11011106    return index; 
    11021107 
    11031108error: 
    11041109    Py_XDECREF(object); 
     1110    PyGILState_Release(gs); 
    11051111    self->halt = 1; 
    11061112    return -1; 
     
    11101116PySyckParser_error_handler(SyckParser *parser, char *str) 
    11111117{ 
     1118    PyGILState_STATE gs; 
     1119 
    11121120    PySyckParserObject *self = (PySyckParserObject *)parser->bonus; 
    11131121    PyObject *value; 
    11141122 
    11151123    if (self->halt) return; 
     1124 
     1125    gs = PyGILState_Ensure(); 
    11161126 
    11171127    self->halt = 1; 
     
    11221132        PyErr_SetObject(PySyck_Error, value); 
    11231133    } 
     1134 
     1135    PyGILState_Release(gs); 
    11241136} 
    11251137 
     
    11271139PySyckParser_bad_anchor_handler(SyckParser *parser, char *anchor) 
    11281140{ 
     1141    PyGILState_STATE gs; 
     1142 
    11291143    PySyckParserObject *self = (PySyckParserObject *)parser->bonus; 
    11301144 
    11311145    if (!self->halt) { 
     1146        gs = PyGILState_Ensure(); 
     1147 
    11321148        self->halt = 1; 
    11331149        PyErr_SetString(PyExc_TypeError, "recursive anchors are not implemented"); 
     1150 
     1151        PyGILState_Release(gs); 
    11341152    } 
    11351153 
     
    11401158PySyckParser_read_handler(char *buf, SyckIoFile *file, long max_size, long skip) 
    11411159{ 
     1160    PyGILState_STATE gs; 
     1161 
    11421162    PySyckParserObject *self = (PySyckParserObject *)file->ptr; 
    11431163 
     
    11541174     
    11551175    max_size -= skip; 
     1176 
     1177    gs = PyGILState_Ensure(); 
    11561178 
    11571179    value = PyObject_CallMethod(self->source, "read", "(i)", max_size); 
    11581180    if (!value) { 
    11591181        self->halt = 1; 
     1182 
     1183        PyGILState_Release(gs); 
     1184 
    11601185        return skip; 
    11611186    } 
     
    11661191        self->halt = 1; 
    11671192         
     1193        PyGILState_Release(gs); 
     1194 
    11681195        return skip; 
    11691196    } 
     
    11731200    if (!length) { 
    11741201        Py_DECREF(value); 
     1202 
     1203        PyGILState_Release(gs); 
     1204 
    11751205        return skip; 
    11761206    } 
     
    11801210        PyErr_SetString(PyExc_ValueError, "read returns an overly long string"); 
    11811211        self->halt = 1; 
     1212 
     1213        PyGILState_Release(gs); 
     1214 
    11821215        return skip; 
    11831216    } 
     
    11881221 
    11891222    Py_DECREF(value); 
     1223 
     1224    PyGILState_Release(gs); 
    11901225 
    11911226    return length; 
     
    12691304 
    12701305    self->parsing = 1; 
     1306    Py_BEGIN_ALLOW_THREADS 
    12711307    index = syck_parse(self->parser)-1; 
     1308    Py_END_ALLOW_THREADS 
    12721309    self->parsing = 0; 
    12731310 
     
    15501587PySyckEmitter_node_handler(SyckEmitter *emitter, st_data_t id) 
    15511588{ 
     1589    PyGILState_STATE gs; 
     1590 
    15521591    PySyckEmitterObject *self = (PySyckEmitterObject *)emitter->bonus; 
    15531592 
     
    15631602    if (self->halt) return; 
    15641603 
     1604    gs = PyGILState_Ensure(); 
     1605 
    15651606    node = (PySyckNodeObject *)PyList_GetItem(self->symbols, id); 
    15661607    if (!node) { 
    15671608        PyErr_SetString(PyExc_RuntimeError, "unknown data id"); 
    15681609        self->halt = 1; 
     1610        PyGILState_Release(gs); 
    15691611        return; 
    15701612    } 
     
    15741616        if (!tag) { 
    15751617            self->halt = 1; 
     1618            PyGILState_Release(gs); 
    15761619            return; 
    15771620        } 
     
    15851628            PyErr_SetString(PyExc_TypeError, "value of _syck.Seq must be a list"); 
    15861629            self->halt = 1; 
     1630            PyGILState_Release(gs); 
    15871631            return; 
    15881632        } 
     
    15921636            if ((index = PyDict_GetItem(self->nodes, item))) { 
    15931637                syck_emit_item(emitter, PyInt_AS_LONG(index)); 
    1594                 if (self->halt) return; 
     1638                if (self->halt) { 
     1639                    PyGILState_Release(gs); 
     1640                    return; 
     1641                } 
    15951642            } 
    15961643            else { 
    15971644                PyErr_SetString(PyExc_RuntimeError, "sequence item is not marked"); 
    15981645                self->halt = 1; 
     1646                PyGILState_Release(gs); 
    15991647                return; 
    16001648            } 
     
    16151663                            "value of _syck.Map must be a list of pairs or a dictionary"); 
    16161664                    self->halt = 1; 
     1665                    PyGILState_Release(gs); 
    16171666                    return; 
    16181667                } 
     
    16211670                    if ((index = PyDict_GetItem(self->nodes, item))) { 
    16221671                        syck_emit_item(emitter, PyInt_AS_LONG(index)); 
    1623                         if (self->halt) return; 
     1672                        if (self->halt) { 
     1673                            PyGILState_Release(gs); 
     1674                            return; 
     1675                        } 
    16241676                    } 
    16251677                    else { 
    16261678                        PyErr_SetString(PyExc_RuntimeError, "mapping item is not marked"); 
    16271679                        self->halt = 1; 
     1680                        PyGILState_Release(gs); 
    16281681                        return; 
    16291682                    } 
     
    16381691                    if ((index = PyDict_GetItem(self->nodes, item))) { 
    16391692                        syck_emit_item(emitter, PyInt_AS_LONG(index)); 
    1640                         if (self->halt) return; 
     1693                        if (self->halt) { 
     1694                            PyGILState_Release(gs); 
     1695                            return; 
     1696                        } 
    16411697                    } 
    16421698                    else { 
    16431699                        PyErr_SetString(PyExc_RuntimeError, "mapping item is not marked"); 
    16441700                        self->halt = 1; 
     1701                        PyGILState_Release(gs); 
    16451702                        return; 
    16461703                    } 
     
    16521709                    "value of _syck.Map must be a list of pairs or a dictionary"); 
    16531710            self->halt = 1; 
     1711            PyGILState_Release(gs); 
    16541712            return; 
    16551713        } 
     
    16611719        if (PyString_AsStringAndSize(node->value, &str, &len) < 0) { 
    16621720            self->halt = 1; 
     1721            PyGILState_Release(gs); 
    16631722            return; 
    16641723        } 
     
    16721731        PyErr_SetString(PyExc_TypeError, "Node instance is required"); 
    16731732        self->halt = 1; 
     1733        PyGILState_Release(gs); 
    16741734        return; 
    16751735    }    
    1676 } 
     1736    PyGILState_Release(gs); 
     1737} 
     1738 
    16771739static void 
    16781740PySyckEmitter_write_handler(SyckEmitter *emitter, char *buf, long len) 
    16791741{ 
     1742    PyGILState_STATE gs; 
     1743 
    16801744    PySyckEmitterObject *self = (PySyckEmitterObject *)emitter->bonus; 
     1745 
     1746    gs = PyGILState_Ensure(); 
    16811747 
    16821748    if (!PyObject_CallMethod(self->output, "write", "(s#)", buf, len)) 
    16831749        self->halt = 1; 
     1750 
     1751    PyGILState_Release(gs); 
    16841752} 
    16851753 
     
    19412009    } 
    19422010 
     2011    Py_BEGIN_ALLOW_THREADS 
    19432012    syck_emit(self->emitter, 0); 
    19442013    syck_emitter_flush(self->emitter, 0); 
     2014    Py_END_ALLOW_THREADS 
    19452015 
    19462016    syck_free_emitter(self->emitter); 
  • trunk/tests/test_syck.py

    r21 r34  
    88from test_dumper import * 
    99from test_pickle import * 
     10from test_threads import * 
    1011 
    1112def main(module='__main__'): 
Note: See TracChangeset for help on using the changeset viewer.