2727static int cupsd_compare_subscriptions (cupsd_subscription_t * first ,
2828 cupsd_subscription_t * second ,
2929 void * unused );
30- static void cupsd_delete_event (cupsd_event_t * event , void * data );
30+ static void cupsd_delete_event (cupsd_event_t * event , void * data );
3131#ifdef HAVE_DBUS
3232static void cupsd_send_dbus (cupsd_eventmask_t event , cupsd_printer_t * dest ,
3333 cupsd_job_t * job );
@@ -50,10 +50,12 @@ cupsdAddEvent(
5050 const char * text , /* I - Notification text */
5151 ...) /* I - Additional arguments as needed */
5252{
53+ int i , /* Looping var */
54+ scount ; /* Number of subscriptions */
5355 va_list ap ; /* Pointer to additional arguments */
5456 char ftext [1024 ]; /* Formatted text buffer */
5557 ipp_attribute_t * attr ; /* Printer/job attribute */
56- cupsd_event_t * temp ; /* New event pointer */
58+ cupsd_event_t * temp = NULL ; /* New event pointer */
5759 cupsd_subscription_t * sub ; /* Current subscription */
5860
5961
@@ -92,14 +94,16 @@ cupsdAddEvent(
9294 if (job && !dest )
9395 dest = cupsdFindPrinter (job -> dest );
9496
95- for ( temp = NULL , sub = ( cupsd_subscription_t * ) cupsArrayFirst ( Subscriptions );
96- sub ;
97- sub = ( cupsd_subscription_t * ) cupsArrayNext ( Subscriptions ))
97+ cupsRWLockRead ( & SubscriptionsLock );
98+
99+ for ( i = 0 , scount = cupsArrayGetCount ( Subscriptions ); i < scount ; i ++ )
98100 {
99101 /*
100102 * Check if this subscription requires this event...
101103 */
102104
105+ sub = (cupsd_subscription_t * )cupsArrayGetElement (Subscriptions , i );
106+
103107 if ((sub -> mask & event ) != 0 && (sub -> dest == dest || !sub -> dest || sub -> job == job ))
104108 {
105109 /*
@@ -111,6 +115,7 @@ cupsdAddEvent(
111115 cupsdLogMessage (CUPSD_LOG_CRIT ,
112116 "Unable to allocate memory for event - %s" ,
113117 strerror (errno ));
118+ cupsRWUnlock (& SubscriptionsLock );
114119 return ;
115120 }
116121
@@ -240,6 +245,8 @@ cupsdAddEvent(
240245 }
241246 }
242247
248+ cupsRWUnlock (& SubscriptionsLock );
249+
243250 if (temp )
244251 cupsdMarkDirty (CUPSD_DIRTY_SUBSCRIPTIONS );
245252 else
@@ -268,6 +275,8 @@ cupsdAddSubscription(
268275 mask , (void * )dest , dest ? dest -> name : "" , (void * )job , job ? job -> id : 0 ,
269276 uri ? uri : "(null)" );
270277
278+ cupsRWLockWrite (& SubscriptionsLock );
279+
271280 if (!Subscriptions )
272281 Subscriptions = cupsArrayNew ((cups_array_func_t )cupsd_compare_subscriptions ,
273282 NULL );
@@ -277,6 +286,7 @@ cupsdAddSubscription(
277286 cupsdLogMessage (CUPSD_LOG_CRIT ,
278287 "Unable to allocate memory for subscriptions - %s" ,
279288 strerror (errno ));
289+ cupsRWUnlock (& SubscriptionsLock );
280290 return (NULL );
281291 }
282292
@@ -290,6 +300,7 @@ cupsdAddSubscription(
290300 "cupsdAddSubscription: Reached MaxSubscriptions %d "
291301 "(count=%d)" , MaxSubscriptions ,
292302 cupsArrayCount (Subscriptions ));
303+ cupsRWUnlock (& SubscriptionsLock );
293304 return (NULL );
294305 }
295306
@@ -310,6 +321,7 @@ cupsdAddSubscription(
310321 "cupsdAddSubscription: Reached MaxSubscriptionsPerJob %d "
311322 "for job #%d (count=%d)" , MaxSubscriptionsPerJob ,
312323 job -> id , count );
324+ cupsRWUnlock (& SubscriptionsLock );
313325 return (NULL );
314326 }
315327 }
@@ -331,6 +343,7 @@ cupsdAddSubscription(
331343 "cupsdAddSubscription: Reached "
332344 "MaxSubscriptionsPerPrinter %d for %s (count=%d)" ,
333345 MaxSubscriptionsPerPrinter , dest -> name , count );
346+ cupsRWUnlock (& SubscriptionsLock );
334347 return (NULL );
335348 }
336349 }
@@ -344,9 +357,12 @@ cupsdAddSubscription(
344357 cupsdLogMessage (CUPSD_LOG_CRIT ,
345358 "Unable to allocate memory for subscription object - %s" ,
346359 strerror (errno ));
360+ cupsRWUnlock (& SubscriptionsLock );
347361 return (NULL );
348362 }
349363
364+ cupsRWInit (& temp -> lock );
365+
350366 /*
351367 * Fill in common data...
352368 */
@@ -380,6 +396,8 @@ cupsdAddSubscription(
380396
381397 cupsArrayAdd (Subscriptions , temp );
382398
399+ cupsRWUnlock (& SubscriptionsLock );
400+
383401 /*
384402 * For RSS subscriptions, run the notifier immediately...
385403 */
@@ -404,13 +422,17 @@ cupsdDeleteAllSubscriptions(void)
404422 if (!Subscriptions )
405423 return ;
406424
425+ cupsRWLockWrite (& SubscriptionsLock );
426+
407427 for (sub = (cupsd_subscription_t * )cupsArrayFirst (Subscriptions );
408428 sub ;
409429 sub = (cupsd_subscription_t * )cupsArrayNext (Subscriptions ))
410430 cupsdDeleteSubscription (sub , 0 );
411431
412432 cupsArrayDelete (Subscriptions );
413433 Subscriptions = NULL ;
434+
435+ cupsRWUnlock (& SubscriptionsLock );
414436}
415437
416438
@@ -434,12 +456,18 @@ cupsdDeleteSubscription(
434456 * Remove subscription from array...
435457 */
436458
459+ cupsRWLockWrite (& SubscriptionsLock );
460+
437461 cupsArrayRemove (Subscriptions , sub );
438462
463+ cupsRWUnlock (& SubscriptionsLock );
464+
439465 /*
440466 * Free memory...
441467 */
442468
469+ cupsRWDestroy (& sub -> lock );
470+
443471 cupsdClearString (& (sub -> owner ));
444472 cupsdClearString (& (sub -> recipient ));
445473
@@ -651,12 +679,18 @@ cupsdExpireSubscriptions(
651679cupsd_subscription_t * /* O - Subscription object */
652680cupsdFindSubscription (int id ) /* I - Subscription ID */
653681{
654- cupsd_subscription_t sub ; /* Subscription template */
682+ cupsd_subscription_t key , /* Subscription key */
683+ * sub ; /* Matching subscription */
684+
685+ key .id = id ;
686+
687+ cupsRWLockRead (& SubscriptionsLock );
655688
689+ sub = (cupsd_subscription_t * )cupsArrayFind (Subscriptions , & sub );
656690
657- sub . id = id ;
691+ cupsRWUnlock ( & SubscriptionsLock ) ;
658692
659- return (( cupsd_subscription_t * ) cupsArrayFind ( Subscriptions , & sub ) );
693+ return (sub );
660694}
661695
662696
@@ -1020,7 +1054,8 @@ cupsdLoadAllSubscriptions(void)
10201054void
10211055cupsdSaveAllSubscriptions (void )
10221056{
1023- int i ; /* Looping var */
1057+ int i , j , /* Looping vars */
1058+ scount ; /* Number of subscriptions */
10241059 cups_file_t * fp ; /* subscriptions.conf file */
10251060 char filename [1024 ]; /* subscriptions.conf filename */
10261061 cupsd_subscription_t * sub ; /* Current subscription */
@@ -1053,10 +1088,12 @@ cupsdSaveAllSubscriptions(void)
10531088 * Write every subscription known to the system...
10541089 */
10551090
1056- for ( sub = ( cupsd_subscription_t * ) cupsArrayFirst ( Subscriptions );
1057- sub ;
1058- sub = ( cupsd_subscription_t * ) cupsArrayNext ( Subscriptions ))
1091+ cupsRWLockRead ( & SubscriptionsLock );
1092+
1093+ for ( i = 0 , scount = cupsArrayGetCount ( Subscriptions ); i < scount ; i ++ )
10591094 {
1095+ sub = (cupsd_subscription_t * )cupsArrayGetElement (Subscriptions , i );
1096+
10601097 cupsFilePrintf (fp , "<Subscription %d>\n" , sub -> id );
10611098
10621099 if ((name = cupsdEventName ((cupsd_eventmask_t )sub -> mask )) != NULL )
@@ -1095,29 +1132,29 @@ cupsdSaveAllSubscriptions(void)
10951132 {
10961133 cupsFilePuts (fp , "UserData " );
10971134
1098- for (i = 0 , hex = 0 ; i < sub -> user_data_len ; i ++ )
1135+ for (j = 0 , hex = 0 ; j < sub -> user_data_len ; j ++ )
10991136 {
1100- if (sub -> user_data [i ] < ' ' ||
1101- sub -> user_data [i ] > 0x7f ||
1102- sub -> user_data [i ] == '<' )
1137+ if (sub -> user_data [j ] < ' ' ||
1138+ sub -> user_data [j ] > 0x7f ||
1139+ sub -> user_data [j ] == '<' )
11031140 {
11041141 if (!hex )
11051142 {
1106- cupsFilePrintf (fp , "<%02X" , sub -> user_data [i ]);
1143+ cupsFilePrintf (fp , "<%02X" , sub -> user_data [j ]);
11071144 hex = 1 ;
11081145 }
11091146 else
1110- cupsFilePrintf (fp , "%02X" , sub -> user_data [i ]);
1147+ cupsFilePrintf (fp , "%02X" , sub -> user_data [j ]);
11111148 }
11121149 else
11131150 {
11141151 if (hex )
11151152 {
1116- cupsFilePrintf (fp , ">%c" , sub -> user_data [i ]);
1153+ cupsFilePrintf (fp , ">%c" , sub -> user_data [j ]);
11171154 hex = 0 ;
11181155 }
11191156 else
1120- cupsFilePutChar (fp , sub -> user_data [i ]);
1157+ cupsFilePutChar (fp , sub -> user_data [j ]);
11211158 }
11221159 }
11231160
@@ -1135,6 +1172,8 @@ cupsdSaveAllSubscriptions(void)
11351172 cupsFilePuts (fp , "</Subscription>\n" );
11361173 }
11371174
1175+ cupsRWUnlock (& SubscriptionsLock );
1176+
11381177 cupsdCloseCreatedConfFile (fp , filename );
11391178}
11401179
@@ -1326,6 +1365,8 @@ cupsd_send_notification(
13261365 * Allocate the events array as needed...
13271366 */
13281367
1368+ cupsRWLockWrite (& sub -> lock );
1369+
13291370 if (!sub -> events )
13301371 {
13311372 sub -> events = cupsArrayNew3 ((cups_array_func_t )NULL , NULL ,
@@ -1425,6 +1466,8 @@ cupsd_send_notification(
14251466 */
14261467
14271468 sub -> next_event_id ++ ;
1469+
1470+ cupsRWUnlock (& sub -> lock );
14281471}
14291472
14301473
0 commit comments