@@ -73,6 +73,8 @@ struct work_notifier_entry_s
73
73
* Private Data
74
74
****************************************************************************/
75
75
76
+ static spinlock_t g_work_notifier_lock ;
77
+
76
78
/* This is a doubly linked list of free notifications. */
77
79
78
80
static dq_queue_t g_notifier_free ;
@@ -160,23 +162,34 @@ static void work_notifier_worker(FAR void *arg)
160
162
(FAR struct work_notifier_entry_s * )arg ;
161
163
irqstate_t flags ;
162
164
163
- /* Forward to the real worker */
164
-
165
- notifier -> info .worker (notifier -> info .arg );
166
-
167
165
/* Disable interrupts very briefly. */
168
166
169
- flags = enter_critical_section ( );
167
+ flags = spin_lock_irqsave ( & g_work_notifier_lock );
170
168
171
169
/* Remove the notification from the pending list */
172
170
173
- dq_rem (& notifier -> entry , & g_notifier_pending );
171
+ notifier = work_notifier_find (notifier -> key );
172
+ if (notifier != NULL )
173
+ {
174
+ /* Forward to the real worker */
175
+
176
+ spin_unlock_irqrestore (& g_work_notifier_lock , flags );
177
+
178
+ notifier -> info .worker (notifier -> info .arg );
179
+
180
+ flags = spin_lock_irqsave (& g_work_notifier_lock );
181
+ notifier = work_notifier_find (notifier -> key );
182
+ if (notifier != NULL )
183
+ {
184
+ dq_rem (& notifier -> entry , & g_notifier_pending );
174
185
175
- /* Put the notification to the free list */
186
+ /* Put the notification to the free list */
176
187
177
- dq_addlast (& notifier -> entry , & g_notifier_free );
188
+ dq_addlast (& notifier -> entry , & g_notifier_free );
189
+ }
190
+ }
178
191
179
- leave_critical_section ( flags );
192
+ spin_unlock_irqrestore ( & g_work_notifier_lock , flags );
180
193
}
181
194
182
195
/****************************************************************************
@@ -213,14 +226,14 @@ int work_notifier_setup(FAR struct work_notifier_s *info)
213
226
214
227
/* Disable interrupts very briefly. */
215
228
216
- flags = enter_critical_section ( );
229
+ flags = spin_lock_irqsave ( & g_work_notifier_lock );
217
230
218
231
/* Try to get the entry from the free list */
219
232
220
233
notifier = (FAR struct work_notifier_entry_s * )
221
234
dq_remfirst (& g_notifier_free );
222
235
223
- leave_critical_section ( flags );
236
+ spin_unlock_irqrestore ( & g_work_notifier_lock , flags );
224
237
225
238
if (notifier == NULL )
226
239
{
@@ -245,7 +258,7 @@ int work_notifier_setup(FAR struct work_notifier_s *info)
245
258
246
259
/* Disable interrupts very briefly. */
247
260
248
- flags = enter_critical_section ( );
261
+ flags = spin_lock_irqsave ( & g_work_notifier_lock );
249
262
250
263
/* Generate a unique key for this notification */
251
264
@@ -262,7 +275,7 @@ int work_notifier_setup(FAR struct work_notifier_s *info)
262
275
dq_addlast (& notifier -> entry , & g_notifier_pending );
263
276
ret = notifier -> key ;
264
277
265
- leave_critical_section ( flags );
278
+ spin_unlock_irqrestore ( & g_work_notifier_lock , flags );
266
279
}
267
280
268
281
return ret ;
@@ -293,7 +306,7 @@ void work_notifier_teardown(int key)
293
306
294
307
/* Disable interrupts very briefly. */
295
308
296
- flags = enter_critical_section ( );
309
+ flags = spin_lock_irqsave ( & g_work_notifier_lock );
297
310
298
311
/* Find the entry matching this key in the g_notifier_pending list. We
299
312
* assume that there is only one.
@@ -304,19 +317,18 @@ void work_notifier_teardown(int key)
304
317
{
305
318
/* Cancel the work, this may be waiting */
306
319
307
- if (work_cancel_sync (notifier -> info .qid , & notifier -> work ) != 1 )
308
- {
309
- /* Remove the notification from the pending list */
320
+ work_cancel (notifier -> info .qid , & notifier -> work );
310
321
311
- dq_rem ( & notifier -> entry , & g_notifier_pending );
322
+ /* Remove the notification from the pending list */
312
323
313
- /* Put the notification to the free list */
324
+ dq_rem ( & notifier -> entry , & g_notifier_pending );
314
325
315
- dq_addlast (& notifier -> entry , & g_notifier_free );
316
- }
326
+ /* Put the notification to the free list */
327
+
328
+ dq_addlast (& notifier -> entry , & g_notifier_free );
317
329
}
318
330
319
- leave_critical_section ( flags );
331
+ spin_unlock_irqrestore ( & g_work_notifier_lock , flags );
320
332
}
321
333
322
334
/****************************************************************************
@@ -352,7 +364,7 @@ void work_notifier_signal(enum work_evtype_e evtype,
352
364
* the notifications have been sent.
353
365
*/
354
366
355
- flags = enter_critical_section ( );
367
+ flags = spin_lock_irqsave ( & g_work_notifier_lock );
356
368
sched_lock ();
357
369
358
370
/* Process the notification at the head of the pending list until the
@@ -397,7 +409,7 @@ void work_notifier_signal(enum work_evtype_e evtype,
397
409
}
398
410
399
411
sched_unlock ();
400
- leave_critical_section ( flags );
412
+ spin_unlock_irqrestore ( & g_work_notifier_lock , flags );
401
413
}
402
414
403
415
#endif /* CONFIG_WQUEUE_NOTIFIER */
0 commit comments