⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 weakrefobject.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}


/* mapping slots */

static int
proxy_length(PyWeakReference *proxy)
{
    if (!proxy_checkref(proxy))
        return -1;
    return PyObject_Length(PyWeakref_GET_OBJECT(proxy));
}

WRAP_BINARY(proxy_getitem, PyObject_GetItem)

static int
proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value)
{
    if (!proxy_checkref(proxy))
        return -1;
    return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value);
}


const static PyNumberMethods proxy_as_number = {
    (binaryfunc)proxy_add,      /*nb_add*/
    (binaryfunc)proxy_sub,      /*nb_subtract*/
    (binaryfunc)proxy_mul,      /*nb_multiply*/
    (binaryfunc)proxy_div,      /*nb_divide*/
    (binaryfunc)proxy_mod,      /*nb_remainder*/
    (binaryfunc)proxy_divmod,   /*nb_divmod*/
    (ternaryfunc)proxy_pow,     /*nb_power*/
    (unaryfunc)proxy_neg,       /*nb_negative*/
    (unaryfunc)proxy_pos,       /*nb_positive*/
    (unaryfunc)proxy_abs,       /*nb_absolute*/
    (inquiry)proxy_nonzero,     /*nb_nonzero*/
    (unaryfunc)proxy_invert,    /*nb_invert*/
    (binaryfunc)proxy_lshift,   /*nb_lshift*/
    (binaryfunc)proxy_rshift,   /*nb_rshift*/
    (binaryfunc)proxy_and,      /*nb_and*/
    (binaryfunc)proxy_xor,      /*nb_xor*/
    (binaryfunc)proxy_or,       /*nb_or*/
    (coercion)0,                /*nb_coerce*/
    (unaryfunc)proxy_int,       /*nb_int*/
    (unaryfunc)proxy_long,      /*nb_long*/
    (unaryfunc)proxy_float,     /*nb_float*/
    (unaryfunc)0,               /*nb_oct*/
    (unaryfunc)0,               /*nb_hex*/
    (binaryfunc)proxy_iadd,     /*nb_inplace_add*/
    (binaryfunc)proxy_isub,     /*nb_inplace_subtract*/
    (binaryfunc)proxy_imul,     /*nb_inplace_multiply*/
    (binaryfunc)proxy_idiv,     /*nb_inplace_divide*/
    (binaryfunc)proxy_imod,     /*nb_inplace_remainder*/
    (ternaryfunc)proxy_ipow,    /*nb_inplace_power*/
    (binaryfunc)proxy_ilshift,  /*nb_inplace_lshift*/
    (binaryfunc)proxy_irshift,  /*nb_inplace_rshift*/
    (binaryfunc)proxy_iand,     /*nb_inplace_and*/
    (binaryfunc)proxy_ixor,     /*nb_inplace_xor*/
    (binaryfunc)proxy_ior,      /*nb_inplace_or*/
};

const static PySequenceMethods proxy_as_sequence = {
    (inquiry)proxy_length,      /*sq_length*/
    0,                          /*sq_concat*/
    0,                          /*sq_repeat*/
    0,                          /*sq_item*/
    (intintargfunc)proxy_slice, /*sq_slice*/
    0,                          /*sq_ass_item*/
    (intintobjargproc)proxy_ass_slice, /*sq_ass_slice*/
    (objobjproc)proxy_contains, /* sq_contains */
};

const static PyMappingMethods proxy_as_mapping = {
    (inquiry)proxy_length,      /*mp_length*/
    (binaryfunc)proxy_getitem,  /*mp_subscript*/
    (objobjargproc)proxy_setitem, /*mp_ass_subscript*/
};

