1# -----------------------------------------------------------------------------
2
3cdef dict type_keyval = {}
4
5cdef inline int type_keyval_new(int keyval,
6                                object copy_fn,object delete_fn) except -1:
7    type_keyval[keyval] = (copy_fn, delete_fn)
8    return 0
9
10cdef inline int type_keyval_del(int keyval) except -1:
11    try: del type_keyval[keyval]
12    except KeyError: pass
13    return 0
14
15cdef inline int type_attr_copy(MPI_Datatype datatype,
16                               int keyval,
17                               void *extra_state,
18                               void *attrval_in,
19                               void *attrval_out,
20                               int *flag) except -1:
21    cdef tuple entry = type_keyval.get(keyval)
22    cdef object copy_fn = None
23    if entry is not None: copy_fn = entry[0]
24    if copy_fn is None or copy_fn is False:
25        flag[0] = 0
26        return 0
27    cdef object attrval = <object>attrval_in
28    cdef void **aptr = <void **>attrval_out
29    if copy_fn is not True:
30        attrval = copy_fn(attrval)
31    Py_INCREF(attrval)
32    aptr[0] = <void*>attrval
33    flag[0] = 1
34    return 0
35
36cdef inline int type_attr_delete(MPI_Datatype datatype,
37                                 int keyval,
38                                 void *attrval,
39                                 void *extra_state) except -1:
40    cdef tuple entry = type_keyval.get(keyval)
41    cdef object delete_fn = None
42    if entry is not None: delete_fn = entry[1]
43    if delete_fn is not None:
44        delete_fn(<object>attrval)
45    Py_DECREF(<object>attrval)
46    return 0
47
48@cython.callspec("PyMPIAPI")
49cdef int type_attr_copy_fn(MPI_Datatype datatype,
50                           int keyval,
51                           void *extra_state,
52                           void *attrval_in,
53                           void *attrval_out,
54                           int *flag) with gil:
55    if not Py_IsInitialized():
56        return MPI_SUCCESS
57    if attrval_in == NULL:
58        return MPI_ERR_INTERN
59    if attrval_out == NULL:
60        return MPI_ERR_INTERN
61    cdef object exc
62    try:
63        type_attr_copy(datatype, keyval, extra_state,
64                       attrval_in, attrval_out, flag)
65    except MPIException, exc:
66        print_traceback()
67        return exc.Get_error_code()
68    except:
69        print_traceback()
70        return MPI_ERR_OTHER
71    return MPI_SUCCESS
72
73@cython.callspec("PyMPIAPI")
74cdef int type_attr_delete_fn(MPI_Datatype datatype,
75                             int keyval,
76                             void *attrval,
77                             void *extra_state) with gil:
78    if not Py_IsInitialized():
79        return MPI_SUCCESS
80    if attrval == NULL:
81        return MPI_ERR_INTERN
82    cdef object exc
83    try:
84        type_attr_delete(datatype, keyval, attrval, extra_state)
85    except MPIException, exc:
86        print_traceback()
87        return exc.Get_error_code()
88    except:
89        print_traceback()
90        return MPI_ERR_OTHER
91    return MPI_SUCCESS
92
93# -----------------------------------------------------------------------------
94