| File: | build/temp.linux-x86_64-3.8/../../dbus_bindings/server.c | 
| Warning: | line 123, column 27 PyObject ownership leak with reference count of 1  | 
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* Implementation of the _dbus_bindings Server type, a Python wrapper | |||
| 2 | * for DBusServer. | |||
| 3 | * | |||
| 4 | * Copyright (C) 2008 Openismus GmbH <http://openismus.com/> | |||
| 5 | * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/> | |||
| 6 | * | |||
| 7 | * SPDX-License-Identifier: MIT | |||
| 8 | * | |||
| 9 | * Permission is hereby granted, free of charge, to any person | |||
| 10 | * obtaining a copy of this software and associated documentation | |||
| 11 | * files (the "Software"), to deal in the Software without | |||
| 12 | * restriction, including without limitation the rights to use, copy, | |||
| 13 | * modify, merge, publish, distribute, sublicense, and/or sell copies | |||
| 14 | * of the Software, and to permit persons to whom the Software is | |||
| 15 | * furnished to do so, subject to the following conditions: | |||
| 16 | * | |||
| 17 | * The above copyright notice and this permission notice shall be | |||
| 18 | * included in all copies or substantial portions of the Software. | |||
| 19 | * | |||
| 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| 21 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| 22 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
| 23 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||
| 24 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |||
| 25 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 27 | * DEALINGS IN THE SOFTWARE. | |||
| 28 | */ | |||
| 29 | ||||
| 30 | #include "dbus_bindings-internal.h" | |||
| 31 | ||||
| 32 | /* Server definition ================================================ */ | |||
| 33 | ||||
| 34 | typedef struct { | |||
| 35 | PyObject_HEADPyObject ob_base; | |||
| 36 | DBusServer *server; | |||
| 37 | ||||
| 38 | /* The Connection subtype for which this Server is a factory */ | |||
| 39 | PyObject *conn_class; | |||
| 40 | ||||
| 41 | /* Weak-references list to make server weakly referenceable */ | |||
| 42 | PyObject *weaklist; | |||
| 43 | ||||
| 44 | PyObject *mainloop; | |||
| 45 | } Server; | |||
| 46 | ||||
| 47 | PyDoc_STRVAR(Server_tp_doc,static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n"  | |||
| 48 | "A D-Bus server.\n"static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n"  | |||
| 49 | "\n"static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n"  | |||
| 50 | "::\n"static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n"  | |||
| 51 | "\n"static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n"  | |||
| 52 | "   Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n"static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n"  | |||
| 53 | "     -> Server\n"static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n"  | |||
| 54 | )static const char Server_tp_doc[] = "A D-Bus server.\n""\n""::\n" "\n"" Server(address, connection_subtype, mainloop=None, auth_mechanisms=None)\n" " -> Server\n";  | |||
| 55 | ||||
| 56 | /* D-Bus Server user data slot, containing an owned reference to either | |||
| 57 | * the Server, or a weakref to the Server. | |||
| 58 | */ | |||
| 59 | static dbus_int32_t _server_python_slot; | |||
| 60 | ||||
| 61 | /* C API for main-loop hooks ======================================== */ | |||
| 62 | ||||
| 63 | /* Return a borrowed reference to the DBusServer which underlies this | |||
| 64 | * Server. */ | |||
| 65 | DBusServer * | |||
| 66 | DBusPyServer_BorrowDBusServer(PyObject *self) | |||
| 67 | { | |||
| 68 | DBusServer *dbs; | |||
| 69 | ||||
| 70 | TRACE(self)do {} while (0); | |||
| 71 | if (!DBusPyServer_Check(self)) { | |||
| 72 | PyErr_SetString(PyExc_TypeError, "A dbus.server.Server is required"); | |||
| 73 | return NULL((void*)0); | |||
| 74 | } | |||
| 75 | dbs = ((Server *)self)->server; | |||
| 76 | if (!dbs) { | |||
| 77 | PyErr_SetString(PyExc_RuntimeError, "Server is in an invalid " | |||
| 78 | "state: no DBusServer"); | |||
| 79 | return NULL((void*)0); | |||
| 80 | } | |||
| 81 | return dbs; | |||
| 82 | } | |||
| 83 | ||||
| 84 | /* Internal C API =================================================== */ | |||
| 85 | ||||
| 86 | static dbus_bool_t | |||
| 87 | DBusPyServer_set_auth_mechanisms(Server *self, | |||
| 88 | PyObject *auth_mechanisms) | |||
| 89 | { | |||
| 90 | PyObject *fast_seq = NULL((void*)0), *references = NULL((void*)0); | |||
| 91 | Py_ssize_t length; | |||
| 92 | Py_ssize_t i; | |||
| 93 | /* a mutable array of constant strings */ | |||
| 94 | const char **list = NULL((void*)0); | |||
| 95 | dbus_bool_t ret = FALSE0; | |||
| 96 | ||||
| 97 | fast_seq = PySequence_Fast(auth_mechanisms, | |||
| 98 | "Expecting sequence for auth_mechanisms parameter"); | |||
| 99 | ||||
| 100 | if (!fast_seq) | |||
| 101 | return FALSE0; | |||
| 102 | ||||
| 103 |     length = PySequence_Fast_GET_SIZE(fast_seq)(((((((PyObject*)(fast_seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? ((((PyVarObject*)(fast_seq))-> ob_size)) : (((PyVarObject*)(((PyTupleObject *)(fast_seq))))-> ob_size));  | |||
| 104 | ||||
| 105 | list = calloc (length + 1, sizeof (char *)); | |||
| 106 | ||||
| 107 | if (!list) { | |||
| 108 | PyErr_NoMemory(); | |||
| 109 | goto finally; | |||
| 110 | } | |||
| 111 | ||||
| 112 | if (!(references = PyTuple_New(length))) | |||
| 113 | goto finally; | |||
| 114 | ||||
| 115 | for (i = 0; i < length; ++i) { | |||
| 116 | PyObject *am, *am_as_bytes; | |||
| 117 | ||||
| 118 |         am = PySequence_Fast_GET_ITEM(auth_mechanisms, i)(((((((PyObject*)(auth_mechanisms))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(auth_mechanisms ))->ob_item[i]) : (((PyTupleObject *)(auth_mechanisms))-> ob_item[i]));  | |||
| 119 | if (!am) | |||
| 120 | goto finally; | |||
| 121 | ||||
| 122 |         if (PyUnicode_Check(am)((((((PyObject*)(am))->ob_type))->tp_flags & ((1UL << 28))) != 0)) {  | |||
| 123 | am_as_bytes = PyUnicode_AsUTF8String(am); | |||
  | ||||
| 124 | if (!am_as_bytes) | |||
| 125 | goto finally; | |||
| 126 | } | |||
| 127 | else { | |||
| 128 | am_as_bytes = am; | |||
| 129 | Py_INCREF(am_as_bytes)_Py_INCREF(((PyObject*)(am_as_bytes))); | |||
| 130 | } | |||
| 131 | list[i] = PyBytes_AsString(am_as_bytes); | |||
| 132 | if (!list[i]) | |||
| 133 | goto finally; | |||
| 134 | ||||
| 135 | PyTuple_SET_ITEM(references, i, am_as_bytes)PyTuple_SetItem(references, i, am_as_bytes); | |||
| 136 | } | |||
| 137 | ||||
| 138 | list[length] = NULL((void*)0); | |||
| 139 | ||||
| 140 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 141 | dbus_server_set_auth_mechanisms(self->server, list); | |||
| 142 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 143 | ||||
| 144 | ret = TRUE1; | |||
| 145 | ||||
| 146 | finally: | |||
| 147 | if (list) | |||
| 148 | free (list); | |||
| 149 |     Py_CLEAR(fast_seq)do { PyObject *_py_tmp = ((PyObject*)(fast_seq)); if (_py_tmp != ((void*)0)) { (fast_seq) = ((void*)0); _Py_DECREF(((PyObject *)(_py_tmp))); } } while (0);  | |||
| 150 |     Py_CLEAR(references)do { PyObject *_py_tmp = ((PyObject*)(references)); if (_py_tmp != ((void*)0)) { (references) = ((void*)0); _Py_DECREF(((PyObject *)(_py_tmp))); } } while (0);  | |||
| 151 | return ret; | |||
| 152 | } | |||
| 153 | ||||
| 154 | /* Return a new reference to a Python Server or subclass corresponding | |||
| 155 | * to the DBusServer server. For use in callbacks. | |||
| 156 | * | |||
| 157 | * Raises AssertionError if the DBusServer does not have a Server. | |||
| 158 | */ | |||
| 159 | static PyObject * | |||
| 160 | DBusPyServer_ExistingFromDBusServer(DBusServer *server) | |||
| 161 | { | |||
| 162 | PyObject *self, *ref; | |||
| 163 | ||||
| 164 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 165 | ref = (PyObject *)dbus_server_get_data(server, | |||
| 166 | _server_python_slot); | |||
| 167 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 168 | if (ref) { | |||
| 169 | DBG("(DBusServer *)%p has weak reference at %p", server, ref)do {} while (0); | |||
| 170 | self = PyWeakref_GetObject(ref); /* still a borrowed ref */ | |||
| 171 | if (self && self != Py_None(&_Py_NoneStruct) && DBusPyServer_Check(self)) { | |||
| 172 | DBG("(DBusServer *)%p has weak reference at %p pointing to %p",do {} while (0) | |||
| 173 | server, ref, self)do {} while (0); | |||
| 174 | TRACE(self)do {} while (0); | |||
| 175 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | |||
| 176 | TRACE(self)do {} while (0); | |||
| 177 | return self; | |||
| 178 | } | |||
| 179 | } | |||
| 180 | ||||
| 181 | PyErr_SetString(PyExc_AssertionError, | |||
| 182 | "D-Bus server does not have a Server " | |||
| 183 | "instance associated with it"); | |||
| 184 | return NULL((void*)0); | |||
| 185 | } | |||
| 186 | ||||
| 187 | static void | |||
| 188 | DBusPyServer_new_connection_cb(DBusServer *server, | |||
| 189 | DBusConnection *conn, | |||
| 190 | void *data UNUSED__attribute__((__unused__))) | |||
| 191 | { | |||
| 192 | PyGILState_STATE gil = PyGILState_Ensure(); | |||
| 193 | PyObject *self = NULL((void*)0); | |||
| 194 | PyObject *method = NULL((void*)0); | |||
| 195 | ||||
| 196 | self = DBusPyServer_ExistingFromDBusServer(server); | |||
| 197 | if (!self) goto out; | |||
| 198 | TRACE(self)do {} while (0); | |||
| 199 | ||||
| 200 | method = PyObject_GetAttrString(self, "_on_new_connection"); | |||
| 201 | TRACE(method)do {} while (0); | |||
| 202 | ||||
| 203 | if (method) { | |||
| 204 | PyObject *conn_class = ((Server *)self)->conn_class; | |||
| 205 | PyObject *wrapper = DBusPyLibDBusConnection_New(conn); | |||
| 206 | PyObject *conn_obj; | |||
| 207 | PyObject *result; | |||
| 208 | ||||
| 209 | if (!wrapper) | |||
| 210 | goto out; | |||
| 211 | ||||
| 212 | conn_obj = PyObject_CallFunctionObjArgs((PyObject *)conn_class, | |||
| 213 | wrapper, ((Server*) self)->mainloop, NULL((void*)0)); | |||
| 214 |         Py_CLEAR(wrapper)do { PyObject *_py_tmp = ((PyObject*)(wrapper)); if (_py_tmp != ((void*)0)) { (wrapper) = ((void*)0); _Py_DECREF(((PyObject* )(_py_tmp))); } } while (0);  | |||
| 215 | ||||
| 216 | if (!conn_obj) | |||
| 217 | goto out; | |||
| 218 | ||||
| 219 | result = PyObject_CallFunctionObjArgs(method, conn_obj, NULL((void*)0)); | |||
| 220 |         Py_CLEAR (conn_obj)do { PyObject *_py_tmp = ((PyObject*)(conn_obj)); if (_py_tmp != ((void*)0)) { (conn_obj) = ((void*)0); _Py_DECREF(((PyObject *)(_py_tmp))); } } while (0);  | |||
| 221 | ||||
| 222 | /* discard result if not NULL, and fall through regardless */ | |||
| 223 |         Py_CLEAR(result)do { PyObject *_py_tmp = ((PyObject*)(result)); if (_py_tmp != ((void*)0)) { (result) = ((void*)0); _Py_DECREF(((PyObject*) (_py_tmp))); } } while (0);  | |||
| 224 | } | |||
| 225 | ||||
| 226 | out: | |||
| 227 |     Py_CLEAR(method)do { PyObject *_py_tmp = ((PyObject*)(method)); if (_py_tmp != ((void*)0)) { (method) = ((void*)0); _Py_DECREF(((PyObject*) (_py_tmp))); } } while (0);  | |||
| 228 |     Py_CLEAR(self)do { PyObject *_py_tmp = ((PyObject*)(self)); if (_py_tmp != ( (void*)0)) { (self) = ((void*)0); _Py_DECREF(((PyObject*)(_py_tmp ))); } } while (0);  | |||
| 229 | ||||
| 230 | if (PyErr_Occurred()) | |||
| 231 | PyErr_Print(); | |||
| 232 | ||||
| 233 | PyGILState_Release(gil); | |||
| 234 | } | |||
| 235 | ||||
| 236 | /* Return a new reference to a Python Server or subclass (given by cls) | |||
| 237 | * corresponding to the DBusServer server, which must have been newly | |||
| 238 | * created. For use by the Server constructor. | |||
| 239 | * | |||
| 240 | * Raises AssertionError if the DBusServer already has a Server. | |||
| 241 | * | |||
| 242 | * One reference to server is stolen - either the returned DBusPyServer | |||
| 243 | * claims it, or it's unreffed. | |||
| 244 | */ | |||
| 245 | static PyObject * | |||
| 246 | DBusPyServer_NewConsumingDBusServer(PyTypeObject *cls, | |||
| 247 | DBusServer *server, | |||
| 248 | PyObject *conn_class, | |||
| 249 | PyObject *mainloop, | |||
| 250 | PyObject *auth_mechanisms) | |||
| 251 | { | |||
| 252 | Server *self = NULL((void*)0); | |||
| 253 | PyObject *ref; | |||
| 254 | dbus_bool_t ok; | |||
| 255 | ||||
| 256 | DBG("%s(cls=%p, server=%p, mainloop=%p, auth_mechanisms=%p)",do {} while (0) | |||
| 257 | __func__, cls, server, mainloop, auth_mechanisms)do {} while (0); | |||
| 258 |     DBUS_PY_RAISE_VIA_NULL_IF_FAIL(server)do { if (!(server)) { _dbus_py_assertion_failed("server"); return ((void*)0); } } while (0);  | |||
| 259 | ||||
| 260 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 261 | ref = (PyObject *)dbus_server_get_data(server, | |||
| 262 | _server_python_slot); | |||
| 263 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 264 | if (ref) { | |||
| 265 | self = (Server *)PyWeakref_GetObject(ref); | |||
| 266 | ref = NULL((void*)0); | |||
| 267 | if (self && (PyObject *)self != Py_None(&_Py_NoneStruct)) { | |||
| 268 | self = NULL((void*)0); | |||
| 269 | PyErr_SetString(PyExc_AssertionError, | |||
| 270 | "Newly created D-Bus server already has a " | |||
| 271 | "Server instance associated with it"); | |||
| 272 | DBG("%s() fail - assertion failed, DBusPyServer has a DBusServer already", __func__)do {} while (0); | |||
| 273 | DBG_WHEREAMIdo {} while (0); | |||
| 274 | return NULL((void*)0); | |||
| 275 | } | |||
| 276 | } | |||
| 277 | ref = NULL((void*)0); | |||
| 278 | ||||
| 279 | /* Change mainloop from a borrowed reference to an owned reference */ | |||
| 280 | if (!mainloop || mainloop == Py_None(&_Py_NoneStruct)) { | |||
| 281 | mainloop = dbus_py_get_default_main_loop(); | |||
| 282 | ||||
| 283 | if (!mainloop || mainloop == Py_None(&_Py_NoneStruct)) { | |||
| 284 | PyErr_SetString(PyExc_RuntimeError, | |||
| 285 | "To run a D-Bus server, you need to either " | |||
| 286 | "pass mainloop=... to the constructor or call " | |||
| 287 | "dbus.set_default_main_loop(...)"); | |||
| 288 | goto err; | |||
| 289 | } | |||
| 290 | } | |||
| 291 | else { | |||
| 292 | Py_INCREF(mainloop)_Py_INCREF(((PyObject*)(mainloop))); | |||
| 293 | } | |||
| 294 | ||||
| 295 | DBG("Constructing Server from DBusServer at %p", server)do {} while (0); | |||
| 296 | ||||
| 297 | self = (Server *)(cls->tp_alloc(cls, 0)); | |||
| 298 | if (!self) goto err; | |||
| 299 | TRACE(self)do {} while (0); | |||
| 300 | ||||
| 301 | DBG_WHEREAMIdo {} while (0); | |||
| 302 | ||||
| 303 | self->server = NULL((void*)0); | |||
| 304 | ||||
| 305 | Py_INCREF(conn_class)_Py_INCREF(((PyObject*)(conn_class))); | |||
| 306 | self->conn_class = conn_class; | |||
| 307 | ||||
| 308 | self->mainloop = mainloop; | |||
| 309 | mainloop = NULL((void*)0); /* don't DECREF it - the DBusServer owns it now */ | |||
| 310 | ||||
| 311 | ref = PyWeakref_NewRef((PyObject *)self, NULL((void*)0)); | |||
| 312 | if (!ref) goto err; | |||
| 313 | DBG("Created weak ref %p to (Server *)%p for (DBusServer *)%p",do {} while (0) | |||
| 314 | ref, self, server)do {} while (0); | |||
| 315 | ||||
| 316 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 317 | ok = dbus_server_set_data(server, _server_python_slot, | |||
| 318 | (void *)ref, | |||
| 319 | (DBusFreeFunction)dbus_py_take_gil_and_xdecref); | |||
| 320 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 321 | ||||
| 322 | if (ok) { | |||
| 323 | DBG("Attached weak ref %p ((Server *)%p) to (DBusServer *)%p",do {} while (0) | |||
| 324 | ref, self, server)do {} while (0); | |||
| 325 | ||||
| 326 | ref = NULL((void*)0); /* don't DECREF it - the DBusServer owns it now */ | |||
| 327 | } | |||
| 328 | else { | |||
| 329 | DBG("Failed to attached weak ref %p ((Server *)%p) to "do {} while (0) | |||
| 330 | "(DBusServer *)%p - will dispose of it", ref, self, server)do {} while (0); | |||
| 331 | PyErr_NoMemory(); | |||
| 332 | goto err; | |||
| 333 | } | |||
| 334 | ||||
| 335 |     DBUS_PY_RAISE_VIA_GOTO_IF_FAIL(server, err)do { if (!(server)) { _dbus_py_assertion_failed("server"); goto err; } } while (0);  | |||
| 336 | self->server = server; | |||
| 337 | /* the DBusPyServer will close it now */ | |||
| 338 | server = NULL((void*)0); | |||
| 339 | ||||
| 340 | if (self->mainloop != Py_None(&_Py_NoneStruct) && | |||
| 341 | !dbus_py_set_up_server((PyObject *)self, self->mainloop)) | |||
| 342 | goto err; | |||
| 343 | ||||
| 344 | if (auth_mechanisms && auth_mechanisms != Py_None(&_Py_NoneStruct) && | |||
| 345 | !DBusPyServer_set_auth_mechanisms(self, auth_mechanisms)) | |||
| 346 | goto err; | |||
| 347 | ||||
| 348 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 349 | dbus_server_set_new_connection_function(self->server, | |||
| 350 | DBusPyServer_new_connection_cb, | |||
| 351 | NULL((void*)0), NULL((void*)0)); | |||
| 352 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 353 | ||||
| 354 | DBG("%s() -> %p", __func__, self)do {} while (0); | |||
| 355 | TRACE(self)do {} while (0); | |||
| 356 | return (PyObject *)self; | |||
| 357 | ||||
| 358 | err: | |||
| 359 | DBG("Failed to construct Server from DBusServer at %p", server)do {} while (0); | |||
| 360 |     Py_CLEAR(mainloop)do { PyObject *_py_tmp = ((PyObject*)(mainloop)); if (_py_tmp != ((void*)0)) { (mainloop) = ((void*)0); _Py_DECREF(((PyObject *)(_py_tmp))); } } while (0);  | |||
| 361 |     Py_CLEAR(self)do { PyObject *_py_tmp = ((PyObject*)(self)); if (_py_tmp != ( (void*)0)) { (self) = ((void*)0); _Py_DECREF(((PyObject*)(_py_tmp ))); } } while (0);  | |||
| 362 |     Py_CLEAR(ref)do { PyObject *_py_tmp = ((PyObject*)(ref)); if (_py_tmp != ( (void*)0)) { (ref) = ((void*)0); _Py_DECREF(((PyObject*)(_py_tmp ))); } } while (0);  | |||
| 363 | ||||
| 364 | if (server) { | |||
| 365 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 366 | dbus_server_disconnect(server); | |||
| 367 | dbus_server_unref(server); | |||
| 368 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 369 | } | |||
| 370 | ||||
| 371 | DBG("%s() fail", __func__)do {} while (0); | |||
| 372 | DBG_WHEREAMIdo {} while (0); | |||
| 373 | return NULL((void*)0); | |||
| 374 | } | |||
| 375 | ||||
| 376 | /* Server type-methods ============================================== */ | |||
| 377 | ||||
| 378 | static PyObject * | |||
| 379 | Server_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs) | |||
| 380 | { | |||
| 381 | DBusServer *server; | |||
| 382 | const char *address; | |||
| 383 | DBusError error; | |||
| 384 | PyObject *self, *conn_class, *mainloop = NULL((void*)0), *auth_mechanisms = NULL((void*)0); | |||
| 385 | static char *argnames[] = { "address", "connection_class", "mainloop", | |||
| 386 | "auth_mechanisms", NULL((void*)0)}; | |||
| 387 | ||||
| 388 | if (!PyArg_ParseTupleAndKeywords_PyArg_ParseTupleAndKeywords_SizeT(args, kwargs, "sO|OO", argnames, | |||
  | ||||
| 389 | &address, &conn_class, &mainloop, &auth_mechanisms)) { | |||
| 390 | return NULL((void*)0); | |||
| 391 | } | |||
| 392 | ||||
| 393 |     if (!PyType_Check(conn_class)((((((PyObject*)(conn_class))->ob_type))->tp_flags & ((1UL << 31))) != 0) ||  | |||
| 394 | !PyType_IsSubtype((PyTypeObject *) conn_class, &DBusPyConnection_Type)) { | |||
| 395 | /* strictly speaking, it can be any subtype of | |||
| 396 | * _dbus_bindings._Connection - but nobody else should be subtyping | |||
| 397 | * that, so let's keep this slightly inaccurate message */ | |||
| 398 | PyErr_SetString(PyExc_TypeError, "connection_class must be " | |||
| 399 | "dbus.connection.Connection or a subtype"); | |||
| 400 | return NULL((void*)0); | |||
| 401 | } | |||
| 402 | ||||
| 403 | dbus_error_init(&error); | |||
| 404 | ||||
| 405 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 406 | server = dbus_server_listen(address, &error); | |||
| 407 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 408 | ||||
| 409 | if (!server) { | |||
| 410 | DBusPyException_ConsumeError(&error); | |||
| 411 | return NULL((void*)0); | |||
| 412 | } | |||
| 413 | ||||
| 414 | self = DBusPyServer_NewConsumingDBusServer(cls, server, conn_class, | |||
| 415 | mainloop, auth_mechanisms); | |||
| 416 | ||||
| 417 | if (!self) { | |||
| 418 | return NULL((void*)0); | |||
| 419 | } | |||
| 420 | ||||
| 421 | ((Server *)self)->weaklist = NULL((void*)0); | |||
| 422 | TRACE(self)do {} while (0); | |||
| 423 | ||||
| 424 | return self; | |||
| 425 | } | |||
| 426 | ||||
| 427 | /* Destructor */ | |||
| 428 | static void Server_tp_dealloc(Server *self) | |||
| 429 | { | |||
| 430 | DBusServer *server = self->server; | |||
| 431 | PyObject *et, *ev, *etb; | |||
| 432 | ||||
| 433 | /* avoid clobbering any pending exception */ | |||
| 434 | PyErr_Fetch(&et, &ev, &etb); | |||
| 435 | ||||
| 436 | if (self->weaklist) { | |||
| 437 | PyObject_ClearWeakRefs((PyObject *)self); | |||
| 438 | } | |||
| 439 | ||||
| 440 | TRACE(self)do {} while (0); | |||
| 441 | DBG("Deallocating Server at %p (DBusServer at %p)", self, server)do {} while (0); | |||
| 442 | DBG_WHEREAMIdo {} while (0); | |||
| 443 | ||||
| 444 | if (server) { | |||
| 445 | DBG("Server at %p has a server, disconnecting it...", self)do {} while (0); | |||
| 446 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 447 | dbus_server_disconnect(server); | |||
| 448 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 449 | } | |||
| 450 | ||||
| 451 |     Py_CLEAR(self->mainloop)do { PyObject *_py_tmp = ((PyObject*)(self->mainloop)); if (_py_tmp != ((void*)0)) { (self->mainloop) = ((void*)0); _Py_DECREF (((PyObject*)(_py_tmp))); } } while (0);  | |||
| 452 | ||||
| 453 | /* make sure to do this last to preserve the invariant that | |||
| 454 | * self->server is always non-NULL for any referenced Server. | |||
| 455 | */ | |||
| 456 | DBG("Server at %p: nulling self->server", self)do {} while (0); | |||
| 457 | self->server = NULL((void*)0); | |||
| 458 | ||||
| 459 | if (server) { | |||
| 460 | DBG("Server at %p: unreffing server", self)do {} while (0); | |||
| 461 | dbus_server_unref(server); | |||
| 462 | } | |||
| 463 | ||||
| 464 | DBG("Server at %p: freeing self", self)do {} while (0); | |||
| 465 | PyErr_Restore(et, ev, etb); | |||
| 466 | (Py_TYPE(self)(((PyObject*)(self))->ob_type)->tp_free)((PyObject *)self); | |||
| 467 | } | |||
| 468 | ||||
| 469 | PyDoc_STRVAR(Server_disconnect__doc__,static const char Server_disconnect__doc__[] = "disconnect()\n\n" "Releases the server's address and stops listening for new clients.\n\n" "If called more than once, only the first call has an effect."  | |||
| 470 | "disconnect()\n\n"static const char Server_disconnect__doc__[] = "disconnect()\n\n" "Releases the server's address and stops listening for new clients.\n\n" "If called more than once, only the first call has an effect."  | |||
| 471 | "Releases the server's address and stops listening for new clients.\n\n"static const char Server_disconnect__doc__[] = "disconnect()\n\n" "Releases the server's address and stops listening for new clients.\n\n" "If called more than once, only the first call has an effect."  | |||
| 472 | "If called more than once, only the first call has an effect.")static const char Server_disconnect__doc__[] = "disconnect()\n\n" "Releases the server's address and stops listening for new clients.\n\n" "If called more than once, only the first call has an effect.";  | |||
| 473 | static PyObject * | |||
| 474 | Server_disconnect (Server *self, PyObject *args UNUSED__attribute__((__unused__))) | |||
| 475 | { | |||
| 476 | TRACE(self)do {} while (0); | |||
| 477 | if (self->server) { | |||
| 478 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 479 | dbus_server_disconnect(self->server); | |||
| 480 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 481 | } | |||
| 482 |     Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct);  | |||
| 483 | } | |||
| 484 | ||||
| 485 | PyDoc_STRVAR(Server_get_address__doc__,static const char Server_get_address__doc__[] = "get_address() -> str\n\n" "Returns the address of the server."  | |||
| 486 | "get_address() -> str\n\n"static const char Server_get_address__doc__[] = "get_address() -> str\n\n" "Returns the address of the server."  | |||
| 487 | "Returns the address of the server.")static const char Server_get_address__doc__[] = "get_address() -> str\n\n" "Returns the address of the server.";  | |||
| 488 | static PyObject * | |||
| 489 | Server_get_address(Server *self, PyObject *args UNUSED__attribute__((__unused__))) | |||
| 490 | { | |||
| 491 | const char *address; | |||
| 492 | ||||
| 493 | TRACE(self)do {} while (0); | |||
| 494 |     DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->server)do { if (!(self->server)) { _dbus_py_assertion_failed("self->server" ); return ((void*)0); } } while (0);  | |||
| 495 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 496 | address = dbus_server_get_address(self->server); | |||
| 497 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 498 | ||||
| 499 | return PyUnicode_FromString(address); | |||
| 500 | } | |||
| 501 | ||||
| 502 | PyDoc_STRVAR(Server_get_id__doc__,static const char Server_get_id__doc__[] = "get_id() -> str\n\n" "Returns the unique ID of the server."  | |||
| 503 | "get_id() -> str\n\n"static const char Server_get_id__doc__[] = "get_id() -> str\n\n" "Returns the unique ID of the server."  | |||
| 504 | "Returns the unique ID of the server.")static const char Server_get_id__doc__[] = "get_id() -> str\n\n" "Returns the unique ID of the server.";  | |||
| 505 | static PyObject * | |||
| 506 | Server_get_id(Server *self, PyObject *args UNUSED__attribute__((__unused__))) | |||
| 507 | { | |||
| 508 | const char *id; | |||
| 509 | ||||
| 510 | TRACE(self)do {} while (0); | |||
| 511 |     DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->server)do { if (!(self->server)) { _dbus_py_assertion_failed("self->server" ); return ((void*)0); } } while (0);  | |||
| 512 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 513 | id = dbus_server_get_id(self->server); | |||
| 514 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 515 | ||||
| 516 | return PyUnicode_FromString(id); | |||
| 517 | } | |||
| 518 | ||||
| 519 | PyDoc_STRVAR(Server_get_is_connected__doc__,static const char Server_get_is_connected__doc__[] = "get_is_connected() -> bool\n\n" "Return true if this Server is still listening for new connections.\n"  | |||
| 520 | "get_is_connected() -> bool\n\n"static const char Server_get_is_connected__doc__[] = "get_is_connected() -> bool\n\n" "Return true if this Server is still listening for new connections.\n"  | |||
| 521 | "Return true if this Server is still listening for new connections.\n")static const char Server_get_is_connected__doc__[] = "get_is_connected() -> bool\n\n" "Return true if this Server is still listening for new connections.\n";  | |||
| 522 | static PyObject * | |||
| 523 | Server_get_is_connected (Server *self, PyObject *args UNUSED__attribute__((__unused__))) | |||
| 524 | { | |||
| 525 | dbus_bool_t ret; | |||
| 526 | ||||
| 527 | TRACE(self)do {} while (0); | |||
| 528 |     DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->server)do { if (!(self->server)) { _dbus_py_assertion_failed("self->server" ); return ((void*)0); } } while (0);  | |||
| 529 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | |||
| 530 | ret = dbus_server_get_is_connected(self->server); | |||
| 531 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | |||
| 532 | return PyBool_FromLong(ret); | |||
| 533 | } | |||
| 534 | ||||
| 535 | /* Server type object =============================================== */ | |||
| 536 | ||||
| 537 | struct PyMethodDef DBusPyServer_tp_methods[] = { | |||
| 538 | #define ENTRY(name, flags) {#name, (PyCFunction) (void (*)(void))Server_##name, flags, Server_##name##__doc__} | |||
| 539 | ENTRY(disconnect, METH_NOARGS0x0004), | |||
| 540 | ENTRY(get_address, METH_NOARGS0x0004), | |||
| 541 | ENTRY(get_id, METH_NOARGS0x0004), | |||
| 542 | ENTRY(get_is_connected, METH_NOARGS0x0004), | |||
| 543 | {NULL((void*)0)}, | |||
| 544 | #undef ENTRY | |||
| 545 | }; | |||
| 546 | ||||
| 547 | PyTypeObject DBusPyServer_Type = { | |||
| 548 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, | |||
| 549 | "_dbus_bindings._Server",/*tp_name*/ | |||
| 550 | sizeof(Server), /*tp_basicsize*/ | |||
| 551 | 0, /*tp_itemsize*/ | |||
| 552 | /* methods */ | |||
| 553 | (destructor)Server_tp_dealloc, | |||
| 554 | 0, /*tp_print*/ | |||
| 555 | 0, /*tp_getattr*/ | |||
| 556 | 0, /*tp_setattr*/ | |||
| 557 | 0, /*tp_compare*/ | |||
| 558 | 0, /*tp_repr*/ | |||
| 559 | 0, /*tp_as_number*/ | |||
| 560 | 0, /*tp_as_sequence*/ | |||
| 561 | 0, /*tp_as_mapping*/ | |||
| 562 | 0, /*tp_hash*/ | |||
| 563 | 0, /*tp_call*/ | |||
| 564 | 0, /*tp_str*/ | |||
| 565 | 0, /*tp_getattro*/ | |||
| 566 | 0, /*tp_setattro*/ | |||
| 567 | 0, /*tp_as_buffer*/ | |||
| 568 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0) | Py_TPFLAGS_BASETYPE(1UL << 10), | |||
| 569 | Server_tp_doc, /*tp_doc*/ | |||
| 570 | 0, /*tp_traverse*/ | |||
| 571 | 0, /*tp_clear*/ | |||
| 572 | 0, /*tp_richcompare*/ | |||
| 573 | offsetof(Server, weaklist)__builtin_offsetof(Server, weaklist), /*tp_weaklistoffset*/ | |||
| 574 | 0, /*tp_iter*/ | |||
| 575 | 0, /*tp_iternext*/ | |||
| 576 | DBusPyServer_tp_methods,/*tp_methods*/ | |||
| 577 | 0, /*tp_members*/ | |||
| 578 | 0, /*tp_getset*/ | |||
| 579 | 0, /*tp_base*/ | |||
| 580 | 0, /*tp_dict*/ | |||
| 581 | 0, /*tp_descr_get*/ | |||
| 582 | 0, /*tp_descr_set*/ | |||
| 583 | 0, /*tp_dictoffset*/ | |||
| 584 | 0, /*tp_init*/ | |||
| 585 | 0, /*tp_alloc*/ | |||
| 586 | Server_tp_new, /*tp_new*/ | |||
| 587 | 0, /*tp_free*/ | |||
| 588 | 0, /*tp_is_gc*/ | |||
| 589 | }; | |||
| 590 | ||||
| 591 | dbus_bool_t | |||
| 592 | dbus_py_init_server_types(void) | |||
| 593 | { | |||
| 594 | /* Get a slot to store our weakref on DBus Server */ | |||
| 595 | _server_python_slot = -1; | |||
| 596 | if (!dbus_server_allocate_data_slot(&_server_python_slot)) | |||
| 597 | return FALSE0; | |||
| 598 | ||||
| 599 | if (PyType_Ready(&DBusPyServer_Type) < 0) | |||
| 600 | return FALSE0; | |||
| 601 | ||||
| 602 | return TRUE1; | |||
| 603 | } | |||
| 604 | ||||
| 605 | dbus_bool_t | |||
| 606 | dbus_py_insert_server_types(PyObject *this_module) | |||
| 607 | { | |||
| 608 | /* PyModule_AddObject steals a ref */ | |||
| 609 | Py_INCREF (&DBusPyServer_Type)_Py_INCREF(((PyObject*)(&DBusPyServer_Type))); | |||
| 610 | if (PyModule_AddObject(this_module, "_Server", | |||
| 611 | (PyObject *)&DBusPyServer_Type) < 0) return FALSE0; | |||
| 612 | ||||
| 613 | return TRUE1; | |||
| 614 | } | |||
| 615 | ||||
| 616 | /* vim:set ft=c cino< sw=4 sts=4 et: */ | 
| 1 | #ifndef PyUnicode_AsUTF8String | 
| 2 | struct _object; | 
| 3 | typedef struct _object PyObject; | 
| 4 | PyObject* clang_analyzer_PyObject_New_Reference(); | 
| 5 | PyObject* PyUnicode_AsUTF8String(PyObject *unicode) { | 
| 6 | return clang_analyzer_PyObject_New_Reference(); | 
| 7 | } | 
| 8 | #else | 
| 9 | #warning "API PyUnicode_AsUTF8String is defined as a macro." | 
| 10 | #endif |