#ifndef SYMBIAN
PyTypeObject
_PyWeakref_ProxyType = {
    PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject
_c_PyWeakref_ProxyType = {
    PyObject_HEAD_INIT(NULL)
#endif
    0,
    "weakproxy",
    sizeof(PyWeakReference),
    0,
    /* methods */
    (destructor)weakref_dealloc,/*tp_dealloc*/
    (printfunc)proxy_print,     /*tp_print*/
    0,				/*tp_getattr*/
    0, 				/*tp_setattr*/
    proxy_compare,		/*tp_compare*/
    (unaryfunc)proxy_repr,	/*tp_repr*/
    &proxy_as_number,		/*tp_as_number*/
    &proxy_as_sequence,		/*tp_as_sequence*/
    &proxy_as_mapping,		/*tp_as_mapping*/
    0,	                        /*tp_hash*/
    (ternaryfunc)0,	        /*tp_call*/
    (unaryfunc)proxy_str,	/*tp_str*/
    (getattrofunc)proxy_getattr,/*tp_getattro*/
    (setattrofunc)proxy_setattr,/*tp_setattro*/
    0,				/*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
    |Py_TPFLAGS_CHECKTYPES,     /*tp_flags*/
    0,                          /*tp_doc*/
    (traverseproc)gc_traverse,  /*tp_traverse*/
    (inquiry)gc_clear,          /*tp_clear*/
};

#ifndef SYMBIAN
PyTypeObject
_PyWeakref_CallableProxyType = {
    PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject
_c_PyWeakref_CallableProxyType = {
    PyObject_HEAD_INIT(NULL)
#endif
    0,
    "weakcallableproxy",
    sizeof(PyWeakReference),
    0,
    /* methods */
    (destructor)weakref_dealloc,/*tp_dealloc*/
    (printfunc)proxy_print,     /*tp_print*/
    0,				/*tp_getattr*/
    0, 				/*tp_setattr*/
    proxy_compare,		/*tp_compare*/
    (unaryfunc)proxy_repr,	/*tp_repr*/
    &proxy_as_number,		/*tp_as_number*/
    &proxy_as_sequence,		/*tp_as_sequence*/
    &proxy_as_mapping,		/*tp_as_mapping*/
    0,	                        /*tp_hash*/
    (ternaryfunc)proxy_call,	/*tp_call*/
    (unaryfunc)proxy_str,	/*tp_str*/
    (getattrofunc)proxy_getattr,/*tp_getattro*/
    (setattrofunc)proxy_setattr,/*tp_setattro*/
    0,				/*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
    |Py_TPFLAGS_CHECKTYPES,     /*tp_flags*/
    0,                          /*tp_doc*/
    (traverseproc)gc_traverse,  /*tp_traverse*/
    (inquiry)gc_clear,          /*tp_clear*/
};


/* Given the head of an object's list of weak references, extract the
 * two callback-less refs (ref and proxy).  Used to determine if the
 * shared references exist and to determine the back link for newly
 * inserted references.
 */
static void
get_basic_refs(PyWeakReference *head,
               PyWeakReference **refp, PyWeakReference **proxyp)
{
    *refp = NULL;
    *proxyp = NULL;

    if (head != NULL && head->wr_callback == NULL) {
        if (head->ob_type == &_PyWeakref_RefType) {
            *refp = head;
            head = head->wr_next;
        }
        if (head != NULL && head->wr_callback == NULL) {
            *proxyp = head;
            head = head->wr_next;
        }
    }
}

/* Insert 'newref' in the list after 'prev'.  Both must be non-NULL. */
static void
insert_after(PyWeakReference *newref, PyWeakReference *prev)
{
    newref->wr_prev = prev;
    newref->wr_next = prev->wr_next;
    if (prev->wr_next != NULL)
        prev->wr_next->wr_prev = newref;
    prev->wr_next = newref;
}

/* Insert 'newref' at the head of the list; 'list' points to the variable
 * that stores the head.
 */
static void
insert_head(PyWeakReference *newref, PyWeakReference **list)
{
    PyWeakReference *next = *list;

    newref->wr_prev = NULL;
    newref->wr_next = next;
    if (next != NULL)
        next->wr_prev = newref;
    *list = newref;
}


DL_EXPORT(PyObject *)
PyWeakref_NewRef(PyObject *ob, PyObject *callback)
{
    PyWeakReference *result = NULL;
    PyWeakReference **list;
    PyWeakReference *ref, *proxy;

    if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
        PyErr_Format(PyExc_TypeError,
		     "cannot create weak reference to '%s' object",
                     ob->ob_type->tp_name);
        return NULL;
    }
    list = GET_WEAKREFS_LISTPTR(ob);
    get_basic_refs(*list, &ref, &proxy);
    if (callback == NULL || callback == Py_None)
        /* return existing weak reference if it exists */
        result = ref;
    if (result != NULL)
        Py_XINCREF(result);
    else {
        result = new_weakref();
        if (result != NULL) {
            Py_XINCREF(callback);
            result->wr_callback = callback;
            result->wr_object = ob;
            if (callback == NULL) {
                insert_head(result, list);
            }
            else {
                PyWeakReference *prev = (proxy == NULL) ? ref : proxy;

                if (prev == NULL)
                    insert_head(result, list);
                else
                    insert_after(result, prev);
            }
            PyObject_GC_Track(result);
        }
    }
    return (PyObject *) result;
}


DL_EXPORT(PyObject *)
PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
{
    PyWeakReference *result = NULL;
    PyWeakReference **list;
    PyWeakReference *ref, *proxy;

    if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
        PyErr_Format(PyExc_TypeError,
		     "cannot create weak reference to '%s' object",
                     ob->ob_type->tp_name);
        return NULL;
    }
    list = GET_WEAKREFS_LISTPTR(ob);
    get_basic_refs(*list, &ref, &proxy);
    if (callback == NULL)
        /* attempt to return an existing weak reference if it exists */
        result = proxy;
    if (result != NULL)
        Py_XINCREF(result);
    else {
        result = new_weakref();
        if (result != NULL) {
            PyWeakReference *prev;

            if (PyCallable_Check(ob))
                result->ob_type = &_PyWeakref_CallableProxyType;
            else
                result->ob_type = &_PyWeakref_ProxyType;
            result->wr_object = ob;
            Py_XINCREF(callback);
            result->wr_callback = callback;
            if (callback == NULL)
                prev = ref;
            else
                prev = (proxy == NULL) ? ref : proxy;

            if (prev == NULL)
                insert_head(result, list);
            else
                insert_after(result, prev);
            PyObject_GC_Track(result);
        }
    }
    return (PyObject *) result;
}


