diff -U0 pycups-1.9.42/ChangeLog.git-master pycups-1.9.42/ChangeLog --- pycups-1.9.42/ChangeLog.git-master 2008-08-29 09:56:45.000000000 +0100 +++ pycups-1.9.42/ChangeLog 2008-11-12 17:30:17.000000000 +0000 @@ -0,0 +1,12 @@ +2008-11-12 Tim Waugh + + * cupsconnection.c (Connection): Store thread state in Connection + data. + (Connection_begin_allow_threads): Save current thread state. + (Connection_end_allow_threads): Restore current thread state. + (Connection_init): Use new functions. + (Connection_getPPDs): Likewise. + (Connection_getServerPPD): Likewise. + (Connection_getDocument): Likewise. + (Connection_getDevices): Likewise. + diff -up pycups-1.9.42/cupsconnection.c.git-master pycups-1.9.42/cupsconnection.c --- pycups-1.9.42/cupsconnection.c.git-master 2008-08-29 09:56:45.000000000 +0100 +++ pycups-1.9.42/cupsconnection.c 2008-11-12 17:30:17.000000000 +0000 @@ -41,6 +41,7 @@ typedef struct PyObject_HEAD http_t *http; char *host; /* for repr */ + PyThreadState *tstate; } Connection; typedef struct @@ -143,6 +144,7 @@ Connection_new (PyTypeObject *type, PyOb if (self != NULL) { self->http = NULL; self->host = NULL; + self->tstate = NULL; } return (PyObject *) self; @@ -167,10 +169,10 @@ Connection_init (Connection *self, PyObj return -1; } - Py_BEGIN_ALLOW_THREADS; + Connection_begin_allow_threads (self); debugprintf ("httpConnectEncrypt(...)\n"); self->http = httpConnectEncrypt (host, port, (http_encryption_t) encryption); - Py_END_ALLOW_THREADS; + Connection_end_allow_threads (self); if (!self->http) { PyErr_SetString (PyExc_RuntimeError, "httpConnectionEncrypt failed"); @@ -201,6 +203,30 @@ Connection_repr (Connection *self) self->host, self); } +void +Connection_begin_allow_threads (void *connection) +{ + Connection *self = (Connection *) connection; + if (!self || !self->tstate) + return; + + debugprintf ("begin allow threads\n"); + g_current_connection = connection; + self->tstate = PyEval_SaveThread (); +} + +void +Connection_end_allow_threads (void *connection) +{ + Connection *self = (Connection *) connection; + if (!self || !self->tstate) + return; + + debugprintf ("end allow threads\n"); + PyEval_RestoreThread (self->tstate); + self->tstate = NULL; +} + //////////////// // Connection // METHODS //////////////// @@ -632,9 +658,9 @@ Connection_getPPDs (Connection *self) debugprintf ("-> Connection_getPPDs()\n"); debugprintf ("cupsDoRequest(\"/\")\n"); - Py_BEGIN_ALLOW_THREADS; + Connection_begin_allow_threads (self); answer = cupsDoRequest (self->http, request, "/"); - Py_END_ALLOW_THREADS; + Connection_end_allow_threads (self); if (!answer || answer->request.status.status_code > IPP_OK_CONFLICT) { set_ipp_error (answer ? answer->request.status.status_code : @@ -700,9 +726,9 @@ Connection_getServerPPD (Connection *sel if (!PyArg_ParseTuple (args, "s", &ppd_name)) return NULL; debugprintf ("-> Connection_getServerPPD()\n"); - Py_BEGIN_ALLOW_THREADS; + Connection_begin_allow_threads (self); filename = cupsGetServerPPD (self->http, ppd_name); - Py_END_ALLOW_THREADS; + Connection_end_allow_threads (self); if (!filename) { set_ipp_error (cupsLastError ()); debugprintf ("<- Connection_getServerPPD() (error)\n"); @@ -759,9 +785,9 @@ Connection_getDocument (Connection *self return NULL; } - Py_BEGIN_ALLOW_THREADS; + Connection_begin_allow_threads (self); answer = cupsDoIORequest (self->http, request, "/", -1, fd); - Py_END_ALLOW_THREADS; + Connection_end_allow_threads (self); close (fd); if (!answer || answer->request.status.status_code > IPP_OK_CONFLICT) { @@ -823,9 +849,9 @@ Connection_getDevices (Connection *self) debugprintf ("-> Connection_getDevices()\n"); debugprintf ("cupsDoRequest(\"/\")\n"); - Py_BEGIN_ALLOW_THREADS; + Connection_begin_allow_threads (self); answer = cupsDoRequest (self->http, request, "/"); - Py_END_ALLOW_THREADS; + Connection_end_allow_threads (self); if (!answer || answer->request.status.status_code > IPP_OK_CONFLICT) { set_ipp_error (answer ? answer->request.status.status_code : diff -up pycups-1.9.42/cupsconnection.h.git-master pycups-1.9.42/cupsconnection.h --- pycups-1.9.42/cupsconnection.h.git-master 2008-07-05 18:19:02.000000000 +0100 +++ pycups-1.9.42/cupsconnection.h 2008-11-12 17:30:17.000000000 +0000 @@ -1,6 +1,6 @@ /* * cups - Python bindings for CUPS - * Copyright (C) 2002, 2005, 2006 Tim Waugh + * Copyright (C) 2002, 2005, 2006, 2008 Tim Waugh * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,4 +29,6 @@ extern PyTypeObject cups_DestType; extern PyObject *HTTPError; extern PyObject *IPPError; +void Connection_begin_allow_threads (void *connection); +void Connection_end_allow_threads (void *connection); #endif /* HAVE_CUPSCONNECTION_H */ diff -up pycups-1.9.42/cupsmodule.c.git-master pycups-1.9.42/cupsmodule.c --- pycups-1.9.42/cupsmodule.c.git-master 2008-07-05 18:19:02.000000000 +0100 +++ pycups-1.9.42/cupsmodule.c 2008-11-12 17:30:17.000000000 +0000 @@ -30,6 +30,7 @@ #include "cupsppd.h" static PyObject *cups_password_callback = NULL; +void *g_current_connection = NULL; ////////////////////// // Worker functions // @@ -105,11 +106,17 @@ do_password_callback (const char *prompt PyObject *result; const char *pwval; + debugprintf ("-> do_password_callback\n"); + Connection_end_allow_threads (g_current_connection); args = Py_BuildValue ("(s)", prompt); result = PyEval_CallObject (cups_password_callback, args); Py_DECREF (args); if (result == NULL) + { + debugprintf ("<- do_password_callback (empty string)\n"); + Connection_begin_allow_threads (g_current_connection); return ""; + } if (password) { free (password); @@ -120,8 +127,14 @@ do_password_callback (const char *prompt password = strdup (pwval); Py_DECREF (result); if (!password) + { + debugprintf ("<- do_password_callback (empty string)\n"); + Connection_begin_allow_threads (g_current_connection); return ""; - + } + + Connection_begin_allow_threads (g_current_connection); + debugprintf ("<- do_password_callback\n"); return password; } diff -up pycups-1.9.42/cupsmodule.h.git-master pycups-1.9.42/cupsmodule.h --- pycups-1.9.42/cupsmodule.h.git-master 2008-07-05 18:19:02.000000000 +0100 +++ pycups-1.9.42/cupsmodule.h 2008-11-12 17:30:17.000000000 +0000 @@ -1,6 +1,6 @@ /* * cups - Python bindings for CUPS - * Copyright (C) 2006, 2007 Tim Waugh + * Copyright (C) 2006, 2007, 2008 Tim Waugh * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -53,4 +53,6 @@ extern void debugprintf (const char *fmt #error pycups requires CUPS 1.2.x #endif +extern void *g_current_connection; + #endif /* HAVE_CUPSMODULE_H */