Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions backend/usb-libusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ typedef struct usb_globals_s /* Global USB printer information */
pthread_cond_t sidechannel_thread_cond;
int sidechannel_thread_stop;
int sidechannel_thread_done;

int wakeup_pipe[2]; /* Pipe for waking up select() in the main thread */
} usb_globals_t;

/*
Expand Down Expand Up @@ -188,12 +190,14 @@ print_device(const char *uri, /* I - Device URI */
*print_ptr; /* Pointer into print data buffer */
fd_set input_set; /* Input set for select() */
int nfds; /* Number of file descriptors */
int nfd_max; /* Maximum file descriptor number for select() */
struct timeval *timeout, /* Timeout pointer */
tv; /* Time value */
struct timespec cond_timeout; /* pthread condition timeout */
int num_opts; /* Number of options */
cups_option_t *opts; /* Options */
const char *val; /* Option value */
char dummy; /* select() wakeup bogus data */


load_quirks();
Expand All @@ -205,6 +209,17 @@ print_device(const char *uri, /* I - Device URI */
have_sidechannel = !fstat(CUPS_SC_FD, &sidechannel_info) &&
S_ISSOCK(sidechannel_info.st_mode);

/*
* Create a pipe for waking up the main thread from select()...
*/

if (pipe(g.wakeup_pipe) < 0)
{
fprintf(stderr, "DEBUG: Unable to create wakeup pipe - %s\n",
strerror(errno));
return (CUPS_BACKEND_STOP);
}

g.wait_eof = WAIT_EOF;

/*
Expand Down Expand Up @@ -346,12 +361,15 @@ print_device(const char *uri, /* I - Device URI */
lseek(print_fd, 0, SEEK_SET);
}

nfd_max = (print_fd > g.wakeup_pipe[0] ? print_fd : g.wakeup_pipe[0]) + 1;

while (status == CUPS_BACKEND_OK)
{
FD_ZERO(&input_set);

if (!g.print_bytes)
FD_SET(print_fd, &input_set);
FD_SET(g.wakeup_pipe[0], &input_set);

/*
* Calculate select timeout...
Expand Down Expand Up @@ -384,7 +402,7 @@ print_device(const char *uri, /* I - Device URI */
pthread_cond_signal(&g.readwrite_lock_cond);
pthread_mutex_unlock(&g.readwrite_lock_mutex);

nfds = select(print_fd + 1, &input_set, NULL, NULL, timeout);
nfds = select(nfd_max, &input_set, NULL, NULL, timeout);

/*
* Reacquire the lock...
Expand Down Expand Up @@ -415,15 +433,22 @@ print_device(const char *uri, /* I - Device URI */
}
}

/*
* Check if we were woken up by the sidechannel thread...
*/

if (FD_ISSET(g.wakeup_pipe[0], &input_set))
read(g.wakeup_pipe[0], &dummy, 1);

/*
* If drain output has finished send a response...
*/

if (g.drain_output && !nfds && !g.print_bytes)
{
/* Send a response... */
cupsSideChannelWrite(CUPS_SC_CMD_DRAIN_OUTPUT, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
g.drain_output = 0;
cupsSideChannelWrite(CUPS_SC_CMD_DRAIN_OUTPUT, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
}

/*
Expand Down Expand Up @@ -641,6 +666,13 @@ print_device(const char *uri, /* I - Device URI */

close_device(g.printer);

/*
* Close the wakeup pipe...
*/

close(g.wakeup_pipe[0]);
close(g.wakeup_pipe[1]);

/*
* Clean up ....
*/
Expand Down Expand Up @@ -1885,6 +1917,17 @@ sidechannel_thread(void *reference)
stderr);

g.drain_output = 1;
pthread_mutex_lock(&g.readwrite_lock_mutex);
if (!g.readwrite_lock)
{
/*
* If main thread is inside select(), assume it has infinite
* timeout and needs to be woken up.
*/
if (write(g.wakeup_pipe[1], &data, 1) < 0)
fputs("DEBUG: Error writing to wakeup pipe\n", stderr);
}
pthread_mutex_unlock(&g.readwrite_lock_mutex);
break;

case CUPS_SC_CMD_GET_BIDI: /* Is the connection bidirectional? */
Expand Down
Loading