DL_EXPORT(PyObject *)
PyWeakref_GetObject(PyObject *ref)
{
    if (ref == NULL || !PyWeakref_Check(ref)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    return PyWeakref_GET_OBJECT(ref);
}


static void
handle_callback(PyWeakReference *ref, PyObject *callback)
{
    PyObject *cbresult = PyObject_CallFunction(callback, "O", ref);

    if (cbresult == NULL)
        PyErr_WriteUnraisable(callback);
    else
        Py_DECREF(cbresult);
}

/* This function is called by the tp_dealloc handler to clear weak references.
 *
 * This iterates through the weak references for 'object' and calls callbacks
 * for those references which have one.  It returns when all callbacks have
 * been attempted.
 */
DL_EXPORT(void)
PyObject_ClearWeakRefs(PyObject *object)
{
    PyWeakReference **list;

    if (object == NULL
        || !PyType_SUPPORTS_WEAKREFS(object->ob_type)
        || object->ob_refcnt != 0) {
        PyErr_BadInternalCall();
        return;
    }
    list = GET_WEAKREFS_LISTPTR(object);
    /* Remove the callback-less basic and proxy references */
    if (*list != NULL && (*list)->wr_callback == NULL) {
        clear_weakref(*list);
        if (*list != NULL && (*list)->wr_callback == NULL)
            clear_weakref(*list);
    }
    if (*list != NULL) {
        PyWeakReference *current = *list;
        int count = _PyWeakref_GetWeakrefCount(current);
        int restore_error = PyErr_Occurred() ? 1 : 0;
        PyObject *err_type, *err_value, *err_tb;

        if (restore_error)
            PyErr_Fetch(&err_type, &err_value, &err_tb);
        if (count == 1) {
            PyObject *callback = current->wr_callback;

            current->wr_callback = NULL;
            clear_weakref(current);
            handle_callback(current, callback);
            Py_DECREF(callback);
        }
        else {
            PyObject *tuple = PyTuple_New(count * 2);
            int i = 0;

            for (i = 0; i < count; ++i) {
                PyWeakReference *next = current->wr_next;

                Py_INCREF(current);
                PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
                PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
                current->wr_callback = NULL;
                clear_weakref(current);
                current = next;
            }
            for (i = 0; i < count; ++i) {
                PyObject *current = PyTuple_GET_ITEM(tuple, i * 2);
                PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);

                handle_callback((PyWeakReference *)current, callback);
            }
            Py_DECREF(tuple);
        }
        if (restore_error)
            PyErr_Restore(err_type, err_value, err_tb);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -