mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-30 11:07:38 +00:00
Fix polling for new data in cups print backend (bug #599664)
This commit is contained in:
parent
875e6f4bdb
commit
f0726904cb
@ -253,34 +253,43 @@ gtk_cups_request_free (GtkCupsRequest *request)
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_cups_request_read_write (GtkCupsRequest *request)
|
||||
gtk_cups_request_read_write (GtkCupsRequest *request, gboolean connect_only)
|
||||
{
|
||||
if (request->type == GTK_CUPS_POST)
|
||||
post_states[request->state] (request);
|
||||
else if (request->type == GTK_CUPS_GET)
|
||||
get_states[request->state] (request);
|
||||
|
||||
if (request->attempts > _GTK_CUPS_MAX_ATTEMPTS &&
|
||||
request->state != GTK_CUPS_REQUEST_DONE)
|
||||
{
|
||||
/* TODO: should add a status or error code for too many failed attempts */
|
||||
gtk_cups_result_set_error (request->result,
|
||||
GTK_CUPS_ERROR_GENERAL,
|
||||
0,
|
||||
0,
|
||||
"Too many failed attempts");
|
||||
|
||||
request->state = GTK_CUPS_REQUEST_DONE;
|
||||
request->poll_state = GTK_CUPS_HTTP_IDLE;
|
||||
}
|
||||
|
||||
if (request->state == GTK_CUPS_REQUEST_DONE)
|
||||
{
|
||||
request->poll_state = GTK_CUPS_HTTP_IDLE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
if (connect_only && request->state != GTK_CUPS_REQUEST_START)
|
||||
return FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
if (request->type == GTK_CUPS_POST)
|
||||
post_states[request->state] (request);
|
||||
else if (request->type == GTK_CUPS_GET)
|
||||
get_states[request->state] (request);
|
||||
|
||||
if (request->attempts > _GTK_CUPS_MAX_ATTEMPTS &&
|
||||
request->state != GTK_CUPS_REQUEST_DONE)
|
||||
{
|
||||
/* TODO: should add a status or error code for too many failed attempts */
|
||||
gtk_cups_result_set_error (request->result,
|
||||
GTK_CUPS_ERROR_GENERAL,
|
||||
0,
|
||||
0,
|
||||
"Too many failed attempts");
|
||||
|
||||
request->state = GTK_CUPS_REQUEST_DONE;
|
||||
}
|
||||
|
||||
if (request->state == GTK_CUPS_REQUEST_DONE)
|
||||
{
|
||||
request->poll_state = GTK_CUPS_HTTP_IDLE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
/* We need to recheck using httpCheck if the poll_state is read, because
|
||||
* Cups has an internal read buffer. And if this buffer is filled, we may
|
||||
* never get a poll event again. */
|
||||
while (request->poll_state == GTK_CUPS_HTTP_READ && request->http && httpCheck(request->http));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GtkCupsPollState
|
||||
@ -643,6 +652,7 @@ static void
|
||||
_connect (GtkCupsRequest *request)
|
||||
{
|
||||
request->poll_state = GTK_CUPS_HTTP_IDLE;
|
||||
request->bytes_received = 0;
|
||||
|
||||
if (request->http == NULL)
|
||||
{
|
||||
@ -1404,18 +1414,11 @@ _get_read_data (GtkCupsRequest *request)
|
||||
#else
|
||||
bytes = httpRead (request->http, buffer, sizeof (buffer));
|
||||
#endif /* HAVE_CUPS_API_1_2 */
|
||||
request->bytes_received += bytes;
|
||||
|
||||
GTK_NOTE (PRINTING,
|
||||
g_print ("CUPS Backend: %" G_GSIZE_FORMAT " bytes read\n", bytes));
|
||||
|
||||
if (bytes == 0)
|
||||
{
|
||||
request->state = GTK_CUPS_GET_DONE;
|
||||
request->poll_state = GTK_CUPS_HTTP_IDLE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
io_status =
|
||||
g_io_channel_write_chars (request->data_io,
|
||||
buffer,
|
||||
@ -1435,6 +1438,19 @@ _get_read_data (GtkCupsRequest *request)
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
/* Stop if we do not expect any more data or EOF was received. */
|
||||
#if HAVE_CUPS_API_1_2
|
||||
if (httpGetLength2 (request->http) <= request->bytes_received || bytes == 0)
|
||||
#else
|
||||
if (httpGetLength (request->http) <= request->bytes_received || bytes == 0)
|
||||
#endif /* HAVE_CUPS_API_1_2 */
|
||||
{
|
||||
request->state = GTK_CUPS_GET_DONE;
|
||||
request->poll_state = GTK_CUPS_HTTP_IDLE;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -93,6 +93,7 @@ struct _GtkCupsRequest
|
||||
|
||||
gint state;
|
||||
GtkCupsPollState poll_state;
|
||||
guint64 bytes_received;
|
||||
|
||||
gchar *password;
|
||||
gchar *username;
|
||||
@ -172,7 +173,8 @@ void gtk_cups_request_ipp_add_strings (GtkCupsRequest *
|
||||
const char * gtk_cups_request_ipp_get_string (GtkCupsRequest *request,
|
||||
ipp_tag_t tag,
|
||||
const char *name);
|
||||
gboolean gtk_cups_request_read_write (GtkCupsRequest *request);
|
||||
gboolean gtk_cups_request_read_write (GtkCupsRequest *request,
|
||||
gboolean connect_only);
|
||||
GtkCupsPollState gtk_cups_request_get_poll_state (GtkCupsRequest *request);
|
||||
void gtk_cups_request_free (GtkCupsRequest *request);
|
||||
GtkCupsResult * gtk_cups_request_get_result (GtkCupsRequest *request);
|
||||
|
@ -92,6 +92,7 @@ typedef struct
|
||||
|
||||
http_t *http;
|
||||
GtkCupsRequest *request;
|
||||
GtkCupsPollState poll_state;
|
||||
GPollFD *data_poll;
|
||||
GtkPrintBackendCups *backend;
|
||||
GtkPrintCupsResponseCallbackFunc callback;
|
||||
@ -917,11 +918,20 @@ cups_dispatch_add_poll (GSource *source)
|
||||
|
||||
poll_state = gtk_cups_request_get_poll_state (dispatch->request);
|
||||
|
||||
/* Remove the old source if the poll state changed. */
|
||||
if (poll_state != dispatch->poll_state && dispatch->data_poll != NULL)
|
||||
{
|
||||
g_source_remove_poll (source, dispatch->data_poll);
|
||||
g_free (dispatch->data_poll);
|
||||
dispatch->data_poll = NULL;
|
||||
}
|
||||
|
||||
if (dispatch->request->http != NULL)
|
||||
{
|
||||
if (dispatch->data_poll == NULL)
|
||||
{
|
||||
dispatch->data_poll = g_new0 (GPollFD, 1);
|
||||
dispatch->poll_state = poll_state;
|
||||
|
||||
if (poll_state == GTK_CUPS_HTTP_READ)
|
||||
dispatch->data_poll->events = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
|
||||
@ -1093,13 +1103,11 @@ cups_dispatch_watch_check (GSource *source)
|
||||
|
||||
poll_state = gtk_cups_request_get_poll_state (dispatch->request);
|
||||
|
||||
cups_dispatch_add_poll (source);
|
||||
|
||||
if (poll_state != GTK_CUPS_HTTP_IDLE && !dispatch->request->need_password)
|
||||
if (!(dispatch->data_poll->revents & dispatch->data_poll->events))
|
||||
return FALSE;
|
||||
|
||||
result = gtk_cups_request_read_write (dispatch->request);
|
||||
result = gtk_cups_request_read_write (dispatch->request, FALSE);
|
||||
if (result && dispatch->data_poll != NULL)
|
||||
{
|
||||
g_source_remove_poll (source, dispatch->data_poll);
|
||||
@ -1130,8 +1138,8 @@ cups_dispatch_watch_prepare (GSource *source,
|
||||
g_print ("CUPS Backend: %s <source %p>\n", G_STRFUNC, source));
|
||||
|
||||
*timeout_ = -1;
|
||||
|
||||
result = gtk_cups_request_read_write (dispatch->request);
|
||||
|
||||
result = gtk_cups_request_read_write (dispatch->request, TRUE);
|
||||
|
||||
cups_dispatch_add_poll (source);
|
||||
|
||||
@ -1231,7 +1239,12 @@ cups_dispatch_watch_finalize (GSource *source)
|
||||
dispatch->backend = NULL;
|
||||
}
|
||||
|
||||
g_free (dispatch->data_poll);
|
||||
if (dispatch->data_poll)
|
||||
{
|
||||
g_source_remove_poll (source, dispatch->data_poll);
|
||||
g_free (dispatch->data_poll);
|
||||
dispatch->data_poll = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GSourceFuncs _cups_dispatch_watch_funcs = {
|
||||
@ -1260,6 +1273,7 @@ cups_request_execute (GtkPrintBackendCups *print_backend,
|
||||
|
||||
dispatch->request = request;
|
||||
dispatch->backend = g_object_ref (print_backend);
|
||||
dispatch->poll_state = GTK_CUPS_HTTP_IDLE;
|
||||
dispatch->data_poll = NULL;
|
||||
dispatch->callback = NULL;
|
||||
dispatch->callback_data = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user