Skip to content

Commit 7dc51ee

Browse files
committed
Mirror USB backend fixes (Issue #1461)
1 parent efab7e7 commit 7dc51ee

1 file changed

Lines changed: 45 additions & 2 deletions

File tree

backend/usb-libusb.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ typedef struct usb_globals_s /* Global USB printer information */
7878
pthread_cond_t sidechannel_thread_cond;
7979
int sidechannel_thread_stop;
8080
int sidechannel_thread_done;
81+
82+
int wakeup_pipe[2]; /* Pipe for waking up select() in the main thread */
8183
} usb_globals_t;
8284

8385
/*
@@ -191,12 +193,14 @@ print_device(const char *uri, /* I - Device URI */
191193
*print_ptr; /* Pointer into print data buffer */
192194
fd_set input_set; /* Input set for select() */
193195
int nfds; /* Number of file descriptors */
196+
int nfd_max; /* Maximum file descriptor number for select() */
194197
struct timeval *timeout, /* Timeout pointer */
195198
tv; /* Time value */
196199
struct timespec cond_timeout; /* pthread condition timeout */
197200
int num_opts; /* Number of options */
198201
cups_option_t *opts; /* Options */
199202
const char *val; /* Option value */
203+
char dummy; /* select() wakeup bogus data */
200204

201205

202206
load_quirks();
@@ -208,6 +212,17 @@ print_device(const char *uri, /* I - Device URI */
208212
have_sidechannel = !fstat(CUPS_SC_FD, &sidechannel_info) &&
209213
S_ISSOCK(sidechannel_info.st_mode);
210214

215+
/*
216+
* Create a pipe for waking up the main thread from select()...
217+
*/
218+
219+
if (pipe(g.wakeup_pipe) < 0)
220+
{
221+
fprintf(stderr, "DEBUG: Unable to create wakeup pipe - %s\n",
222+
strerror(errno));
223+
return (CUPS_BACKEND_STOP);
224+
}
225+
211226
g.wait_eof = WAIT_EOF;
212227

213228
/*
@@ -349,12 +364,15 @@ print_device(const char *uri, /* I - Device URI */
349364
lseek(print_fd, 0, SEEK_SET);
350365
}
351366

367+
nfd_max = (print_fd > g.wakeup_pipe[0] ? print_fd : g.wakeup_pipe[0]) + 1;
368+
352369
while (status == CUPS_BACKEND_OK)
353370
{
354371
FD_ZERO(&input_set);
355372

356373
if (!g.print_bytes)
357374
FD_SET(print_fd, &input_set);
375+
FD_SET(g.wakeup_pipe[0], &input_set);
358376

359377
/*
360378
* Calculate select timeout...
@@ -387,7 +405,7 @@ print_device(const char *uri, /* I - Device URI */
387405
pthread_cond_signal(&g.readwrite_lock_cond);
388406
pthread_mutex_unlock(&g.readwrite_lock_mutex);
389407

390-
nfds = select(print_fd + 1, &input_set, NULL, NULL, timeout);
408+
nfds = select(nfd_max, &input_set, NULL, NULL, timeout);
391409

392410
/*
393411
* Reacquire the lock...
@@ -418,15 +436,22 @@ print_device(const char *uri, /* I - Device URI */
418436
}
419437
}
420438

439+
/*
440+
* Check if we were woken up by the sidechannel thread...
441+
*/
442+
443+
if (FD_ISSET(g.wakeup_pipe[0], &input_set))
444+
read(g.wakeup_pipe[0], &dummy, 1);
445+
421446
/*
422447
* If drain output has finished send a response...
423448
*/
424449

425450
if (g.drain_output && !nfds && !g.print_bytes)
426451
{
427452
/* Send a response... */
428-
cupsSideChannelWrite(CUPS_SC_CMD_DRAIN_OUTPUT, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
429453
g.drain_output = 0;
454+
cupsSideChannelWrite(CUPS_SC_CMD_DRAIN_OUTPUT, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
430455
}
431456

432457
/*
@@ -644,6 +669,13 @@ print_device(const char *uri, /* I - Device URI */
644669

645670
close_device(g.printer);
646671

672+
/*
673+
* Close the wakeup pipe...
674+
*/
675+
676+
close(g.wakeup_pipe[0]);
677+
close(g.wakeup_pipe[1]);
678+
647679
/*
648680
* Clean up ....
649681
*/
@@ -1899,6 +1931,17 @@ sidechannel_thread(void *reference)
18991931
stderr);
19001932

19011933
g.drain_output = 1;
1934+
pthread_mutex_lock(&g.readwrite_lock_mutex);
1935+
if (!g.readwrite_lock)
1936+
{
1937+
/*
1938+
* If main thread is inside select(), assume it has infinite
1939+
* timeout and needs to be woken up.
1940+
*/
1941+
if (write(g.wakeup_pipe[1], &data, 1) < 0)
1942+
fputs("DEBUG: Error writing to wakeup pipe\n", stderr);
1943+
}
1944+
pthread_mutex_unlock(&g.readwrite_lock_mutex);
19021945
break;
19031946

19041947
case CUPS_SC_CMD_GET_BIDI: /* Is the connection bidirectional? */

0 commit comments

Comments
 (0)