Skip to content

Commit f6a2b50

Browse files
committed
Fix threading issues for subscriptions in cupsd (Issue #1235)
1 parent ac85dcb commit f6a2b50

7 files changed

Lines changed: 137 additions & 49 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Changes in CUPS v2.4.13 (YYYY-MM-DD)
77

88
- Fixed a memory leak in `httpClose` (Issue #1223)
99
- Fixed missing commas in `ippCreateRequestedArray` (Issue #1234)
10+
- Fixed subscription threading issues in the scheduler (Issue #1235)
1011

1112

1213
Changes in CUPS v2.4.12 (2025-04-08)

cups/libcups2.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ _cupsMutexInit
3636
_cupsMutexLock
3737
_cupsMutexUnlock
3838
_cupsNextDelay
39+
_cupsRWDestroy
3940
_cupsRWInit
4041
_cupsRWLockRead
4142
_cupsRWLockWrite

cups/thread-private.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
/*
22
* Private threading definitions for CUPS.
33
*
4-
* Copyright 2009-2017 by Apple Inc.
4+
* Copyright © 2025 by OpenPrinting.
5+
* Copyright © 2009-2017 by Apple Inc.
56
*
6-
* Licensed under Apache License v2.0. See the file "LICENSE" for more information.
7+
* Licensed under Apache License v2.0. See the file "LICENSE" for more
8+
* information.
79
*/
810

911
#ifndef _CUPS_THREAD_PRIVATE_H_
@@ -88,6 +90,7 @@ extern void _cupsCondWait(_cups_cond_t *cond, _cups_mutex_t *mutex, double timeo
8890
extern void _cupsMutexInit(_cups_mutex_t *mutex) _CUPS_PRIVATE;
8991
extern void _cupsMutexLock(_cups_mutex_t *mutex) _CUPS_PRIVATE;
9092
extern void _cupsMutexUnlock(_cups_mutex_t *mutex) _CUPS_PRIVATE;
93+
extern void _cupsRWDestroy(_cups_rwlock_t *rwlock) _CUPS_PRIVATE;
9194
extern void _cupsRWInit(_cups_rwlock_t *rwlock) _CUPS_PRIVATE;
9295
extern void _cupsRWLockRead(_cups_rwlock_t *rwlock) _CUPS_PRIVATE;
9396
extern void _cupsRWLockWrite(_cups_rwlock_t *rwlock) _CUPS_PRIVATE;

cups/thread.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Threading primitives for CUPS.
33
*
4-
* Copyright © 2020-2024 by OpenPrinting.
4+
* Copyright © 2020-2025 by OpenPrinting.
55
* Copyright © 2009-2018 by Apple Inc.
66
*
77
* Licensed under Apache License v2.0. See the file "LICENSE" for more
@@ -103,6 +103,17 @@ _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
103103
}
104104

105105

106+
/*
107+
* '_cupsRWDestroy()' - Destroy a reader/writer lock.
108+
*/
109+
110+
void
111+
_cupsRWDestroy(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
112+
{
113+
pthread_rwlock_destroy(rwlock);
114+
}
115+
116+
106117
/*
107118
* '_cupsRWInit()' - Initialize a reader/writer lock.
108119
*/
@@ -290,6 +301,17 @@ _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
290301
}
291302

292303

304+
/*
305+
* '_cupsRWDestroy()' - Destroy a reader/writer lock.
306+
*/
307+
308+
void
309+
_cupsRWDestroy(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
310+
{
311+
(void)rwlock;
312+
}
313+
314+
293315
/*
294316
* '_cupsRWInit()' - Initialize a reader/writer lock.
295317
*/

scheduler/ipp.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5063,9 +5063,9 @@ copy_subscription_attrs(
50635063
const char *name; /* Current event name */
50645064

50655065

5066-
cupsdLogMessage(CUPSD_LOG_DEBUG2,
5067-
"copy_subscription_attrs(con=%p, sub=%p, ra=%p, exclude=%p)",
5068-
(void *)con, (void *)sub, (void *)ra, (void *)exclude);
5066+
cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_subscription_attrs(con=%p, sub=%p, ra=%p, exclude=%p)", (void *)con, (void *)sub, (void *)ra, (void *)exclude);
5067+
5068+
_cupsRWLockRead(&sub->lock);
50695069

50705070
/*
50715071
* Copy the subscription attributes to the response using the
@@ -5156,6 +5156,8 @@ copy_subscription_attrs(
51565156
if (!ra || cupsArrayFind(ra, "notify-subscription-id"))
51575157
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
51585158
"notify-subscription-id", sub->id);
5159+
5160+
_cupsRWUnlock(&sub->lock);
51595161
}
51605162

51615163

@@ -5433,7 +5435,6 @@ create_local_bg_thread(
54335435
goto finish_response;
54345436
}
54355437

5436-
// TODO: Grab printer icon file...
54375438
httpClose(http);
54385439

54395440
/*
@@ -7940,7 +7941,9 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */
79407941
ipp_attribute_t *uri) /* I - Printer/job URI */
79417942
{
79427943
http_status_t status; /* Policy status */
7943-
int count; /* Number of subscriptions */
7944+
int i, /* Looping var */
7945+
scount; /* Total number of subscriptions */
7946+
int count; /* Number of subscriptions returned */
79447947
int limit; /* Limit */
79457948
cupsd_subscription_t *sub; /* Subscription */
79467949
cups_array_t *ra; /* Requested attributes array */
@@ -8064,9 +8067,12 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */
80648067
else
80658068
username[0] = '\0';
80668069

8067-
for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), count = 0;
8068-
sub;
8069-
sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions))
8070+
_cupsRWLockRead(&SubscriptionsLock);
8071+
8072+
for (i = 0, count = 0, scount = cupsArrayCount(Subscriptions); i < scount; i ++)
8073+
{
8074+
sub = (cupsd_subscription_t *)cupsArrayIndex(Subscriptions, i);
8075+
80708076
if ((!printer || sub->dest == printer) && (!job || sub->job == job) &&
80718077
(!username[0] || !_cups_strcasecmp(username, sub->owner)))
80728078
{
@@ -8082,6 +8088,9 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */
80828088
if (limit && count >= limit)
80838089
break;
80848090
}
8091+
}
8092+
8093+
_cupsRWUnlock(&SubscriptionsLock);
80858094

80868095
cupsArrayDelete(ra);
80878096

@@ -9455,6 +9464,8 @@ renew_subscription(
94559464
* Renew the subscription...
94569465
*/
94579466

9467+
_cupsRWLockWrite(&sub->lock);
9468+
94589469
lease = ippFindAttribute(con->request, "notify-lease-duration",
94599470
IPP_TAG_INTEGER);
94609471

@@ -9471,9 +9482,11 @@ renew_subscription(
94719482

94729483
sub->expire = sub->lease ? time(NULL) + sub->lease : 0;
94739484

9485+
_cupsRWUnlock(&sub->lock);
9486+
94749487
cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
94759488

9476-
con->response->request.status.status_code = IPP_OK;
9489+
con->response->request.status.status_code = IPP_STATUS_OK;
94779490

94789491
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
94799492
"notify-lease-duration", sub->lease);

0 commit comments

Comments
 (0)