Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
cpython.h
1 
27 /* Some python versions don't include this by default. */
28 
29 #include <longintrepr.h>
30 
31 /* These two macros are basically Py_BEGIN_ALLOW_THREADS and
32  * Py_BEGIN_ALLOW_THREADS
33  * from the other direction. If a Python thread calls a C function
34  * Py_BEGIN_ALLOW_THREADS is used to allow other python threads to run because
35  * we don't intend to call any Python functions.
36  *
37  * These two macros are used whenever a C thread intends to call some Python
38  * function, usually because some registered callback was triggered.
39  * Just like Py_BEGIN_ALLOW_THREADS it opens a block so these macros have to be
40  * used in pairs. They acquire the GIL, create a new Python thread state and
41  * swap
42  * the current thread state with the new one. This means this thread is now
43  * allowed
44  * to execute Python code. */
45 
46 #define CPY_LOCK_THREADS \
47  { \
48  PyGILState_STATE gil_state; \
49  gil_state = PyGILState_Ensure();
50 
51 #define CPY_RETURN_FROM_THREADS \
52  PyGILState_Release(gil_state); \
53  return
54 
55 #define CPY_RELEASE_THREADS \
56  PyGILState_Release(gil_state); \
57  }
58 
59 /* This macro is a shortcut for calls like
60  * x = PyObject_Repr(x);
61  * This can't be done like this example because this would leak
62  * a reference the the original x and crash in case of x == NULL.
63  * This calling syntax is less than elegant but it works, saves
64  * a lot of lines and avoids potential refcount errors. */
65 
66 #define CPY_SUBSTITUTE(func, a, ...) \
67  do { \
68  if ((a) != NULL) { \
69  PyObject *__tmp = (a); \
70  (a) = func(__VA_ARGS__); \
71  Py_DECREF(__tmp); \
72  } \
73  } while (0)
74 
75 /* Python3 compatibility layer. To keep the actual code as clean as possible
76  * do a lot of defines here. */
77 
78 #if PY_MAJOR_VERSION >= 3
79 #define IS_PY3K
80 #endif
81 
82 #ifdef IS_PY3K
83 
84 #define PyInt_FromLong PyLong_FromLong
85 #define CPY_INIT_TYPE PyVarObject_HEAD_INIT(NULL, 0)
86 #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyBytes_Check(o))
87 #define CPY_STRCAT_AND_DEL(a, b) \
88  do { \
89  CPY_STRCAT((a), (b)); \
90  Py_XDECREF((b)); \
91  } while (0)
92 static inline void CPY_STRCAT(PyObject **a, PyObject *b) {
93  PyObject *ret;
94 
95  if (!a || !*a)
96  return;
97 
98  ret = PyUnicode_Concat(*a, b);
99  Py_DECREF(*a);
100  *a = ret;
101 }
102 
103 #else
104 
105 #define CPY_INIT_TYPE PyObject_HEAD_INIT(NULL) 0,
106 #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyString_Check(o))
107 #define CPY_STRCAT_AND_DEL PyString_ConcatAndDel
108 #define CPY_STRCAT PyString_Concat
109 
110 #endif
111 
112 static inline const char *cpy_unicode_or_bytes_to_string(PyObject **o) {
113  if (PyUnicode_Check(*o)) {
114  PyObject *tmp;
115  tmp = PyUnicode_AsEncodedString(*o, NULL, NULL); /* New reference. */
116  if (tmp == NULL)
117  return NULL;
118  Py_DECREF(*o);
119  *o = tmp;
120  }
121 #ifdef IS_PY3K
122  return PyBytes_AsString(*o);
123 #else
124  return PyString_AsString(*o);
125 #endif
126 }
127 
128 static inline PyObject *cpy_string_to_unicode_or_bytes(const char *buf) {
129 #ifdef IS_PY3K
130  /* Python3 preferrs unicode */
131  PyObject *ret;
132  ret = PyUnicode_Decode(buf, strlen(buf), NULL, NULL);
133  if (ret != NULL)
134  return ret;
135  PyErr_Clear();
136  return PyBytes_FromString(buf);
137 #else
138  return PyString_FromString(buf);
139 #endif
140 }
141 
142 void cpy_log_exception(const char *context);
143 
144 /* Python object declarations. */
145 
146 typedef struct {
147  // clang-format off
148  PyObject_HEAD /* No semicolon! */
149  PyObject *parent; /* Config */
150  PyObject *key; /* String */
151  PyObject *values; /* Sequence */
152  PyObject *children; /* Sequence */
153  // clang-format on
154 } Config;
155 extern PyTypeObject ConfigType;
156 
157 typedef struct {
158  // clang-format off
159  PyObject_HEAD /* No semicolon! */
160  double time;
161  // clang-format on
162  char host[DATA_MAX_NAME_LEN];
163  char plugin[DATA_MAX_NAME_LEN];
164  char plugin_instance[DATA_MAX_NAME_LEN];
165  char type[DATA_MAX_NAME_LEN];
166  char type_instance[DATA_MAX_NAME_LEN];
167 } PluginData;
168 extern PyTypeObject PluginDataType;
169 #define PluginData_New() \
170  PyObject_CallFunctionObjArgs((PyObject *)&PluginDataType, (void *)0)
171 
172 typedef struct {
173  PluginData data;
174  PyObject *values; /* Sequence */
175  PyObject *meta; /* dict */
176  double interval;
177 } Values;
178 extern PyTypeObject ValuesType;
179 #define Values_New() \
180  PyObject_CallFunctionObjArgs((PyObject *)&ValuesType, (void *)0)
181 
182 typedef struct {
183  PluginData data;
184  PyObject *meta; /* dict */
185  int severity;
186  char message[NOTIF_MAX_MSG_LEN];
187 } Notification;
188 extern PyTypeObject NotificationType;
189 #define Notification_New() \
190  PyObject_CallFunctionObjArgs((PyObject *)&NotificationType, (void *)0)
191 
192 typedef PyLongObject Signed;
193 extern PyTypeObject SignedType;
194 
195 typedef PyLongObject Unsigned;
196 extern PyTypeObject UnsignedType;
Notification
Definition: cpython.h:182
Values
Definition: cpython.h:172
Config
Definition: cpython.h:146
PluginData
Definition: cpython.h:157